Move function definition to aul header
[platform/core/appfw/aul-1.git] / src / aul_comp_info.cc
1 /*
2  * Copyright (c) 2019 - 2022 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 "include/aul_comp_info.h"
18
19 #include <vconf.h>
20
21 #include <cctype>
22 #include <memory>
23 #include <string>
24 #include <vector>
25
26 #include "app_request.h"
27 #include "aul_api.h"
28 #include "aul_util.h"
29 #include "include/aul.h"
30 #include "include/aul_error.h"
31 #include "include/aul_sock.h"
32
33 #include "aul/common/exception.hh"
34 #include "aul/component/component_info.hh"
35
36 using namespace aul;
37
38 namespace {
39 using namespace aul::internal;
40
41 constexpr const char kDefaultLocale[] = "No Locale";
42
43 std::string GetSystemLocale() {
44   char* lang = vconf_get_str(VCONFKEY_LANGSET);
45   if (lang == nullptr) {
46     lang = strdup(kDefaultLocale);
47     if (lang == nullptr) {
48       _E("strdup() is failed");
49       THROW(AUL_R_ENOMEM);
50     }
51   }
52
53   auto lang_auto = std::unique_ptr<char, decltype(std::free)*>(lang, std::free);
54
55   return std::string({
56         lang[0],
57         lang[1],
58         '-',
59         static_cast<char>(std::tolower(static_cast<int>(lang[3]))),
60         static_cast<char>(std::tolower(static_cast<int>(lang[4])))
61       });
62 }
63
64 ComponentInfo* CreateComponentInfoFromAppPacket(
65     app_pkt_t* pkt) {
66   if (pkt->cmd != APP_GET_INFO_OK)
67     THROW(aul_error_convert(pkt->cmd));
68
69   bundle* kb = nullptr;
70   if (pkt->opt & AUL_SOCK_BUNDLE) {
71     kb = bundle_decode(pkt->data, pkt->len);
72     if (kb == nullptr)
73       THROW(AUL_R_ENOMEM);
74   } else {
75     THROW(AUL_R_ERROR);
76   }
77
78   tizen_base::Bundle b(kb, false, true);
79   return ComponentInfo::Builder()
80       .SetAppId(b)
81       .SetComponentId(b)
82       .SetType(b)
83       .SetLaunchMode(b)
84       .SetMainComponent(b)
85       .SetIconDisplay(b)
86       .SetTaskmanage(b)
87       .SetLocalizedInfo(b);
88 }
89
90 ComponentInfo* GetComponentInfo(const char* comp_id,
91     uid_t uid) {
92   tizen_base::Bundle b { { AUL_K_COMPONENT_ID, comp_id } };
93   int fd = AppRequest(COMP_INFO_GET, uid)
94       .With(std::move(b))
95       .SendSimply(AUL_SOCK_ASYNC);
96   if (fd < 0)
97     THROW(fd);
98
99   app_pkt_t* pkt = nullptr;
100   int ret = aul_sock_recv_reply_pkt(fd, &pkt);
101   if (ret < 0)
102     THROW(aul_error_convert(ret));
103
104   auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
105       pkt, std::free);
106   return CreateComponentInfoFromAppPacket(pkt);
107 }
108
109 std::vector<std::shared_ptr<ComponentInfo>> GetComponentInfos(uid_t uid) {
110   int fd = AppRequest(COMP_INFO_FOREACH, uid)
111       .SendSimply(AUL_SOCK_ASYNC);
112   if (fd < 0)
113     THROW(fd);
114
115   std::vector<std::shared_ptr<ComponentInfo>> component_infos;
116   int ret = aul_sock_recv_pkt_with_cb(fd,
117       [](app_pkt_t* pkt, void* user_data) {
118         if (pkt == nullptr)
119           return;
120
121         try {
122           auto* infos =
123               static_cast<std::vector<std::shared_ptr<ComponentInfo>>*>(
124                   user_data);
125           infos->emplace_back(CreateComponentInfoFromAppPacket(pkt));
126         } catch (const Exception& e) {
127           _E("Exception occurs. error(%s)", e.what());
128         }
129       }, &component_infos);
130   if (ret < 0)
131     THROW(aul_error_convert(ret));
132
133   return component_infos;
134 }
135
136 }  // namespace
137
138 extern "C" API int aul_comp_info_create(const char* comp_id,
139     aul_comp_info_h* handle) {
140   return aul_comp_info_usr_create(comp_id, getuid(), handle);
141 }
142
143 extern "C" API int aul_comp_info_usr_create(const char* comp_id, uid_t uid,
144     aul_comp_info_h* handle) {
145   if(comp_id == nullptr || handle == nullptr) {
146     _E("Invalid parameter");
147     return AUL_R_EINVAL;
148   }
149
150   try {
151     auto* info = GetComponentInfo(comp_id, uid);
152     *handle = static_cast<aul_comp_info_h>(info);
153   } catch (const Exception& e) {
154     _E("Exception occurs. error(%s)", e.what());
155     return e.GetErrorCode();
156   }
157
158   return AUL_R_OK;
159 }
160
161 extern "C" API int aul_comp_info_destroy(aul_comp_info_h handle) {
162   if (handle == nullptr) {
163     _E("Invalid parameter");
164     return AUL_R_EINVAL;
165   }
166
167   auto* info = static_cast<ComponentInfo*>(handle);
168   delete info;
169   return AUL_R_OK;
170 }
171
172 extern "C" API int aul_comp_info_clone(aul_comp_info_h handle,
173     aul_comp_info_h* clone) {
174   if (handle == nullptr || clone == nullptr) {
175     _E("Invalid parameter");
176     return AUL_R_EINVAL;
177   }
178
179   auto* info = static_cast<ComponentInfo*>(handle);
180   auto* cloned_info = new (std::nothrow) ComponentInfo(*info);
181   if (cloned_info == nullptr) {
182     _E("Out of memory");
183     return AUL_R_ENOMEM;
184   }
185
186   *clone = static_cast<aul_comp_info_h>(cloned_info);
187   return AUL_R_OK;
188 }
189
190 extern "C" API int aul_comp_info_get_app_id(aul_comp_info_h handle,
191     const char** app_id) {
192   if (handle == nullptr || app_id == nullptr) {
193     _E("Invalid parameter");
194     return AUL_R_EINVAL;
195   }
196
197   auto* info = static_cast<ComponentInfo*>(handle);
198   *app_id = info->GetAppId().c_str();
199   return AUL_R_OK;
200 }
201
202 extern "C" API int aul_comp_info_get_comp_id(aul_comp_info_h handle,
203     const char** comp_id) {
204   if (handle == nullptr || comp_id == nullptr) {
205     _E("Invalid parameter");
206     return AUL_R_EINVAL;
207   }
208
209   auto* info = static_cast<ComponentInfo*>(handle);
210   *comp_id = info->GetComponentId().c_str();
211   return AUL_R_OK;
212 }
213
214 extern "C" API int aul_comp_info_get_type(aul_comp_info_h handle,
215     const char** type) {
216   if (handle == nullptr || type == nullptr) {
217     _E("Invalid parameter");
218     return AUL_R_EINVAL;
219   }
220
221   auto* info = static_cast<ComponentInfo*>(handle);
222   *type = info->GetType().c_str();
223   return AUL_R_OK;
224 }
225
226 extern "C" API int aul_comp_info_get_launch_mode(aul_comp_info_h handle,
227     const char** launch_mode) {
228   if (handle == nullptr || launch_mode == nullptr) {
229     _E("Invalid parameter");
230     return AUL_R_EINVAL;
231   }
232
233   auto* info = static_cast<ComponentInfo*>(handle);
234   *launch_mode = info->GetLaunchMode().c_str();
235   return AUL_R_OK;
236 }
237
238 extern "C" API int aul_comp_info_is_main_comp(aul_comp_info_h handle,
239     bool* main_comp) {
240   if (handle == nullptr || main_comp == nullptr) {
241     _E("Invalid parameter");
242     return AUL_R_EINVAL;
243   }
244
245   auto* info = static_cast<ComponentInfo*>(handle);
246   *main_comp = info->IsMainComponent();
247   return AUL_R_OK;
248 }
249
250 extern "C" API int aul_comp_info_is_icon_display(aul_comp_info_h handle,
251     bool* icon_display) {
252   if (handle == nullptr || icon_display == nullptr) {
253     _E("Invalid parameter");
254     return AUL_R_EINVAL;
255   }
256
257   auto* info = static_cast<ComponentInfo*>(handle);
258   *icon_display = info->IsIconDisplay();
259   return AUL_R_OK;
260 }
261
262 extern "C" API int aul_comp_info_is_taskmanage(aul_comp_info_h handle,
263     bool* taskmanage) {
264   if (handle == nullptr || taskmanage == nullptr) {
265     _E("Invalid parameter");
266     return AUL_R_EINVAL;
267   }
268
269   auto* info = static_cast<ComponentInfo*>(handle);
270   *taskmanage = info->IsTaskmanage();
271   return AUL_R_OK;
272 }
273
274 extern "C" API int aul_comp_info_get_icon(aul_comp_info_h handle,
275     const char** icon) {
276   if (handle == nullptr || icon == nullptr) {
277     _E("Invalid parameter");
278     return AUL_R_EINVAL;
279   }
280
281   auto* info = static_cast<ComponentInfo*>(handle);
282   try {
283     auto* localized_info = info->GetLocalizedInfo(GetSystemLocale());
284     if (localized_info == nullptr) {
285       localized_info = info->GetLocalizedInfo(kDefaultLocale);
286       if (localized_info == nullptr)
287         return AUL_R_ENOENT;
288     }
289
290     *icon = localized_info->GetIcon().c_str();
291   } catch (const Exception& e) {
292     _E("Exception occurs. error(%s)", e.what());
293     return e.GetErrorCode();
294   }
295
296   return AUL_R_OK;
297 }
298
299 extern "C" API int aul_comp_info_get_label(aul_comp_info_h handle,
300     const char** label) {
301   if (handle == nullptr || label == nullptr) {
302     _E("Invalid parameter");
303     return AUL_R_EINVAL;
304   }
305
306   auto* info = static_cast<ComponentInfo*>(handle);
307   try {
308     auto* localized_info = info->GetLocalizedInfo(GetSystemLocale());
309     if (localized_info == nullptr) {
310       localized_info = info->GetLocalizedInfo(kDefaultLocale);
311       if (localized_info == nullptr)
312         return AUL_R_ENOENT;
313     }
314
315     *label = localized_info->GetLabel().c_str();
316   } catch (const Exception& e) {
317     _E("Exception occurs. error(%s)", e.what());
318     return e.GetErrorCode();
319   }
320
321   return AUL_R_OK;
322 }
323
324 extern "C" API int aul_comp_info_get_localed_label(aul_comp_info_h handle,
325     const char* locale, const char** label) {
326   if (handle == nullptr || locale == nullptr || label == nullptr) {
327     _E("Invalid parameter");
328     return AUL_R_EINVAL;
329   }
330
331   auto* info = static_cast<ComponentInfo*>(handle);
332   auto* localized_info = info->GetLocalizedInfo(locale);
333   if (localized_info == nullptr) {
334     localized_info = info->GetLocalizedInfo(kDefaultLocale);
335     if (localized_info == nullptr)
336       return AUL_R_ENOENT;
337   }
338
339   *label = localized_info->GetLabel().c_str();
340   return AUL_R_OK;
341 }
342
343 extern "C" API int aul_comp_info_foreach_comp_info_from_app(const char* app_id,
344     aul_comp_info_cb callback, void* user_data) {
345   return aul_comp_info_usr_foreach_comp_info_from_app(app_id, getuid(),
346       callback, user_data);
347 }
348
349 extern "C" API int aul_comp_info_usr_foreach_comp_info_from_app(
350     const char* app_id, uid_t uid, aul_comp_info_cb callback, void* user_data) {
351   if (app_id == nullptr || callback == nullptr) {
352     _E("Invalid parameter");
353     return AUL_R_EINVAL;
354   }
355
356   try {
357     for (auto const& info : GetComponentInfos(uid)) {
358       if (info->GetAppId().compare(app_id) != 0)
359         continue;
360
361       if (!callback(info.get(), user_data))
362         break;
363     }
364   } catch (const Exception& e) {
365     _E("Exception occurs. error(%s)", e.what());
366     return e.GetErrorCode();
367   }
368
369   return AUL_R_OK;
370 }
371
372 extern "C" API int aul_comp_info_foreach_comp_info(aul_comp_info_cb callback,
373     void* user_data) {
374   return aul_comp_info_usr_foreach_comp_info(getuid(), callback, user_data);
375 }
376
377 extern "C" API int aul_comp_info_usr_foreach_comp_info(uid_t uid,
378     aul_comp_info_cb callback, void* user_data) {
379   if (callback == nullptr) {
380     _E("Invalid parameter");
381     return AUL_R_EINVAL;
382   }
383
384   try {
385     for (auto const& info : GetComponentInfos(uid)) {
386       if (!callback(info.get(), user_data))
387         break;
388     }
389   } catch (const Exception& e) {
390     _E("Exception occurs. error(%s)", e.what());
391     return e.GetErrorCode();
392   }
393
394   return AUL_R_OK;
395 }