Return "single" launch mode with default
[platform/core/api/application.git] / app_control / app_control.c
1 /*
2  * Copyright (c) 2011 - 2016 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 <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <errno.h>
22
23 #include <bundle.h>
24 #include <bundle_internal.h>
25 #include <aul.h>
26 #include <appsvc.h>
27 #include <aul_svc.h>
28 #include <dlog.h>
29
30 #include <app_control.h>
31
32 #ifdef LOG_TAG
33 #undef LOG_TAG
34 #endif
35
36 #define LOG_TAG "CAPI_APPFW_APP_CONTROL"
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 #define BUNDLE_KEY_CATEGORY     "__APP_SVC_CATEGORY__"
52
53 #define LAUNCH_MODE_SIZE 8
54 #define LAUNCH_MODE_SINGLE "single"
55 #define LAUNCH_MODE_GROUP "group"
56
57 typedef enum {
58         APP_CONTROL_TYPE_REQUEST,
59         APP_CONTROL_TYPE_EVENT,
60         APP_CONTROL_TYPE_REPLY,
61 } app_control_type_e;
62
63 struct app_control_s {
64         int id;
65         app_control_type_e type;
66         bundle *data;
67         int launch_pid;
68 };
69
70 typedef struct app_control_request_context_s {
71         app_control_h app_control;
72         app_control_reply_cb reply_cb;
73         void *user_data;
74 } *app_control_request_context_h;
75
76 extern int appsvc_allow_transient_app(bundle *b, unsigned int id);
77 extern int appsvc_request_transient_app(bundle *b, unsigned int callee_id, appsvc_host_res_fn cbfunc, void *data);
78 static int app_control_create_reply(bundle *data, struct app_control_s **app_control);
79
80 static const char *app_control_error_to_string(app_control_error_e error)
81 {
82         switch (error) {
83         case APP_CONTROL_ERROR_NONE:
84                 return "NONE";
85         case APP_CONTROL_ERROR_INVALID_PARAMETER:
86                 return "INVALID_PARAMETER";
87         case APP_CONTROL_ERROR_OUT_OF_MEMORY:
88                 return "OUT_OF_MEMORY";
89         case APP_CONTROL_ERROR_APP_NOT_FOUND:
90                 return "APP_NOT_FOUND";
91         case APP_CONTROL_ERROR_KEY_NOT_FOUND:
92                 return "KEY_NOT_FOUND";
93         case APP_CONTROL_ERROR_KEY_REJECTED:
94                 return "KEY_REJECTED";
95         case APP_CONTROL_ERROR_INVALID_DATA_TYPE:
96                 return "INVALID_DATA_TYPE";
97         case APP_CONTROL_ERROR_LAUNCH_REJECTED:
98                 return "LAUNCH_REJECTED";
99         case APP_CONTROL_ERROR_PERMISSION_DENIED:
100                 return "PERMISSION_DENIED";
101         case APP_CONTROL_ERROR_LAUNCH_FAILED:
102                 return "LAUNCH_FAILED";
103         case APP_CONTROL_ERROR_TIMED_OUT:
104                 return "TIMED_OUT";
105         case APP_CONTROL_ERROR_IO_ERROR:
106                 return "IO ERROR";
107         default:
108                 return "UNKNOWN";
109         }
110 }
111
112 int app_control_error(app_control_error_e error, const char *function, const char *description)
113 {
114         if (description)
115                 LOGE("[%s] %s(0x%08x) : %s", function, app_control_error_to_string(error), error, description);
116         else {
117                 if (error == APP_CONTROL_ERROR_KEY_NOT_FOUND)
118                         LOGW("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error);
119                 else
120                         LOGE("[%s] %s(0x%08x)", function, app_control_error_to_string(error), error);
121         }
122
123         return error;
124 }
125
126 static int app_control_validate_extra_data(const char *data)
127 {
128         if (data == NULL || data[0] == '\0')
129                 return APP_CONTROL_ERROR_INVALID_PARAMETER;
130
131         return APP_CONTROL_ERROR_NONE;
132 }
133
134 static int app_control_validate(app_control_h app_control)
135 {
136         if (app_control == NULL || app_control->data == NULL)
137                 return APP_CONTROL_ERROR_INVALID_PARAMETER;
138
139         return APP_CONTROL_ERROR_NONE;
140 }
141
142 static int app_control_new_id()
143 {
144         static int sid = 0;
145         return sid++;
146 }
147
148 int app_control_validate_internal_key(const char *key)
149 {
150         if (strncmp(BUNDLE_KEY_PREFIX_AUL, key, strlen(BUNDLE_KEY_PREFIX_AUL)) == 0)
151                 return -1;
152
153         if (strncmp(BUNDLE_KEY_PREFIX_SERVICE, key, strlen(BUNDLE_KEY_PREFIX_SERVICE)) == 0)
154                 return -1;
155
156         return 0;
157 }
158
159 static void app_control_request_result_broker(bundle *appsvc_bundle, int appsvc_request_code, appsvc_result_val appsvc_result, void *appsvc_data)
160 {
161         app_control_request_context_h request_context;
162         app_control_h request;
163         app_control_h reply = NULL;
164         app_control_result_e result;
165         void *user_data;
166         app_control_reply_cb reply_cb;
167
168         if (appsvc_data == NULL) {
169                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control reply");
170                 return;
171         }
172
173         if (app_control_create_reply(appsvc_bundle, &reply) != 0) {
174                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control reply");
175                 return;
176         }
177
178         request_context = appsvc_data;
179         request = request_context->app_control;
180
181         switch (appsvc_result) {
182         case APPSVC_RES_OK:
183                 result = APP_CONTROL_RESULT_SUCCEEDED;
184                 break;
185         case APPSVC_RES_NOT_OK:
186                 result = APP_CONTROL_RESULT_FAILED;
187                 break;
188         case APPSVC_RES_CANCEL:
189                 result = APP_CONTROL_RESULT_CANCELED;
190                 break;
191         default:
192                 result = APP_CONTROL_RESULT_CANCELED;
193                 break;
194         }
195
196         user_data = request_context->user_data;
197         reply_cb = request_context->reply_cb;
198
199         if (reply_cb != NULL)
200                 reply_cb(request, reply, result, user_data);
201         else
202                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
203
204         app_control_destroy(reply);
205
206         if (request_context->app_control != NULL)
207                 app_control_destroy(request_context->app_control);
208
209         free(request_context);
210 }
211
212 int app_control_create_request(bundle *data, app_control_h *app_control)
213 {
214         struct app_control_s *app_control_request;
215
216         if (app_control == NULL)
217                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
218
219         app_control_request = malloc(sizeof(struct app_control_s));
220         if (app_control_request == NULL)
221                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
222
223         app_control_request->type = APP_CONTROL_TYPE_REQUEST;
224
225         if (data != NULL)
226                 app_control_request->data = bundle_dup(data);
227         else
228                 app_control_request->data = bundle_create();
229
230         if (app_control_request->data == NULL) {
231                 free(app_control_request);
232                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a bundle");
233         }
234
235         app_control_request->id = app_control_new_id();
236         app_control_request->launch_pid = -1;
237
238         *app_control = app_control_request;
239
240         return APP_CONTROL_ERROR_NONE;
241 }
242
243 int app_control_create(app_control_h *app_control)
244 {
245         return app_control_create_request(NULL, app_control);
246 }
247
248 int app_control_create_event(bundle *data, struct app_control_s **app_control)
249 {
250         struct app_control_s *app_control_event;
251
252         const char *operation;
253
254         if (data == NULL || app_control == NULL)
255                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
256
257         app_control_event = malloc(sizeof(struct app_control_s));
258         if (app_control_event == NULL)
259                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
260
261         app_control_event->type = APP_CONTROL_TYPE_EVENT;
262         app_control_event->data = bundle_dup(data);
263         app_control_event->id = app_control_new_id();
264
265         operation = appsvc_get_operation(app_control_event->data);
266         if (operation == NULL)
267                 appsvc_set_operation(app_control_event->data, APP_CONTROL_OPERATION_DEFAULT);
268
269         *app_control = app_control_event;
270
271         return APP_CONTROL_ERROR_NONE;
272 }
273
274 static int app_control_create_reply(bundle *data, struct app_control_s **app_control)
275 {
276         struct app_control_s *app_control_reply;
277
278         if (data == NULL || app_control == NULL)
279                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
280
281         app_control_reply = malloc(sizeof(struct app_control_s));
282         if (app_control_reply == NULL)
283                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
284
285         app_control_reply->type = APP_CONTROL_TYPE_REPLY;
286         app_control_reply->data = bundle_dup(data);
287         app_control_reply->id = app_control_new_id();
288
289         *app_control = app_control_reply;
290
291         return APP_CONTROL_ERROR_NONE;
292 }
293
294 int app_control_destroy(app_control_h app_control)
295 {
296         if (app_control_validate(app_control))
297                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
298
299         if (app_control->type == APP_CONTROL_TYPE_REQUEST && app_control->launch_pid > 0
300                         && bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED) == NULL)
301                 aul_remove_caller_cb(app_control->launch_pid, app_control);
302
303         bundle_free(app_control->data);
304         app_control->data = NULL;
305         free(app_control);
306
307         return APP_CONTROL_ERROR_NONE;
308 }
309
310 int app_control_to_bundle(app_control_h app_control, bundle **data)
311 {
312         if (app_control_validate(app_control) || data == NULL)
313                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
314
315         *data = app_control->data;
316
317         return APP_CONTROL_ERROR_NONE;
318 }
319
320 int app_control_set_operation(app_control_h app_control, const char *operation)
321 {
322         if (app_control_validate(app_control))
323                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
324
325         if (operation != NULL) {
326                 if (appsvc_set_operation(app_control->data, operation) != 0)
327                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid operation");
328         } else {
329                 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
330         }
331
332         return APP_CONTROL_ERROR_NONE;
333 }
334
335 int app_control_get_operation(app_control_h app_control, char **operation)
336 {
337         const char *operation_value;
338
339         if (app_control_validate(app_control) || operation == NULL)
340                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
341
342         operation_value = appsvc_get_operation(app_control->data);
343         if (operation_value != NULL)
344                 *operation = strdup(operation_value);
345         else
346                 *operation = NULL;
347
348         return APP_CONTROL_ERROR_NONE;
349 }
350
351 int app_control_set_uri(app_control_h app_control, const char *uri)
352 {
353         if (app_control_validate(app_control))
354                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
355
356         if (uri != NULL) {
357                 if (appsvc_set_uri(app_control->data, uri) != 0)
358                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid URI");
359         } else {
360                 bundle_del(app_control->data, BUNDLE_KEY_URI);
361         }
362
363         return APP_CONTROL_ERROR_NONE;
364 }
365
366 int app_control_get_uri(app_control_h app_control, char **uri)
367 {
368         const char *uri_value;
369
370         if (app_control_validate(app_control) || uri == NULL)
371                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
372
373         uri_value = appsvc_get_uri(app_control->data);
374         if (uri_value != NULL)
375                 *uri = strdup(uri_value);
376         else
377                 *uri = NULL;
378
379         return APP_CONTROL_ERROR_NONE;
380 }
381
382 int app_control_set_mime(app_control_h app_control, const char *mime)
383 {
384         if (app_control_validate(app_control))
385                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
386
387         if (mime != NULL) {
388                 if (appsvc_set_mime(app_control->data, mime) != 0)
389                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid MIME type");
390         } else {
391                 bundle_del(app_control->data, BUNDLE_KEY_MIME);
392         }
393
394         return APP_CONTROL_ERROR_NONE;
395 }
396
397 int app_control_get_mime(app_control_h app_control, char **mime)
398 {
399         const char *mime_value;
400
401         if (app_control_validate(app_control) || mime == NULL)
402                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
403
404         mime_value = appsvc_get_mime(app_control->data);
405         if (mime_value != NULL)
406                 *mime = strdup(mime_value);
407         else
408                 *mime = NULL;
409
410         return APP_CONTROL_ERROR_NONE;
411 }
412
413 int app_control_set_category(app_control_h app_control, const char *category)
414 {
415         if (app_control_validate(app_control))
416                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
417
418         if (category != NULL) {
419                 if (appsvc_set_category(app_control->data, category) != 0)
420                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid Category");
421         } else {
422                 bundle_del(app_control->data, BUNDLE_KEY_CATEGORY);
423         }
424
425         return APP_CONTROL_ERROR_NONE;
426 }
427
428 int app_control_get_category(app_control_h app_control, char **category)
429 {
430         const char *category_value;
431
432         if (app_control_validate(app_control) || category == NULL)
433                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
434
435         category_value = appsvc_get_category(app_control->data);
436         if (category_value != NULL)
437                 *category = strdup(category_value);
438         else
439                 *category = NULL;
440
441         return APP_CONTROL_ERROR_NONE;
442 }
443
444 int app_control_set_package(app_control_h app_control, const char *package)
445 {
446         /* TODO: this function must be deprecated */
447         return app_control_set_app_id(app_control, package);
448 }
449
450 int app_control_get_package(app_control_h app_control, char **package)
451 {
452         /* TODO: this function must be deprecated */
453         return app_control_get_app_id(app_control, package);
454 }
455
456 int app_control_set_app_id(app_control_h app_control, const char *app_id)
457 {
458         if (app_control_validate(app_control))
459                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
460
461         if (app_id != NULL) {
462                 if (appsvc_set_appid(app_control->data, app_id) != 0)
463                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid application ID");
464         } else {
465                 bundle_del(app_control->data, BUNDLE_KEY_PACKAGE);
466         }
467
468         return APP_CONTROL_ERROR_NONE;
469 }
470
471 int app_control_get_app_id(app_control_h app_control, char **app_id)
472 {
473         const char *app_id_value;
474
475         if (app_control_validate(app_control) || app_id == NULL)
476                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
477
478         app_id_value = appsvc_get_appid(app_control->data);
479         if (app_id_value != NULL)
480                 *app_id = strdup(app_id_value);
481         else
482                 *app_id = NULL;
483
484         return APP_CONTROL_ERROR_NONE;
485 }
486
487 int app_control_set_window(app_control_h app_control, unsigned int id)
488 {
489         if (app_control_validate(app_control))
490                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
491
492         if (id > 0) {
493                 if (appsvc_allow_transient_app(app_control->data, id) != 0)
494                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid id");
495         } else {
496                 bundle_del(app_control->data, BUNDLE_KEY_WINDOW);
497         }
498
499         return APP_CONTROL_ERROR_NONE;
500 }
501
502 int app_control_get_window(app_control_h app_control, unsigned int *id)
503 {
504         const char *window_id;
505
506         if (app_control_validate(app_control) || id == NULL)
507                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
508
509         window_id = bundle_get_val(app_control->data, BUNDLE_KEY_WINDOW);
510         if (window_id != NULL)
511                 *id = atoi(window_id);
512         else
513                 *id = 0;
514
515         return APP_CONTROL_ERROR_NONE;
516 }
517
518 int app_control_clone(app_control_h *clone, app_control_h app_control)
519 {
520         app_control_h app_control_clone;
521
522         if (app_control_validate(app_control) || clone == NULL)
523                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
524
525         app_control_clone = malloc(sizeof(struct app_control_s));
526         if (app_control_clone == NULL)
527                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create a app_control handle");
528
529         app_control_clone->id = app_control_new_id();
530         app_control_clone->type = app_control->type;
531         app_control_clone->data = bundle_dup(app_control->data);
532
533         *clone = app_control_clone;
534
535         return APP_CONTROL_ERROR_NONE;
536 }
537
538 int app_control_set_launch_mode(app_control_h app_control,
539                 app_control_launch_mode_e mode)
540 {
541         char launch_mode[LAUNCH_MODE_SIZE] = { 0, };
542
543         if (app_control_validate(app_control)) {
544                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
545                                 __FUNCTION__, NULL);
546         }
547
548         switch (mode) {
549         case APP_CONTROL_LAUNCH_MODE_SINGLE:
550                 strncpy(launch_mode, LAUNCH_MODE_SINGLE, strlen(LAUNCH_MODE_SINGLE));
551                 break;
552         case APP_CONTROL_LAUNCH_MODE_GROUP:
553                 strncpy(launch_mode, LAUNCH_MODE_GROUP, strlen(LAUNCH_MODE_GROUP));
554                 break;
555         default:
556                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
557                                 __FUNCTION__, "invalid mode");
558         }
559
560         return appsvc_set_launch_mode(app_control->data, launch_mode);
561 }
562
563 int app_control_get_launch_mode(app_control_h app_control,
564                 app_control_launch_mode_e *mode)
565 {
566         const char *launch_mode;
567
568         if (app_control_validate(app_control)) {
569                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
570                                 __FUNCTION__, NULL);
571         }
572
573         launch_mode = appsvc_get_launch_mode(app_control->data);
574         if (launch_mode == NULL) {
575                 *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
576         } else {
577                 if (!strcmp(launch_mode, LAUNCH_MODE_SINGLE)) {
578                         *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
579                 } else if (!strcmp(launch_mode, LAUNCH_MODE_GROUP)) {
580                         *mode = APP_CONTROL_LAUNCH_MODE_GROUP;
581                 } else {
582                         *mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
583                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER,
584                                         __FUNCTION__, "launch_mode is not matched");
585                 }
586         }
587
588         return APP_CONTROL_ERROR_NONE;
589 }
590
591 int app_control_set_defapp(app_control_h app_control, const char *app_id)
592 {
593         int ret;
594
595         if (app_control_validate(app_control) || app_id == NULL)
596                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
597
598         ret = aul_svc_set_appid(app_control->data, app_id);
599         if (ret < 0)
600                 return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
601
602         ret = aul_set_default_app_by_operation(app_control->data);
603         if (ret < 0) {
604                 if (ret == AUL_R_EILLACC)
605                         return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
606                 else
607                         return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
608         }
609
610         return APP_CONTROL_ERROR_NONE;
611 }
612
613 int app_control_unset_defapp(const char *app_id)
614 {
615         int ret;
616
617         if (app_id == NULL)
618                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
619
620         ret = aul_unset_default_app_by_operation(app_id);
621         if (ret < 0) {
622                 if (ret == AUL_R_EILLACC)
623                         return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
624                 else
625                         return app_control_error(APP_CONTROL_ERROR_IO_ERROR, __FUNCTION__, NULL);
626         }
627
628         return APP_CONTROL_ERROR_NONE;
629 }
630
631 static void __update_launch_pid(int launched_pid, void *data)
632 {
633         app_control_h app_control;
634
635         if (data == NULL)
636                 return;
637
638         app_control = data;
639
640         app_control->launch_pid = launched_pid;
641 }
642
643 static void __handle_launch_result(int launched_pid, void *data)
644 {
645         app_control_request_context_h request_context;
646         app_control_h reply = NULL;
647         app_control_h request;
648         app_control_result_e result;
649         app_control_reply_cb reply_cb;
650         void *user_data;
651         char callee[255] = {0, };
652         int ret = 0;
653
654         if (data == NULL)
655                 return;
656
657         request_context = (app_control_request_context_h)data;
658
659         if (app_control_create_event(request_context->app_control->data, &reply) != 0) {
660                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create app_control event");
661                 return;
662         }
663
664         ret = aul_app_get_appid_bypid(launched_pid, callee, sizeof(callee));
665         if (ret < 0)
666                 LOGE("aul_app_get_appid_bypid failed: %d", launched_pid);
667
668         app_control_set_app_id(reply, callee);
669         LOGI("app control async result callback callee pid:%d", launched_pid);
670
671         result = APP_CONTROL_RESULT_APP_STARTED;
672         request = request_context->app_control;
673         user_data = request_context->user_data;
674         reply_cb = request_context->reply_cb;
675
676         if (reply_cb != NULL)
677                 reply_cb(request, reply, result, user_data);
678         else
679                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid callback ");
680
681         app_control_destroy(reply);
682 }
683
684 int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data)
685 {
686         const char *operation;
687         bool implicit_default_operation = false;
688         int launch_pid;
689         app_control_request_context_h request_context = NULL;
690
691         if (app_control_validate(app_control))
692                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
693
694         operation = appsvc_get_operation(app_control->data);
695         if (operation == NULL) {
696                 implicit_default_operation = true;
697                 operation = APP_CONTROL_OPERATION_DEFAULT;
698         }
699
700         if (!strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT))
701                 return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__,
702                                 "Not supported operation value");
703
704         /* TODO: Check the privilege for call operation */
705
706         /* operation : default */
707         if (!strcmp(operation, APP_CONTROL_OPERATION_DEFAULT)) {
708                 const char *appid  = appsvc_get_appid(app_control->data);
709                 if (appid == NULL)
710                         return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, "package must be specified if the operation is default value");
711         }
712
713         if (callback != NULL) {
714                 app_control_h request_clone = NULL;
715
716                 request_context = calloc(1, sizeof(struct app_control_request_context_s));
717                 if (request_context == NULL)
718                         return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
719
720                 request_context->reply_cb = callback;
721
722                 if (app_control_clone(&request_clone, app_control) != APP_CONTROL_ERROR_NONE) {
723                         free(request_context);
724                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to clone the app_control request handle");
725                 }
726
727                 request_context->app_control = request_clone;
728                 request_context->user_data = user_data;
729         }
730
731         if (implicit_default_operation == true)
732                 appsvc_set_operation(app_control->data, APP_CONTROL_OPERATION_DEFAULT);
733
734         launch_pid = appsvc_usr_run_service(app_control->data, app_control->id, callback ? app_control_request_result_broker : NULL, request_context, getuid());
735         if (implicit_default_operation == true)
736                 bundle_del(app_control->data, BUNDLE_KEY_OPERATION);
737
738         if (launch_pid < 0) {
739                 if (launch_pid == APPSVC_RET_ENOMATCH)
740                         return app_control_error(APP_CONTROL_ERROR_APP_NOT_FOUND, __FUNCTION__, NULL);
741                 else if (launch_pid == APPSVC_RET_EILLACC)
742                         return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
743                 else if (launch_pid == APPSVC_RET_EINVAL)
744                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
745                 else
746                         return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
747         }
748
749         app_control->launch_pid = launch_pid;
750         /* app_control_enable_app_started_result_event called */
751         if (bundle_get_val(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED)) {
752                 char callee[255] = {0,};
753                 if (aul_app_get_appid_bypid(launch_pid, callee, sizeof(callee)) != AUL_R_OK)
754                         LOGE("aul_app_get_appid_bypid failed: %d", launch_pid);
755
756                 if (request_context && request_context->app_control)
757                         request_context->app_control->launch_pid = launch_pid;
758
759                 aul_add_caller_cb(launch_pid, __handle_launch_result, request_context);
760
761                 /* launched without app selector */
762                 if (strncmp(callee, APP_SELECTOR, strlen(APP_SELECTOR)) != 0)
763                         aul_invoke_caller_cb(request_context);
764
765         } else { /* default case */
766                 aul_add_caller_cb(launch_pid, __update_launch_pid, app_control);
767         }
768
769         return APP_CONTROL_ERROR_NONE;
770 }
771
772 int app_control_send_terminate_request(app_control_h app_control)
773 {
774         if (app_control_validate(app_control))
775                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
776
777         if (app_control->type != APP_CONTROL_TYPE_REQUEST || app_control->launch_pid < 0)
778                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
779
780         appsvc_subapp_terminate_request_pid(app_control->launch_pid);
781
782         return APP_CONTROL_ERROR_NONE;
783 }
784
785 static bool app_control_copy_reply_data_cb(app_control_h app_control, const char *key, void *user_data)
786 {
787         bundle *reply_data = user_data;
788         char *value = NULL;
789         char **value_array = NULL;
790         int value_array_length = 0;
791         int value_array_index = 0;
792
793         if (reply_data == NULL) {
794                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
795                 return false;
796         }
797
798         if (appsvc_data_is_array(app_control->data, key)) {
799                 app_control_get_extra_data_array(app_control, key, &value_array, &value_array_length);
800                 appsvc_add_data_array(reply_data, key, (const char **)value_array, value_array_length);
801
802                 for (value_array_index = 0; value_array_index < value_array_length; value_array_index++)
803                         free(value_array[value_array_index]);
804
805                 free(value_array);
806         } else {
807                 app_control_get_extra_data(app_control, key, &value);
808                 appsvc_add_data(reply_data, key, value);
809                 free(value);
810         }
811
812         return true;
813 }
814
815 int app_control_reply_to_launch_request(app_control_h reply, app_control_h request, app_control_result_e result)
816 {
817         bundle *reply_data;
818         int appsvc_result;
819         int ret = 0;
820
821         if (app_control_validate(reply) || app_control_validate(request))
822                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
823
824         if (result == APP_CONTROL_RESULT_APP_STARTED)
825                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "APP_CONTROL_RESULT_APP_STARTED is not allowed to use");
826
827         if (appsvc_create_result_bundle(request->data, &reply_data) != 0)
828                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to create a result bundle");
829
830         app_control_foreach_extra_data(reply, app_control_copy_reply_data_cb, reply_data);
831
832         switch (result) {
833         case APP_CONTROL_RESULT_SUCCEEDED:
834                 appsvc_result = APPSVC_RES_OK;
835                 break;
836         case APP_CONTROL_RESULT_FAILED:
837                 appsvc_result = APPSVC_RES_NOT_OK;
838                 break;
839         case APP_CONTROL_RESULT_CANCELED:
840                 appsvc_result = APPSVC_RES_CANCEL;
841                 break;
842         default:
843                 appsvc_result = APPSVC_RES_CANCEL;
844                 break;
845         }
846
847         ret = appsvc_send_result(reply_data, appsvc_result);
848         bundle_free(reply_data);
849         if (ret < 0) {
850                 if (ret == APPSVC_RET_EINVAL)
851                         return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
852                 else
853                         return app_control_error(APP_CONTROL_ERROR_LAUNCH_REJECTED, __FUNCTION__, NULL);
854         }
855
856         return APP_CONTROL_ERROR_NONE;
857 }
858
859
860 int app_control_add_extra_data(app_control_h app_control, const char *key, const char *value)
861 {
862         if (app_control_validate(app_control) || app_control_validate_extra_data(key) || app_control_validate_extra_data(value))
863                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
864
865         if (app_control_validate_internal_key(key))
866                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
867
868         if (appsvc_get_data(app_control->data, key) != NULL) {
869                 /* overwrite any existing value */
870                 bundle_del(app_control->data, key);
871         }
872
873         if (appsvc_add_data(app_control->data, key, value) != 0)
874                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add data to the appsvc handle");
875
876         return APP_CONTROL_ERROR_NONE;
877 }
878
879
880 int app_control_add_extra_data_array(app_control_h app_control, const char *key, const char* value[], int length)
881 {
882         if (app_control_validate(app_control) || app_control_validate_extra_data(key))
883                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
884
885         if (value == NULL || length <= 0)
886                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid array");
887
888         if (app_control_validate_internal_key(key))
889                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
890
891         if (appsvc_get_data_array(app_control->data, key, NULL) != NULL) {
892                 /* overwrite any existing value */
893                 bundle_del(app_control->data, key);
894         }
895
896         if (appsvc_add_data_array(app_control->data, key, value, length) != 0)
897                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "failed to add array data to the appsvc handle");
898
899         return APP_CONTROL_ERROR_NONE;
900 }
901
902 int app_control_remove_extra_data(app_control_h app_control, const char *key)
903 {
904         if (app_control_validate(app_control) || app_control_validate_extra_data(key))
905                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
906
907         if (app_control_validate_internal_key(key))
908                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
909
910         if (bundle_del(app_control->data, key))
911                 return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
912
913         return APP_CONTROL_ERROR_NONE;
914 }
915
916 int app_control_get_extra_data(app_control_h app_control, const char *key, char **value)
917 {
918         const char *data_value;
919
920         if (app_control_validate(app_control) || app_control_validate_extra_data(key) || value == NULL)
921                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
922
923         if (app_control_validate_internal_key(key))
924                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
925
926         data_value = appsvc_get_data(app_control->data, key);
927         if (data_value == NULL) {
928                 if (errno == ENOTSUP)
929                         return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
930                 else
931                         return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
932         }
933
934         *value = strdup(data_value);
935
936         return APP_CONTROL_ERROR_NONE;
937 }
938
939 int app_control_get_extra_data_array(app_control_h app_control, const char *key, char ***value, int *length)
940 {
941         const char **array_data;
942         int array_data_length;
943         char **array_data_clone;
944         int i;
945
946         if (app_control_validate(app_control) || app_control_validate_extra_data(key))
947                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
948
949         if (value == NULL || length == 0)
950                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
951
952         if (app_control_validate_internal_key(key))
953                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
954
955         array_data = appsvc_get_data_array(app_control->data, key, &array_data_length);
956         if (array_data == NULL) {
957                 if (errno == ENOTSUP)
958                         return app_control_error(APP_CONTROL_ERROR_INVALID_DATA_TYPE, __FUNCTION__, NULL);
959                 else
960                         return app_control_error(APP_CONTROL_ERROR_KEY_NOT_FOUND, __FUNCTION__, NULL);
961         }
962
963         array_data_clone = calloc(array_data_length, sizeof(char *));
964         if (array_data_clone == NULL)
965                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
966
967         for (i = 0; i < array_data_length; i++) {
968                 if (array_data[i] != NULL)
969                         array_data_clone[i] = strdup(array_data[i]);
970         }
971
972         *value = array_data_clone;
973         *length = array_data_length;
974
975         return APP_CONTROL_ERROR_NONE;
976 }
977
978 int app_control_is_extra_data_array(app_control_h app_control, const char *key, bool *array)
979 {
980         if (app_control_validate(app_control) || app_control_validate_extra_data(key) || array == NULL)
981                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
982
983         if (app_control_validate_internal_key(key))
984                 return app_control_error(APP_CONTROL_ERROR_KEY_REJECTED, __FUNCTION__, "the given key is reserved as internal use");
985
986         if (!appsvc_data_is_array(app_control->data, key))
987                 *array = false;
988         else
989                 *array = true;
990
991         return APP_CONTROL_ERROR_NONE;
992 }
993
994 typedef struct {
995         app_control_h app_control;
996         app_control_extra_data_cb callback;
997         void *user_data;
998         bool foreach_break;
999 } foreach_context_extra_data_t;
1000
1001 static void app_control_cb_broker_bundle_iterator(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
1002 {
1003         foreach_context_extra_data_t *foreach_context = NULL;
1004         app_control_extra_data_cb extra_data_cb;
1005
1006         if (key == NULL || !(type == BUNDLE_TYPE_STR || type == BUNDLE_TYPE_STR_ARRAY))
1007                 return;
1008
1009         foreach_context = (foreach_context_extra_data_t *)user_data;
1010         if (foreach_context->foreach_break == true)
1011                 return;
1012
1013         if (app_control_validate_internal_key(key))
1014                 return;
1015
1016         extra_data_cb = foreach_context->callback;
1017
1018         if (extra_data_cb != NULL) {
1019                 bool stop_foreach = false;
1020
1021                 stop_foreach = !extra_data_cb(foreach_context->app_control, key, foreach_context->user_data);
1022
1023                 foreach_context->foreach_break = stop_foreach;
1024         }
1025 }
1026
1027 int app_control_foreach_extra_data(app_control_h app_control, app_control_extra_data_cb callback, void *user_data)
1028 {
1029         foreach_context_extra_data_t foreach_context = {
1030                 .app_control = app_control,
1031                 .callback = callback,
1032                 .user_data = user_data,
1033                 .foreach_break = false
1034         };
1035
1036         if (app_control_validate(app_control) || callback == NULL)
1037                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1038
1039         bundle_foreach(app_control->data, app_control_cb_broker_bundle_iterator, &foreach_context);
1040
1041         return APP_CONTROL_ERROR_NONE;
1042 }
1043
1044 typedef struct {
1045         app_control_h app_control;
1046         app_control_app_matched_cb callback;
1047         void *user_data;
1048         bool foreach_break;
1049 } foreach_context_launchable_app_t;
1050
1051 int app_control_cb_broker_foreach_app_matched(const char *package, void *data)
1052 {
1053         foreach_context_launchable_app_t *foreach_context;
1054         app_control_app_matched_cb app_matched_cb;
1055
1056         if (package == NULL || data == NULL) {
1057                 app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1058                 return -1;
1059         }
1060
1061         foreach_context = (foreach_context_launchable_app_t *)data;
1062         if (foreach_context->foreach_break == true)
1063                 return -1;
1064
1065         app_matched_cb = foreach_context->callback;
1066         if (app_matched_cb != NULL) {
1067                 bool stop_foreach = false;
1068
1069                 stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
1070
1071                 foreach_context->foreach_break = stop_foreach;
1072         }
1073
1074         return 0;
1075 }
1076
1077 int app_control_foreach_app_matched(app_control_h app_control, app_control_app_matched_cb callback, void *user_data)
1078 {
1079         foreach_context_launchable_app_t foreach_context = {
1080                 .app_control = app_control,
1081                 .callback = callback,
1082                 .user_data = user_data,
1083                 .foreach_break = false
1084         };
1085
1086         if (app_control_validate(app_control) || callback == NULL)
1087                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1088
1089         appsvc_usr_get_list(app_control->data, app_control_cb_broker_foreach_app_matched, &foreach_context, getuid());
1090
1091         return APP_CONTROL_ERROR_NONE;
1092 }
1093
1094 int app_control_get_caller(app_control_h app_control, char **package)
1095 {
1096         const char *bundle_value;
1097         char *package_dup;
1098
1099         if (app_control_validate(app_control) || package == NULL)
1100                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1101
1102         if (app_control->type != APP_CONTROL_TYPE_EVENT)
1103                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1104
1105         bundle_value = bundle_get_val(app_control->data, AUL_K_CALLER_APPID);
1106         if (bundle_value == NULL)
1107                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to retrieve the appid of the caller");
1108
1109         package_dup = strdup(bundle_value);
1110         if (package_dup == NULL)
1111                 return app_control_error(APP_CONTROL_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1112
1113         *package = package_dup;
1114
1115         return APP_CONTROL_ERROR_NONE;
1116 }
1117
1118 int app_control_is_reply_requested(app_control_h app_control, bool *requested)
1119 {
1120         const char *bundle_value;
1121
1122         if (app_control_validate(app_control) || requested == NULL)
1123                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1124
1125         if (app_control->type != APP_CONTROL_TYPE_EVENT)
1126                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid app_control handle type");
1127
1128         bundle_value = bundle_get_val(app_control->data, AUL_K_WAIT_RESULT);
1129         if (bundle_value != NULL)
1130                 *requested = true;
1131         else
1132                 *requested = false;
1133
1134         return APP_CONTROL_ERROR_NONE;
1135 }
1136
1137 int app_control_import_from_bundle(app_control_h app_control, bundle *data)
1138 {
1139         bundle *data_dup = NULL;
1140
1141         if (app_control_validate(app_control) || data == NULL)
1142                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1143
1144         data_dup = bundle_dup(data);
1145         if (data_dup == NULL)
1146                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1147
1148         if (app_control->data != NULL)
1149                 bundle_free(app_control->data);
1150
1151         app_control->data = data_dup;
1152
1153         return APP_CONTROL_ERROR_NONE;
1154 }
1155
1156 int app_control_export_as_bundle(app_control_h app_control, bundle **data)
1157 {
1158         bundle *data_dup = NULL;
1159
1160         if (app_control_validate(app_control) || data == NULL)
1161                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1162
1163         data_dup = bundle_dup(app_control->data);
1164         if (data_dup == NULL)
1165                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, "failed to duplicate the bundle");
1166
1167         *data = data_dup;
1168
1169         return APP_CONTROL_ERROR_NONE;
1170 }
1171
1172 int app_control_request_transient_app(app_control_h app_control, unsigned int callee_id, app_control_host_res_fn cbfunc, void *data)
1173 {
1174         int ret;
1175
1176         if (app_control_validate(app_control))
1177                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1178
1179         ret = appsvc_request_transient_app(app_control->data, callee_id, (appsvc_host_res_fn)cbfunc, data);
1180         if (ret < 0)
1181                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1182
1183         return APP_CONTROL_ERROR_NONE;
1184 }
1185
1186 int app_control_enable_app_started_result_event(app_control_h app_control)
1187 {
1188         int ret;
1189
1190         if (app_control_validate(app_control))
1191                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1192
1193         ret = aul_svc_subscribe_launch_result(app_control->data, AUL_SVC_K_LAUNCH_RESULT_APP_STARTED);
1194         if (ret < 0)
1195                 return app_control_error(APP_CONTROL_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1196
1197         return APP_CONTROL_ERROR_NONE;
1198 }
1199