Fix wrong error log
[platform/core/appfw/aul-1.git] / src / aul_svc.cc
1 /*
2  * Copyright (c) 2021 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 #include <bundle.h>
18 #include <bundle_cpp.h>
19 #include <bundle_internal.h>
20 #include <glib.h>
21 #include <iniparser.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28
29 #include <memory>
30 #include <string>
31 #include <vector>
32
33 #include "aul/app_control/resolve_info.hh"
34 #include "include/aul.h"
35 #include "include/aul_app_group.h"
36 #include "include/aul_error.h"
37 #include "include/aul_sock.h"
38 #include "include/aul_svc.h"
39 #include "include/aul_svc_internal.h"
40 #include "src/aul_api.h"
41 #include "src/aul_svc_priv_key.h"
42 #include "src/aul_util.h"
43 #include "src/launch.h"
44
45 #undef MAX_MIME_STR_SIZE
46 #define MAX_MIME_STR_SIZE 256
47
48 #undef MAX_SCHEME_STR_SIZE
49 #define MAX_SCHEME_STR_SIZE 256
50
51 #undef MAX_HOST_STR_SIZE
52 #define MAX_HOST_STR_SIZE 256
53
54 #undef DEPRECATION_WARNING
55 #define DEPRECATION_WARNING() do {                                             \
56     dlog_print(DLOG_WARN, LOG_TAG,                                             \
57         "DEPRECATION WARNING: %s() is deprecated and "                         \
58         "will be removed from next release.", __FUNCTION__);                   \
59 } while (0)
60
61 namespace {
62
63 class CbInfo {
64  public:
65   CbInfo(int request_code, aul_svc_res_fn res_fn,
66       aul_svc_err_cb err_cb, void* user_data)
67       : request_code_(request_code),
68         res_fn_(res_fn),
69         err_cb_(err_cb),
70         user_data_(user_data) {
71   }
72
73   int request_code_;
74   aul_svc_res_fn res_fn_;
75   aul_svc_err_cb err_cb_;
76   void* user_data_;
77 };
78
79 int SetBundle(bundle* b, const char* key, const char* value) {
80   if (bundle_get_type(b, key) != BUNDLE_TYPE_NONE) {
81     if (bundle_del(b, key) != BUNDLE_ERROR_NONE)
82       return AUL_SVC_RET_ERROR;
83   }
84
85   if (value == nullptr)
86     return AUL_SVC_RET_EINVAL;
87
88   if (bundle_add(b, key, value) != BUNDLE_ERROR_NONE)
89     return AUL_SVC_RET_ERROR;
90
91   SECURE_LOGD("key(%s), value(%s)", key, value);
92   return AUL_SVC_RET_OK;
93 }
94
95 int SetBundleArray(bundle* b, const char* key, const char** value,
96     int len) {
97   int is_array = aul_svc_data_is_array(b, key);
98   if (is_array) {
99     if (bundle_del(b, key) != BUNDLE_ERROR_NONE)
100       return AUL_SVC_RET_ERROR;
101   }
102
103   if (value == nullptr)
104     return AUL_SVC_RET_EINVAL;
105
106   if (bundle_add_str_array(b, key, value, len) != BUNDLE_ERROR_NONE)
107     return AUL_SVC_RET_ERROR;
108
109   SECURE_LOGD("key(%s), length(%d)", key, len);
110   return AUL_SVC_RET_OK;
111 }
112
113 std::string GetAliasAppId(const char* appid) {
114   dictionary* dic = iniparser_load("/usr/share/appsvc/alias.ini");
115   if (dic == nullptr)
116     return {};
117
118   auto dic_ptr = std::unique_ptr<dictionary, decltype(iniparser_freedict)*>(
119       dic, iniparser_freedict);
120
121   std::string key = std::string("Alias:") + appid;
122   const char* value = iniparser_getstring(dic, key.c_str(), nullptr);
123   SECURE_LOGD("appid(%s), alias_id(%s)", appid, value);
124   if (value == nullptr)
125     return {};
126
127   return std::string(value);
128 }
129
130 bool IsSpecialApp(const char* appid) {
131   if (!strcmp(appid, APP_SELECTOR) || !strcmp(appid, SHARE_PANEL))
132     return true;
133
134   return false;
135 }
136
137 bool IsSpecialOperation(const char* operation) {
138   if (operation == nullptr)
139     return false;
140
141   int ret = strcmp(operation,
142       "http://tizen.org/appcontrol/operation/guide_privacy_setting");
143   if (ret == 0)
144     return true;
145
146   return false;
147 }
148
149 std::string GetAppId(bundle* request) {
150   const char* appid = aul_svc_get_pkgname(request);
151   if (appid == nullptr) {
152     if (aul_svc_get_operation(request) == nullptr) {
153       _E("Invalid request");
154       return {};
155     }
156
157     appid = "@UNKNOWN";
158   }
159
160   int ret = bundle_get_type(request, AUL_SVC_K_SELECTOR_EXTRA_LIST);
161   if (ret != BUNDLE_TYPE_NONE) {
162     if (appid == nullptr || !strcmp(appid, "@UNKNOWN"))
163       appid = APP_SELECTOR;
164   }
165
166   ret = bundle_get_type(request, AUL_K_FORCE_LAUNCH_APP_SELECTOR);
167   if (ret != BUNDLE_TYPE_NONE)
168     appid = APP_SELECTOR;
169
170   return std::string(appid);
171 }
172
173 void SetLaunchData(bundle* request, const std::string& appid) {
174   const char* operation = aul_svc_get_operation(request);
175   if (operation == nullptr)
176     aul_svc_set_operation(request, AUL_SVC_OPERATION_DEFAULT);
177
178   if (IsSpecialApp(appid.c_str()) || IsSpecialOperation(operation)) {
179     SetBundle(request, AUL_SVC_K_CAN_BE_LEADER, "true");
180     SetBundle(request, AUL_SVC_K_REROUTE, "true");
181     SetBundle(request, AUL_SVC_K_RECYCLE, "true");
182   }
183
184   const char* launch_mode = aul_svc_get_launch_mode(request);
185   if (launch_mode && !strcmp(launch_mode, "group")) {
186     int ret = bundle_get_type(request, AUL_K_INSTANCE_ID);
187     if (ret != BUNDLE_TYPE_NONE)
188       aul_set_instance_info(appid.c_str(), request);
189   }
190 }
191
192 int AulErrorConvert(int res) {
193   switch (res) {
194   case AUL_R_EILLACC:
195     return AUL_SVC_RET_EILLACC;
196   case AUL_R_EINVAL:
197     return AUL_SVC_RET_EINVAL;
198   case AUL_R_ETERMINATING:
199     return AUL_SVC_RET_ETERMINATING;
200   case AUL_R_EREJECTED:
201     return AUL_SVC_RET_EREJECTED;
202   case AUL_R_ENOAPP:
203     return AUL_SVC_RET_ENOMATCH;
204   case AUL_R_ECANCELED:
205     return AUL_SVC_RET_ECANCELED;
206   default:
207     return AUL_SVC_RET_ELAUNCH;
208   }
209 }
210
211 void LaunchWithResultCb(bundle* b, int is_cancel, void* data) {
212   int res;
213   if (is_cancel) {
214     res = AUL_SVC_RES_CANCEL;
215   } else {
216     const char* val = bundle_get_val(b, AUL_SVC_K_RES_VAL);
217     res = (val == nullptr) ? AUL_SVC_RES_NOT_OK : atoi(val);
218   }
219
220   bundle_del(b, AUL_SVC_K_RES_VAL);
221   auto* cb_info = static_cast<CbInfo*>(data);
222   if (cb_info == nullptr) {
223     _E("Invalid parameter");
224     return;
225   }
226
227   if (cb_info->res_fn_) {
228     cb_info->res_fn_(b, cb_info->request_code_,
229         static_cast<aul_svc_result_val>(res), cb_info->user_data_);
230     cb_info->res_fn_ = nullptr;
231   }
232
233   if (cb_info->err_cb_ != nullptr)
234     return;
235
236   delete cb_info;
237 }
238
239 void ErrorCb(int error, void* data) {
240   if (error < 0)
241     error = AulErrorConvert(error);
242
243   auto* cb_info = static_cast<CbInfo*>(data);
244   if (cb_info == nullptr) {
245     _E("Invalid parameter");
246     return;
247   }
248
249   if (cb_info->err_cb_) {
250     cb_info->err_cb_(cb_info->request_code_, error, cb_info->user_data_);
251     cb_info->err_cb_ = nullptr;
252   }
253
254   if (cb_info->res_fn_)
255     return;
256
257   delete cb_info;
258 }
259
260 using SendLaunchRequestCb =
261     int (*)(const std::string&, bundle*, uid_t, CbInfo*);
262 using SendLaunchRequestSyncCb =
263     int (*)(const std::string&, bundle*, uid_t, bundle**);
264
265 template <typename T, typename A>
266 int SendLaunchRequest(T cb, bundle* request, uid_t uid, A arg) {
267   if (request == nullptr) {
268     _E("Invalid parameter");
269     return AUL_SVC_RET_EINVAL;
270   }
271
272   std::string appid = GetAppId(request);
273   if (appid.empty()) {
274     _E("GetAppId() is failed");
275     return AUL_SVC_RET_EINVAL;
276   }
277
278   SetLaunchData(request, appid);
279   return cb(appid, request, uid, arg);
280 }
281
282 int SendAndReceive(int cmd, uid_t uid, bundle* request, bundle** response) {
283   int fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, cmd, request,
284       AUL_SOCK_ASYNC);
285   if (fd < 0)
286     return AUL_SVC_RET_ERROR;
287
288   app_pkt_t* pkt = nullptr;
289   int ret = aul_sock_recv_reply_pkt(fd, &pkt);
290   if (ret < 0) {
291     _E("Failed to receive reply packet. error(%d)", ret);
292     return AUL_SVC_RET_ERROR;
293   }
294
295   auto ptr = std::unique_ptr<app_pkt_t, decltype(std::free)*>(pkt, std::free);
296   if (pkt->cmd != APP_GET_INFO_OK && pkt->cmd != cmd) {
297     if (pkt->cmd == APP_GET_INFO_ERROR)
298       return AUL_SVC_RET_ERROR;
299
300     return AulErrorConvert(aul_error_convert(pkt->cmd));
301   }
302
303   bundle* b = nullptr;
304   if (pkt->opt & AUL_SOCK_BUNDLE) {
305     b = bundle_decode(pkt->data, pkt->len);
306     if (b == nullptr) {
307       _E("bundle_decode() is failed");
308       return AUL_SVC_RET_ENOMEM;
309     }
310   } else {
311     _E("Invalid packet");
312     return AUL_SVC_RET_ERROR;
313   }
314
315   *response = b;
316   return AUL_SVC_RET_OK;
317 }
318
319 }  // namespace
320
321 extern "C" API int aul_svc_set_operation(bundle* b, const char* operation) {
322   if (b == nullptr) {
323     _E("Invalid parameter");
324     return AUL_SVC_RET_EINVAL;
325   }
326
327   return ::SetBundle(b, AUL_SVC_K_OPERATION, operation);
328 }
329
330 extern "C" API int aul_svc_set_uri(bundle* b, const char* uri) {
331   if (b == nullptr) {
332     _E("Invalid parameter");
333     return AUL_SVC_RET_EINVAL;
334   }
335
336   return ::SetBundle(b, AUL_SVC_K_URI, uri);
337 }
338
339 extern "C" API int aul_svc_set_mime(bundle* b, const char* mime) {
340   if (b == nullptr) {
341     _E("Invalid parameter");
342     return AUL_SVC_RET_EINVAL;
343   }
344
345   return ::SetBundle(b, AUL_SVC_K_MIME, mime);
346 }
347
348 extern "C" API int aul_svc_add_data(bundle* b, const char* key,
349     const char* value) {
350   if (b == nullptr || key == nullptr)
351     return AUL_SVC_RET_EINVAL;
352
353   return ::SetBundle(b, key, value);
354 }
355
356 extern "C" API int aul_svc_add_data_array(bundle* b, const char* key,
357     const char** value, int len) {
358   if (b == nullptr || key == nullptr)
359     return AUL_SVC_RET_EINVAL;
360
361   return ::SetBundleArray(b, key, value, len);
362 }
363
364 extern "C" API int aul_svc_set_pkgname(bundle* b, const char* pkg_name) {
365   if (b == nullptr) {
366     _E("Invalid parameter");
367     return AUL_SVC_RET_EINVAL;
368   }
369
370   return ::SetBundle(b, AUL_SVC_K_PKG_NAME, pkg_name);
371 }
372
373 extern "C" API int aul_svc_set_appid(bundle* b, const char* appid) {
374   if (b == nullptr || appid == nullptr) {
375     _E("Invalid parameter");
376     return AUL_SVC_RET_EINVAL;
377   }
378
379   std::string alias_id = ::GetAliasAppId(appid);
380   if (!alias_id.empty())
381     appid = alias_id.c_str();
382
383   return ::SetBundle(b, AUL_SVC_K_PKG_NAME, appid);
384 }
385
386 extern "C" API int aul_svc_set_category(bundle* b, const char* category) {
387   if (b == nullptr) {
388     _E("Invalid parameter");
389     return AUL_SVC_RET_EINVAL;
390   }
391
392   return ::SetBundle(b, AUL_SVC_K_CATEGORY, category);
393 }
394
395 extern "C" API int aul_svc_set_launch_mode(bundle* b, const char* mode) {
396   if (b == nullptr) {
397     _E("Invalid parameter");
398     return AUL_SVC_RET_EINVAL;
399   }
400
401   return ::SetBundle(b, AUL_SVC_K_LAUNCH_MODE, mode);
402 }
403
404 extern "C" API int aul_svc_resolve(bundle* b, uid_t uid, char*** appid_array,
405     unsigned int* len) {
406   return aul_svc_get_appid_array(b, uid, appid_array, len);
407 }
408
409 extern "C" API int aul_svc_run_service(bundle* b, int request_code,
410     aul_svc_res_fn cbfunc, void* data) {
411   return aul_svc_run_service_for_uid(b, request_code, cbfunc, data, getuid());
412 }
413
414 extern "C" API int aul_svc_run_service_for_uid(bundle* b, int request_code,
415   aul_svc_res_fn cbfunc, void* data, uid_t uid) {
416   CbInfo* cb_info = nullptr;
417   if (cbfunc) {
418     cb_info = new (std::nothrow) CbInfo(request_code, cbfunc, nullptr, data);
419     if (cb_info == nullptr)
420       LOGE("Out of memory");
421   }
422
423   std::tuple<aul_svc_res_fn, void*> param { cbfunc, data };
424   int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
425       [](const std::string& appid, bundle* request, uid_t uid,
426           CbInfo* cb_info) -> int {
427         int ret;
428         if (cb_info) {
429           ret = aul_launch_app_with_result_for_uid(appid.c_str(), request,
430               LaunchWithResultCb, cb_info, uid);
431          } else {
432           ret = aul_launch_app_for_uid(appid.c_str(), request, uid);
433         }
434
435         return ret;
436       }, b, uid, cb_info);
437   if (ret < 0) {
438     if (cb_info)
439       delete cb_info;
440
441     ret = AulErrorConvert(ret);
442   }
443
444   return ret;
445 }
446
447 extern "C" API int aul_svc_get_list(bundle* b, aul_svc_info_iter_fn iter_fn,
448     void* data) {
449   return aul_svc_get_list_for_uid(b, iter_fn, data, getuid());
450 }
451
452 extern "C" API int aul_svc_get_list_for_uid(bundle* b,
453     aul_svc_info_iter_fn iter_fn, void* data, uid_t uid) {
454   if (b == nullptr || iter_fn == nullptr) {
455     _E("Invalid parameter");
456     return AUL_SVC_RET_EINVAL;
457   }
458
459   char** appid_array = nullptr;
460   unsigned int len = 0;
461   int ret = aul_svc_get_appid_array(b, uid, &appid_array, &len);
462   if (ret != AUL_SVC_RET_OK)
463     return ret;
464
465   if (len == 0) {
466     _E("Failed to find associated application");
467     aul_svc_free_appid_array(appid_array, len);
468     return AUL_SVC_RET_ENOMATCH;
469   }
470
471   for (unsigned int i = 0; i < len; ++i) {
472     SECURE_LOGD("APPID: %s", appid_array[i]);
473     if (iter_fn(appid_array[i], data) != 0)
474       break;
475   }
476
477   aul_svc_free_appid_array(appid_array, len);
478   return AUL_SVC_RET_OK;
479 }
480
481 extern "C" API int aul_svc_get_all_defapps(aul_svc_info_iter_fn iter_fn,
482     void* data) {
483   return aul_svc_get_all_defapps_for_uid(iter_fn, data, getuid());
484 }
485
486 extern "C" API int aul_svc_get_all_defapps_for_uid(aul_svc_info_iter_fn iter_fn,
487     void* data, uid_t uid) {
488   if (iter_fn == nullptr) {
489     _E("Invalid parameter");
490     return AUL_SVC_RET_EINVAL;
491   }
492
493   bundle* response;
494   tizen_base::Bundle request;
495   int ret = ::SendAndReceive(APP_GET_APP_CONTROL_DEFAULT_APPS, uid,
496       request.GetHandle(), &response);
497   if (ret != AUL_SVC_RET_OK)
498     return ret;
499
500   tizen_base::Bundle res(response, false, true);
501   auto appid_array = res.GetStringArray(AUL_K_APPID_LIST);
502   for (auto& appid : appid_array) {
503     if (iter_fn(appid.c_str(), data) != 0)
504       break;
505   }
506
507   return AUL_SVC_RET_OK;
508 }
509
510 extern "C" API const char* aul_svc_get_operation(bundle* b) {
511   return bundle_get_val(b, AUL_SVC_K_OPERATION);
512 }
513
514 extern "C" API const char* aul_svc_get_uri(bundle* b) {
515   return bundle_get_val(b, AUL_SVC_K_URI);
516 }
517
518 extern "C" API const char* aul_svc_get_mime(bundle* b) {
519   return bundle_get_val(b, AUL_SVC_K_MIME);
520 }
521
522 extern "C" API const char* aul_svc_get_data(bundle* b, const char* key) {
523   return bundle_get_val(b, key);
524 }
525
526 extern "C" API const char** aul_svc_get_data_array(bundle* b, const char* key,
527     int* len) {
528   return bundle_get_str_array(b, key, len);
529 }
530
531 extern "C" API const char* aul_svc_get_pkgname(bundle* b) {
532   return bundle_get_val(b, AUL_SVC_K_PKG_NAME);
533 }
534
535 extern "C" API const char* aul_svc_get_appid(bundle* b) {
536   return bundle_get_val(b, AUL_SVC_K_PKG_NAME);
537 }
538
539 extern "C" API const char* aul_svc_get_category(bundle* b) {
540   return bundle_get_val(b, AUL_SVC_K_CATEGORY);
541 }
542
543 extern "C" API const char* aul_svc_get_launch_mode(bundle* b) {
544   return bundle_get_val(b, AUL_SVC_K_LAUNCH_MODE);
545 }
546
547 extern "C" API int aul_svc_create_result_bundle(bundle* inb, bundle** outb) {
548   if (inb == nullptr || outb == nullptr) {
549     _E("Invalid parameter");
550     return AUL_SVC_RET_EINVAL;
551   }
552
553   int ret = aul_create_result_bundle(inb, outb);
554   if (ret != AUL_R_OK)
555     return AulErrorConvert(ret);
556
557   return AUL_SVC_RET_OK;
558 }
559
560 extern "C" API int aul_svc_send_result(bundle* b, aul_svc_result_val result) {
561   if (b == nullptr) {
562     _E("Invalid parameter");
563     return AUL_SVC_RET_EINVAL;
564   }
565
566   int ret = ::SetBundle(b, AUL_SVC_K_RES_VAL, std::to_string(result).c_str());
567   if (ret < 0)
568     return AUL_SVC_RET_ERROR;
569
570   if (result == AUL_SVC_RES_CANCEL)
571     ret = aul_send_result(b, 1);
572   else
573     ret = aul_send_result(b, 0);
574
575   bundle_del(b, AUL_SVC_K_RES_VAL);
576   return ret;
577 }
578
579 extern "C" API int aul_svc_data_is_array(bundle* b, const char* key) {
580   int type = bundle_get_type(b, key);
581   if (type <= 0)
582     return 0;
583
584   if (type & BUNDLE_TYPE_ARRAY)
585     return 1;
586
587   return 0;
588 }
589
590 extern "C" API int aul_svc_allow_transient_app(bundle* b, int wid) {
591   if (b == nullptr) {
592     _E("Invalid parameter");
593     return AUL_SVC_RET_EINVAL;
594   }
595
596   return ::SetBundle(b, AUL_SVC_K_WIN_ID, std::to_string(wid).c_str());
597 }
598
599 extern "C" API int aul_svc_request_transient_app(bundle* b, int callee_wid,
600     aul_svc_host_res_fn cbfunc, void* data) {
601   return 0;
602 }
603
604 extern "C" API int aul_svc_subapp_terminate_request_pid(int pid) {
605   int cpid = getpid();
606   int lcnt;
607   int* lpids = nullptr;
608   aul_app_group_get_leader_pids(&lcnt, &lpids);
609   for (int i = 0; i < lcnt; ++i) {
610     if (lpids[i] == cpid) {
611       int cnt;
612       int* pids = nullptr;
613       aul_app_group_get_group_pids(cpid, &cnt, &pids);
614       if (cnt == 0) {
615         free(lpids);
616         if (pids)
617           free(pids);
618
619         return aul_subapp_terminate_request_pid(pid);
620       }
621
622       if (pids != nullptr)
623         free(pids);
624       break;
625     }
626   }
627
628   if (lpids != nullptr)
629     free(lpids);
630
631   return aul_app_group_clear_top();
632 }
633
634 extern "C" API int aul_send_service_result(bundle* b) {
635   return aul_send_result(b, 0);
636 }
637
638 extern "C" API int aul_svc_subscribe_launch_result(bundle* b,
639     const char* result) {
640   if (b == nullptr) {
641     _E("Invalid parameter");
642     return AUL_SVC_RET_EINVAL;
643   }
644
645   return ::SetBundle(b, result, "1");
646 }
647
648 extern "C" API int aul_svc_set_loader_id(bundle* b, int loader_id) {
649   if (b == nullptr || loader_id <= 0) {
650     _E("Invalid parameter");
651     return AUL_SVC_RET_EINVAL;
652   }
653
654   return ::SetBundle(b, AUL_K_LOADER_ID, std::to_string(loader_id).c_str());
655 }
656
657 extern "C" API int aul_svc_set_loader_name(bundle* b, const char* loader_name) {
658   if (b == nullptr || loader_name == nullptr) {
659     _E("Invalid parameter");
660     return AUL_SVC_RET_EINVAL;
661   }
662
663   return ::SetBundle(b, AUL_K_LOADER_NAME, loader_name);
664 }
665
666 extern "C" API int aul_svc_set_background_launch(bundle* b, int enabled) {
667   if (b == nullptr) {
668     _E("Invalid parameter");
669     return AUL_SVC_RET_EINVAL;
670   }
671
672   return ::SetBundle(b, AUL_SVC_K_BG_LAUNCH, enabled ? "enable" : nullptr);
673 }
674
675 extern "C" API int aul_svc_get_appid_by_alias_appid(const char* alias_appid,
676     char** appid) {
677   return aul_svc_get_appid_by_alias_appid_for_uid(alias_appid, appid, getuid());
678 }
679
680 extern "C" API int aul_svc_get_appid_by_alias_appid_for_uid(
681     const char* alias_appid, char** appid, uid_t uid) {
682   if (alias_appid == nullptr || appid == nullptr) {
683     _E("Invalid parameter");
684     return AUL_SVC_RET_EINVAL;
685   }
686
687   bundle* response;
688   tizen_base::Bundle request;
689   request.Add(AUL_K_ALIAS_APPID, alias_appid);
690   int ret = ::SendAndReceive(APP_GET_APPID_BY_ALIAS_APPID, uid,
691       request.GetHandle(), &response);
692   if (ret != AUL_SVC_RET_OK)
693     return ret;
694
695   tizen_base::Bundle res(response, false, true);
696   auto val = res.GetString(AUL_K_APPID);
697   if (val.empty())
698     return AUL_SVC_RET_ERROR;
699
700   *appid = strdup(val.c_str());
701   if (*appid == nullptr) {
702     _E("Out of memory");
703     return AUL_SVC_RET_ENOMEM;
704   }
705
706   return AUL_SVC_RET_OK;
707 }
708
709 extern "C" API const char *aul_svc_get_instance_id(bundle* b) {
710   return bundle_get_val(b, AUL_K_INSTANCE_ID);
711 }
712
713 extern "C" API int aul_svc_set_instance_id(bundle* b, const char* instance_id) {
714   if (b == nullptr) {
715     _E("Invalid parameter");
716     return AUL_SVC_RET_EINVAL;
717   }
718
719   return ::SetBundle(b, AUL_K_INSTANCE_ID, instance_id);
720 }
721
722 extern "C" API int aul_svc_run_service_async(bundle* b, int request_code,
723     aul_svc_res_fn cbfunc, void* data) {
724   return aul_svc_run_service_async_for_uid(b, request_code, cbfunc, data,
725       getuid());
726 }
727
728 extern "C" API int aul_svc_run_service_async_for_uid(bundle* b,
729     int request_code, aul_svc_res_fn cbfunc, void* data, uid_t uid) {
730   CbInfo* cb_info = nullptr;
731   if (cbfunc)
732     cb_info = new (std::nothrow) CbInfo(request_code, cbfunc, nullptr, data);
733
734   int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
735       [](const std::string& appid, bundle* request, uid_t uid,
736           CbInfo* info) -> int {
737         if (info) {
738           return aul_launch_app_with_result_async_for_uid(appid.c_str(),
739               request, LaunchWithResultCb, info, uid);
740         }
741
742         return aul_launch_app_async_for_uid(appid.c_str(), request, uid);
743       }, b, uid, cb_info);
744   if (ret < 0) {
745     if (cb_info)
746       delete cb_info;
747
748     ret = AulErrorConvert(ret);
749   }
750
751   return ret;
752 }
753
754 extern "C" API int aul_svc_send_launch_request(bundle* b, int request_code,
755     aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb, void* user_data) {
756   return aul_svc_send_launch_request_for_uid(b, request_code,
757       cbfunc, err_cb, user_data, getuid());
758 }
759
760 extern "C" API int aul_svc_send_launch_request_for_uid(bundle* b,
761     int request_code, aul_svc_res_fn cbfunc, aul_svc_err_cb err_cb,
762     void* user_data, uid_t uid) {
763   if (b == nullptr || err_cb == nullptr) {
764     _E("Invalid parameter");
765     return AUL_SVC_RET_EINVAL;
766   }
767
768   CbInfo* cb_info = new (std::nothrow) CbInfo(request_code, cbfunc, err_cb,
769       user_data);
770   if (cb_info == nullptr)
771     _E("Out of memory");
772
773   int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
774       [](const std::string& appid, bundle* request, uid_t uid,
775         CbInfo* info) -> int {
776         return aul_send_launch_request_for_uid(appid.c_str(), request, uid,
777             info->res_fn_ ? ::LaunchWithResultCb : nullptr, ::ErrorCb, info);
778       }, b, uid, cb_info);
779   if (ret < 0) {
780     delete cb_info;
781     ret = ::AulErrorConvert(ret);
782   }
783
784   return ret;
785 }
786
787 extern "C" API int aul_svc_send_launch_request_sync_for_uid(bundle* b,
788     int request_code, bundle** res_b, aul_svc_result_val* res, uid_t uid) {
789   if (b == nullptr || res_b == nullptr || res == nullptr) {
790     _E("Invalid parameter");
791     return AUL_SVC_RET_EINVAL;
792   }
793
794   int ret = ::SendLaunchRequest<::SendLaunchRequestSyncCb, bundle**>(
795       [](const std::string& appid, bundle* request, uid_t uid,
796           bundle** response) -> int {
797         return aul_send_launch_request_sync_for_uid(appid.c_str(), request,
798             uid, response);
799       }, b, uid, res_b);
800   if (ret > 0) {
801     auto* val = bundle_get_val(*res_b, AUL_SVC_K_RES_VAL);
802     *res = static_cast<aul_svc_result_val>(
803         (val == nullptr) ? AUL_SVC_RES_NOT_OK : atoi(val));
804   } else {
805     ret = ::AulErrorConvert(ret);
806     *res = AUL_SVC_RES_CANCEL;
807   }
808
809   return ret;
810 }
811
812 extern "C" API int aul_svc_info_create(bundle* b, aul_svc_info_h* h) {
813   if (b == nullptr || h == nullptr) {
814     _E("Invalid parameter");
815     return AUL_SVC_RET_EINVAL;
816   }
817
818   aul::ResolveInfo* resolve_info = nullptr;
819   try {
820     tizen_base::Bundle kb(b, false, false);
821     resolve_info = aul::ResolveInfo::Manager::Create(kb);
822   } catch (aul::Exception& e) {
823     return AUL_SVC_RET_ERROR;
824   }
825
826   *h = static_cast<aul_svc_info_h>(resolve_info);
827   return AUL_SVC_RET_OK;
828 }
829
830 extern "C" API int aul_svc_info_get_operation(aul_svc_info_h h,
831     char** operation) {
832   if (h == nullptr || operation == nullptr) {
833     _E("Invalid parameter");
834     return AUL_SVC_RET_EINVAL;
835   }
836
837   auto* info = static_cast<aul::ResolveInfo*>(h);
838   auto& value = info->GetOperation();
839   *operation = strdup(value.empty() ? "NULL" : value.c_str());
840   if (*operation == nullptr) {
841     _E("Failed to duplicate operation");
842     return AUL_SVC_RET_ERROR;
843   }
844
845   return AUL_SVC_RET_OK;
846 }
847
848 extern "C" API int aul_svc_info_get_uri(aul_svc_info_h h, char** uri) {
849   if (h == nullptr || uri == nullptr) {
850     _E("Invalid parameter");
851     return AUL_SVC_RET_EINVAL;
852   }
853
854   auto* info = static_cast<aul::ResolveInfo*>(h);
855   auto& value = info->GetUri();
856   *uri = strdup(value.empty() ? "NULL" : value.c_str());
857   if (*uri == nullptr) {
858     _E("Failed to duplicate URI");
859     return AUL_SVC_RET_ERROR;
860   }
861
862   return AUL_SVC_RET_OK;
863 }
864
865 extern "C" API int aul_svc_info_get_uri_scheme(aul_svc_info_h h,
866     char** uri_scheme) {
867   if (h == nullptr || uri_scheme == nullptr) {
868     _E("Invalid parameter");
869     return AUL_SVC_RET_EINVAL;
870   }
871
872   auto* info = static_cast<aul::ResolveInfo*>(h);
873   auto& value = info->GetScheme();
874   *uri_scheme = strdup(value.empty() ? "NULL" : value.c_str());
875   if (*uri_scheme == nullptr) {
876     _E("Failed to duplicate URI scheme");
877     return AUL_SVC_RET_ERROR;
878   }
879
880   return AUL_SVC_RET_OK;
881 }
882
883 extern "C" API int aul_svc_info_get_uri_host(aul_svc_info_h h,
884     char** uri_host) {
885   if (h == nullptr || uri_host == nullptr) {
886     _E("Invalid parameter");
887     return AUL_SVC_RET_EINVAL;
888   }
889
890   auto* info = static_cast<aul::ResolveInfo*>(h);
891   auto& value = info->GetHost();
892   *uri_host = strdup(value.empty() ? "NULL" : value.c_str());
893   if (*uri_host == nullptr) {
894     _E("Failed to duplicate URI host");
895     return AUL_SVC_RET_ERROR;
896   }
897
898   return AUL_SVC_RET_OK;
899 }
900
901 extern "C" API int aul_svc_info_get_mime(aul_svc_info_h h, char** mime) {
902   if (h == nullptr || mime == nullptr) {
903     _E("Invalid parameter");
904     return AUL_SVC_RET_EINVAL;
905   }
906
907   auto* info = static_cast<aul::ResolveInfo*>(h);
908   auto& value = info->GetMime();
909   *mime = strdup(value.empty() ? "NULL" : value.c_str());
910   if (*mime == nullptr) {
911     _E("Failed to duplicate MIME-Type");
912     return AUL_SVC_RET_ERROR;
913   }
914
915   return AUL_SVC_RET_OK;
916 }
917
918 extern "C" API int aul_svc_info_get_mime_type(aul_svc_info_h h,
919     char** mime_type) {
920   if (h == nullptr || mime_type == nullptr) {
921     _E("Invalid parameter");
922     return AUL_SVC_RET_EINVAL;
923   }
924
925   auto* info = static_cast<aul::ResolveInfo*>(h);
926   auto& value = info->GetMType();
927   *mime_type = strdup(value.empty() ? "NULL" : value.c_str());
928   if (*mime_type == nullptr) {
929     _E("Failed to duplicate the type of MIME-Type");
930     return AUL_SVC_RET_ERROR;
931   }
932
933   return AUL_SVC_RET_OK;
934 }
935
936 extern "C" API int aul_svc_info_get_mime_subtype(aul_svc_info_h h,
937     char** mime_subtype) {
938   if (h == nullptr || mime_subtype == nullptr) {
939     _E("Invalid parameter");
940     return AUL_SVC_RET_EINVAL;
941   }
942
943   auto* info = static_cast<aul::ResolveInfo*>(h);
944   auto& value = info->GetSType();
945   *mime_subtype = strdup(value.empty() ? "NULL" : value.c_str());
946   if (*mime_subtype == nullptr) {
947     _E("Failed to duplicate the subtype of MIME-Type");
948     return AUL_SVC_RET_ERROR;
949   }
950
951   return AUL_SVC_RET_OK;
952 }
953
954 extern "C" API int aul_svc_info_destroy(aul_svc_info_h h) {
955   if (h == nullptr) {
956     _E("Invalid parameter");
957     return AUL_SVC_RET_EINVAL;
958   }
959
960   auto* info = static_cast<aul::ResolveInfo*>(h);
961   delete info;
962   return AUL_SVC_RET_OK;
963 }
964
965 extern "C" API int aul_svc_set_caller_instance_id(bundle* b,
966     const char* instance_id) {
967   if (b == nullptr) {
968     _E("Invalid parameter");
969     return AUL_SVC_RET_EINVAL;
970   }
971
972   return ::SetBundle(b, AUL_K_CALLER_INSTANCE_ID, instance_id);
973 }
974
975 extern "C" API int aul_svc_set_comp_id(bundle* b, const char* comp_id) {
976   if (b == nullptr) {
977     _E("Invalid parameter");
978     return AUL_SVC_RET_EINVAL;
979   }
980
981   return ::SetBundle(b, AUL_K_COMPONENT_ID, comp_id);
982 }
983
984 extern "C" API const char *aul_svc_get_comp_id(bundle* b) {
985   return bundle_get_val(b, AUL_K_COMPONENT_ID);
986 }
987
988 extern "C" API int aul_svc_subapp_terminate_request(bundle* b, int pid) {
989   if (b == nullptr || pid < 0) {
990     _E("Invalid parameter");
991     return AUL_SVC_RET_EINVAL;
992   }
993
994   const char* inst_id = bundle_get_val(b, AUL_K_INSTANCE_ID);
995   if (inst_id == nullptr) {
996     _E("Invalid parameter");
997     return AUL_SVC_RET_EINVAL;
998   }
999
1000   char buf[512] = { 0, };
1001   const char* caller_inst_id = bundle_get_val(b, AUL_K_CALLER_INSTANCE_ID);
1002   if (caller_inst_id == nullptr) {
1003     int ret = aul_app_get_instance_id_bypid(getpid(), buf, sizeof(buf));
1004     if (ret != AUL_R_OK) {
1005       _E("aul_app_get_instance_id_bypid() is failed. error(%d)", ret);
1006       return AUL_SVC_RET_ERROR;
1007     }
1008
1009     caller_inst_id = buf;
1010   }
1011
1012   int cnt = 0;
1013   aul_app_group_foreach_group_info(caller_inst_id,
1014       [](aul_app_group_info_h info, void* data) {
1015       int* count = static_cast<int*>(data);
1016       (*count)++;
1017       }, static_cast<void*>(&cnt));
1018   if (cnt == 0)
1019     return aul_subapp_terminate_request(inst_id, pid);
1020
1021   return aul_app_group_clear_top();
1022 }
1023
1024 extern "C" API int aul_svc_send_resume_request(bundle* b, int request_code,
1025     aul_svc_err_cb err_cb, void *user_data) {
1026   return aul_svc_send_resume_request_for_uid(b, request_code, err_cb, user_data,
1027       getuid());
1028 }
1029
1030 extern "C" API int aul_svc_send_resume_request_for_uid(bundle* b,
1031     int request_code, aul_svc_err_cb err_cb, void* user_data, uid_t uid) {
1032   if (b == nullptr || err_cb == nullptr) {
1033     _E("Invalid parameter");
1034     return AUL_SVC_RET_EINVAL;
1035   }
1036
1037   auto* cb_info = new (std::nothrow) CbInfo(request_code, nullptr, err_cb,
1038       user_data);
1039   if (cb_info == nullptr)
1040     _E("Out of memory");
1041
1042   int ret = ::SendLaunchRequest<::SendLaunchRequestCb, ::CbInfo*>(
1043       [](const std::string& appid, bundle* request, uid_t uid,
1044           CbInfo* info) -> int {
1045         return aul_send_resume_request_for_uid(appid.c_str(), request, uid,
1046             ErrorCb, info);
1047       }, b, uid, cb_info);
1048   if (ret < 0) {
1049     delete cb_info;
1050     ret = ::AulErrorConvert(ret);
1051   }
1052
1053   return ret;
1054 }
1055
1056 extern "C" API int aul_svc_get_appid_array(bundle* b, uid_t uid,
1057     char*** appid_array, unsigned int* len) {
1058   if (b == nullptr || appid_array == nullptr || len == nullptr) {
1059     _E("Invalid parameter");
1060     return AUL_SVC_RET_EINVAL;
1061   }
1062
1063   bundle_del(b, AUL_K_APPID);
1064   bundle_add(b, AUL_K_APPID, "@UNKNOWN");
1065
1066   bundle* response;
1067   int ret = ::SendAndReceive(APP_GET_APPID_LIST, uid, b, &response);
1068   if (ret != AUL_SVC_RET_OK)
1069     return ret;
1070
1071   tizen_base::Bundle res(response, false, true);
1072   auto str = res.GetString(AUL_SVC_K_URI_R_INFO);
1073   if (!str.empty())
1074     ::SetBundle(b, AUL_SVC_K_URI_R_INFO, str.c_str());
1075
1076   auto str_arr = res.GetStringArray(AUL_K_APPID_LIST);
1077   if (str_arr.empty()) {
1078     _E("Failed to get appid list");
1079     return AUL_SVC_RET_ERROR;
1080   }
1081
1082   *appid_array = reinterpret_cast<char**>(
1083       calloc(str_arr.size(), sizeof(char*)));
1084   if (*appid_array == nullptr) {
1085     _E("Out of memory");
1086     return AUL_SVC_RET_ENOMEM;
1087   }
1088
1089   *len = str_arr.size();
1090
1091   int i = 0;
1092   for (auto& appid : str_arr)
1093     (*appid_array)[i++] = strdup(appid.c_str());
1094
1095   return AUL_SVC_RET_OK;
1096 }
1097
1098 extern "C" API void aul_svc_free_appid_array(char** appid_array,
1099     unsigned int len) {
1100   if (appid_array == nullptr)
1101     return;
1102
1103   for (unsigned int i = 0; i < len; ++i)
1104     free(appid_array[i]);
1105
1106   free(appid_array);
1107 }
1108
1109 extern "C" API int aul_svc_set_defapp(const char* op, const char* mime_type,
1110     const char* uri, const char* defapp) {
1111   DEPRECATION_WARNING();
1112   return AUL_SVC_RET_OK;
1113 }
1114
1115 extern "C" API int aul_svc_set_defapp_for_uid(const char* op,
1116     const char* mime_type, const char* uri, const char* defapp, uid_t uid) {
1117   DEPRECATION_WARNING();
1118   return AUL_SVC_RET_OK;
1119 }
1120
1121 extern "C" API int aul_svc_unset_defapp(const char* defapp) {
1122   DEPRECATION_WARNING();
1123   return AUL_SVC_RET_OK;
1124 }
1125
1126 extern "C" API int aul_svc_unset_defapp_for_uid(const char* defapp, uid_t uid) {
1127   DEPRECATION_WARNING();
1128   return AUL_SVC_RET_OK;
1129 }
1130
1131 extern "C" API int aul_svc_unset_all_defapps(void) {
1132   DEPRECATION_WARNING();
1133   return AUL_SVC_RET_OK;
1134 }
1135
1136 extern "C" API int aul_svc_unset_all_defapps_for_uid(uid_t uid) {
1137   DEPRECATION_WARNING();
1138   return AUL_SVC_RET_OK;
1139 }
1140
1141 extern "C" API int aul_svc_is_defapp(const char* pkg_name) {
1142   DEPRECATION_WARNING();
1143   return AUL_SVC_RET_OK;
1144 }
1145
1146 extern "C" API int aul_svc_is_defapp_for_uid(const char* pkg_name, uid_t uid) {
1147   DEPRECATION_WARNING();
1148   return AUL_SVC_RET_OK;
1149 }
1150
1151 extern "C" API int aul_svc_set_alias_appid(const char* alias_appid,
1152     const char* appid) {
1153   DEPRECATION_WARNING();
1154   return AUL_SVC_RET_OK;
1155 }
1156
1157 extern "C" API int aul_svc_set_alias_appid_for_uid(const char* alias_appid,
1158     const char* appid, uid_t uid) {
1159   DEPRECATION_WARNING();
1160   return AUL_SVC_RET_OK;
1161 }
1162
1163 extern "C" API int aul_svc_unset_alias_appid(const char* alias_appid) {
1164   DEPRECATION_WARNING();
1165   return AUL_SVC_RET_OK;
1166 }
1167
1168 extern "C" API int aul_svc_unset_alias_appid_for_uid(const char* alias_appid,
1169     uid_t uid) {
1170   DEPRECATION_WARNING();
1171   return AUL_SVC_RET_OK;
1172 }
1173
1174 extern "C" API int aul_svc_foreach_alias_info(
1175     void (*callback)(const char *, const char *, void *),
1176     void* user_data) {
1177   DEPRECATION_WARNING();
1178   return AUL_SVC_RET_OK;
1179 }
1180
1181 extern "C" API int aul_svc_foreach_alias_info_for_uid(
1182     void (*callback)(const char *, const char *, void *),
1183     uid_t uid, void* user_data) {
1184   DEPRECATION_WARNING();
1185   return AUL_SVC_RET_OK;
1186 }
1187
1188 extern "C" API int aul_svc_enable_alias_info(const char* appid) {
1189   DEPRECATION_WARNING();
1190   return AUL_SVC_RET_OK;
1191 }
1192
1193 extern "C" API int aul_svc_enable_alias_info_for_uid(const char* appid,
1194     uid_t uid) {
1195   DEPRECATION_WARNING();
1196   return AUL_SVC_RET_OK;
1197 }
1198
1199 extern "C" API int aul_svc_disable_alias_info(const char* appid) {
1200   DEPRECATION_WARNING();
1201   return AUL_SVC_RET_OK;
1202 }
1203
1204 extern "C" API int aul_svc_disable_alias_info_for_uid(const char* appid,
1205     uid_t uid) {
1206   DEPRECATION_WARNING();
1207   return AUL_SVC_RET_OK;
1208 }
1209
1210 extern "C" API int aul_svc_foreach_alias_info_by_appid(
1211     int (*callback)(const char *, const char *, void *),
1212     const char* appid, void* user_data) {
1213   DEPRECATION_WARNING();
1214   return AUL_SVC_RET_OK;
1215 }
1216
1217 extern "C" API int aul_svc_foreach_alias_info_by_appid_for_uid(
1218     int (*callback)(const char *, const char *, void *),
1219     const char* appid, uid_t uid, void* user_data) {
1220   DEPRECATION_WARNING();
1221   return AUL_SVC_RET_OK;
1222 }
1223
1224 extern "C" API int aul_svc_foreach_allowed_info(
1225     int (*callback)(const char *, const char *, void *),
1226     void* user_data) {
1227   DEPRECATION_WARNING();
1228   return AUL_SVC_RET_OK;
1229 }
1230
1231 extern "C" API int aul_svc_foreach_allowed_info_for_uid(
1232     int (*callback)(const char *, const char *, void *),
1233     uid_t uid, void* user_data) {
1234   DEPRECATION_WARNING();
1235   return AUL_SVC_RET_OK;
1236 }
1237
1238 extern "C" API int aul_svc_foreach_allowed_info_by_appid(
1239     int (*callback)(const char *, const char *, void *),
1240     const char* appid, void* user_data) {
1241   DEPRECATION_WARNING();
1242   return AUL_SVC_RET_OK;
1243 }
1244
1245 extern "C" API int aul_svc_foreach_allowed_info_by_appid_for_uid(
1246     int (*callback)(const char *, const char *, void *),
1247     const char* appid, uid_t uid, void* user_data) {
1248   DEPRECATION_WARNING();
1249   return AUL_SVC_RET_OK;
1250 }