Move function definition to aul header
[platform/core/appfw/aul-1.git] / src / aul_comp_context.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_context.h"
18
19 #include <bundle_cpp.h>
20
21 #include <memory>
22 #include <string>
23 #include <vector>
24
25 #include "app_request.h"
26 #include "aul_api.h"
27 #include "aul_util.h"
28 #include "include/aul.h"
29 #include "include/aul_error.h"
30
31 #include "aul/common/exception.hh"
32 #include "aul/component/component_running_context.hh"
33
34 using namespace aul;
35
36 struct aul_comp_context_s {
37   void* dummy;
38 };
39
40 namespace {
41 using namespace aul::internal;
42
43 ComponentRunningContext* CreateComponentRunningContext(
44     const tizen_base::Bundle& b) {
45   return ComponentRunningContext::Builder()
46       .SetComponentId(b)
47       .SetInstanceId(b)
48       .SetAppId(b)
49       .SetType(b)
50       .SetPid(b)
51       .SetStatus(b)
52       .SetSubComponent(b);
53 }
54
55 ComponentRunningContext* GetComponentRunningContext(
56     const std::string& component_id, uid_t uid) {
57   tizen_base::Bundle b { { AUL_K_COMPONENT_ID, component_id } };
58   int fd = AppRequest(COMP_CONTEXT_GET, uid)
59       .With(std::move(b))
60       .SendSimply(AUL_SOCK_ASYNC);
61   if (fd < 0)
62     THROW(fd);
63
64   app_pkt_t* pkt;
65   int ret = aul_sock_recv_reply_pkt(fd, &pkt);
66   if (ret < 0)
67     THROW(aul_error_convert(fd));
68
69   auto pkt_auto = std::unique_ptr<app_pkt_t, decltype(std::free)*>(
70       pkt, std::free);
71
72   if (pkt->cmd != APP_GET_INFO_OK) {
73     _E("Failed to get component running context. error(%d)", pkt->cmd);
74     THROW(pkt->cmd);
75   }
76
77   bundle* kb = nullptr;
78   if (pkt->opt & AUL_SOCK_BUNDLE) {
79     kb = bundle_decode(pkt->data, pkt->len);
80     if (kb == nullptr)
81       THROW(AUL_R_ENOMEM);
82   } else {
83     _E("Wrong packet");
84     THROW(AUL_R_ERROR);
85   }
86
87   return CreateComponentRunningContext(tizen_base::Bundle(kb, false, true));
88 }
89
90 std::vector<std::unique_ptr<ComponentRunningContext>>
91 GetComponentRunningContexts() {
92   int fd = AppRequest(COMP_CONTEXT_FOREACH, getuid())
93       .SendSimply(AUL_SOCK_ASYNC);
94   if (fd < 0)
95     THROW(fd);
96
97   std::vector<std::unique_ptr<ComponentRunningContext>> contexts;
98   int ret = aul_sock_recv_pkt_with_cb(fd,
99       [](app_pkt_t* pkt, void* user_data) {
100         if (pkt == nullptr) {
101           _E("pkt is nullptr");
102           return;
103         }
104
105         if (pkt->cmd == APP_GET_INFO_ERROR) {
106           _E("Failed to get component running context");
107           return;
108         }
109
110         bundle* kb = nullptr;
111         if (pkt->opt & AUL_SOCK_BUNDLE)
112           kb = bundle_decode(pkt->data, pkt->len);
113
114         if (kb == nullptr)
115           return;
116
117         tizen_base::Bundle b(kb, false, true);
118         auto* context_array =
119             static_cast<std::vector<std::unique_ptr<ComponentRunningContext>>*>(
120                 user_data);
121
122         try {
123           context_array->emplace_back(CreateComponentRunningContext(b));
124         } catch (const Exception& e) {
125           _E("Exception occurs. error(%s)", e.what());
126         }
127       }, &contexts);
128   if (ret < 0)
129     THROW(aul_error_convert(ret));
130
131   return contexts;
132 }
133
134 int SendRequest(ComponentRunningContext* context, int cmd) {
135   tizen_base::Bundle b {
136     { AUL_K_COMPONENT_ID, context->GetComponentId() },
137     { AUL_K_INSTANCE_ID, context->GetInstanceId() }
138   };
139
140   int ret = AppRequest(cmd, getuid())
141       .With(std::move(b))
142       .SendSimply();
143   if (ret < 0)
144     THROW(ret);
145
146   return ret;
147 }
148
149 }  // namespace
150
151 extern "C" API int aul_comp_context_foreach_comp_context(
152     aul_comp_context_cb callback, void* user_data) {
153   if (callback == nullptr) {
154     _E("Invalid parameter");
155     return AUL_R_EINVAL;
156   }
157
158   try {
159     for (auto const& context : GetComponentRunningContexts()) {
160       auto* handle = reinterpret_cast<aul_comp_context_h>(context.get());
161       if (!callback(handle, user_data))
162         break;
163     }
164   } catch (const Exception& e) {
165     _E("Exception occurs. error(%d)", e.GetErrorCode());
166     return e.GetErrorCode();
167   }
168
169   return AUL_R_OK;
170 }
171
172 extern "C" API int aul_comp_context_get_comp_id(aul_comp_context_h handle,
173     const char** comp_id) {
174   if (handle == nullptr || comp_id == nullptr) {
175     _E("Invalid parameter");
176     return AUL_R_EINVAL;
177   }
178
179   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
180   *comp_id = context->GetComponentId().c_str();
181   return AUL_R_OK;
182 }
183
184 extern "C" API int aul_comp_context_get_instance_id(aul_comp_context_h handle,
185     const char** instance_id) {
186   if (handle == nullptr || instance_id == nullptr) {
187     _E("Invalid parameter");
188     return AUL_R_EINVAL;
189   }
190
191   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
192   *instance_id = context->GetInstanceId().c_str();
193   return AUL_R_OK;
194 }
195
196 extern "C" API int aul_comp_context_get_app_id(aul_comp_context_h handle,
197     const char** app_id) {
198   if (handle == nullptr || app_id == nullptr) {
199     _E("Invalid parameter");
200     return AUL_R_EINVAL;
201   }
202
203   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
204   *app_id = context->GetAppId().c_str();
205   return AUL_R_OK;
206 }
207
208 extern "C" API int aul_comp_context_get_type(aul_comp_context_h handle,
209     const char** type) {
210   if (handle == nullptr || type == nullptr) {
211     _E("Invalid parameter");
212     return AUL_R_EINVAL;
213   }
214
215   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
216   *type = context->GetType().c_str();
217   return AUL_R_OK;
218 }
219
220 extern "C" API int aul_comp_context_get_pid(aul_comp_context_h handle,
221     pid_t* pid) {
222   if (handle == nullptr || pid == nullptr) {
223     _E("Invalid parameter");
224     return AUL_R_EINVAL;
225   }
226
227   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
228   *pid = context->GetPid();
229   return AUL_R_OK;
230 }
231
232 extern "C" API int aul_comp_context_get_status(aul_comp_context_h handle,
233     int* status) {
234   if (handle == nullptr || status == nullptr) {
235     _E("Invalid parameter");
236     return AUL_R_EINVAL;
237   }
238
239   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
240   *status = context->GetStatus();
241   return AUL_R_OK;
242 }
243
244 extern "C" API int aul_comp_context_is_sub_comp(aul_comp_context_h handle,
245     bool* is_sub_comp) {
246   if (handle == nullptr || is_sub_comp == nullptr) {
247     _E("Invalid parameter");
248     return AUL_R_EINVAL;
249   }
250
251   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
252   *is_sub_comp = context->IsSubComponent();
253   return AUL_R_OK;
254 }
255
256 extern "C" API int aul_comp_context_create(const char* comp_id,
257     aul_comp_context_h* handle) {
258   return aul_comp_context_usr_create(comp_id, getuid(), handle);
259 }
260
261 extern "C" API int aul_comp_context_usr_create(const char* comp_id,
262     uid_t uid, aul_comp_context_h* handle) {
263   if (comp_id == nullptr || handle == nullptr) {
264     _E("Invalid parameter");
265     return AUL_R_EINVAL;
266   }
267
268   try {
269     auto* context = GetComponentRunningContext(comp_id, uid);
270     if (context == nullptr)
271       return AUL_R_ENOMEM;
272
273     *handle = reinterpret_cast<aul_comp_context_h>(context);
274   } catch (const Exception& e) {
275     _E("Exception occurs. error(%d)", e.GetErrorCode());
276     return e.GetErrorCode();
277   }
278
279   return AUL_R_OK;
280 }
281
282 extern "C" API int aul_comp_context_destroy(aul_comp_context_h handle) {
283   if (handle == nullptr) {
284     _E("Invalid parameter");
285     return AUL_R_EINVAL;
286   }
287
288   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
289   delete context;
290   return AUL_R_OK;
291 }
292
293 extern "C" API int aul_comp_context_clone(aul_comp_context_h handle,
294     aul_comp_context_h* clone) {
295   if (handle == nullptr || clone == nullptr) {
296     _E("Invalid parameter");
297     return AUL_R_EINVAL;
298   }
299
300   auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
301   auto* cloned_context = new (std::nothrow) ComponentRunningContext(*context);
302   if (cloned_context == nullptr) {
303     _E("Out of memory");
304     return AUL_R_ENOMEM;
305   }
306
307   *clone = reinterpret_cast<aul_comp_context_h>(cloned_context);
308   return AUL_R_OK;
309 }
310
311 extern "C" API int aul_comp_context_is_running(aul_comp_context_h handle,
312     bool* running) {
313   if (handle == nullptr || running == nullptr) {
314     _E("Invalid parameter");
315     return AUL_R_EINVAL;
316   }
317
318   try {
319     auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
320     int ret = SendRequest(context, COMP_CONTEXT_IS_RUNNING);
321     *running = (ret == 0) ? false : true;
322   } catch (const Exception& e) {
323     _E("Exception occurs. error(%d)", e.GetErrorCode());
324     return e.GetErrorCode();
325   }
326
327   return AUL_R_OK;
328 }
329
330 extern "C" int aul_comp_context_resume(aul_comp_context_h handle) {
331   if (handle == nullptr) {
332     _E("Invalid parameter");
333     return AUL_R_EINVAL;
334   }
335
336   try {
337     auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
338     SendRequest(context, COMP_CONTEXT_RESUME);
339   } catch (const Exception& e) {
340     _E("Exception occurs. error(%d)", e.GetErrorCode());
341     return e.GetErrorCode();
342   }
343
344   return AUL_R_OK;
345 }
346
347 extern "C" int aul_comp_context_pause(aul_comp_context_h handle) {
348   if (handle == nullptr) {
349     _E("Invalid parameter");
350     return AUL_R_EINVAL;
351   }
352
353   try {
354     auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
355     SendRequest(context, COMP_CONTEXT_PAUSE);
356   } catch (const Exception& e) {
357     _E("Exception occurs. error(%d)", e.GetErrorCode());
358     return e.GetErrorCode();
359   }
360
361   return AUL_R_OK;
362 }
363
364 extern "C" int aul_comp_context_terminate_bg_comp(aul_comp_context_h handle) {
365   if (handle == nullptr) {
366     _E("Invalid parameter");
367     return AUL_R_EINVAL;
368   }
369
370   try {
371     auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
372     SendRequest(context, COMP_CONTEXT_TERMINATE_BG_COMP);
373   } catch (const Exception& e) {
374     _E("Exception occurs. error(%d)", e.GetErrorCode());
375     return e.GetErrorCode();
376   }
377
378   return AUL_R_OK;
379 }
380
381 extern "C" int aul_comp_context_terminate(aul_comp_context_h handle) {
382   if (handle == nullptr) {
383     _E("Invalid parameter");
384     return AUL_R_EINVAL;
385   }
386
387   try {
388     auto* context = reinterpret_cast<ComponentRunningContext*>(handle);
389     SendRequest(context, COMP_CONTEXT_TERMINATE);
390   } catch (const Exception& e) {
391     _E("Exception occurs. error(%d)", e.GetErrorCode());
392     return e.GetErrorCode();
393   }
394
395   return AUL_R_OK;
396 }