1 // Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
7 #include <bundle_internal.h>
16 #include "include/capability_manager.h"
18 #include "src/sql_connection.h"
19 #include "src/sql_statement.h"
20 #include "src/sqlite_connection.h"
21 #include "src/utils/logging.h"
23 #define API __attribute__((visibility("default")))
27 const char kDBPath[] = "/run/capmgr/capmgr.db";
31 struct capmgr_device_s {
32 std::string device_id;
33 std::string model_name;
34 std::string device_name;
35 std::string platform_ver;
40 struct capmgr_app_control_s {
41 capmgr_device_h device;
45 struct capmgr_application_info_s {
50 capmgr_device_h device;
53 API int capmgr_device_foreach_devices(capmgr_device_foreach_cb cb,
56 return CAPMGR_ERROR_INVALID_PARAMETER;
58 std::unique_ptr<capmgr::SQLConnection> sql_conn(
59 new capmgr::SQLiteConnection(kDBPath, true));
61 const char kQueryForeachDevices[] =
62 "SELECT device_id, model_name, device_name, platform_ver,"
65 std::shared_ptr<capmgr::SQLStatement> stmt = sql_conn->PrepareStatement(
66 kQueryForeachDevices);
68 return CAPMGR_ERROR_IO_ERROR;
70 while (stmt->Step() == capmgr::SQLStatement::StepResult::ROW) {
71 struct capmgr_device_s dev;
73 dev.device_id = stmt->GetColumnString(idx++);
74 dev.model_name = stmt->GetColumnString(idx++);
75 dev.device_name = stmt->GetColumnString(idx++);
76 dev.platform_ver = stmt->GetColumnString(idx++);
77 dev.profile = stmt->GetColumnString(idx++);
78 dev.sw_ver = stmt->GetColumnString(idx++);
79 if (cb(&dev, user_data))
83 return CAPMGR_ERROR_NONE;
86 API int capmgr_device_clone(const capmgr_device_h device,
87 capmgr_device_h* device_clone) {
88 if (!device || !device_clone)
89 return CAPMGR_ERROR_INVALID_PARAMETER;
92 struct capmgr_device_s* clone = new struct capmgr_device_s();
94 clone->device_id = device->device_id;
95 clone->model_name = device->model_name;
96 clone->device_name = device->device_name;
97 clone->platform_ver = device->platform_ver;
98 clone->profile = device->profile;
99 clone->sw_ver = device->sw_ver;
101 *device_clone = clone;
102 } catch (const std::bad_alloc& e) {
103 LOG(ERROR) << e.what();
104 return CAPMGR_ERROR_OUT_OF_MEMORY;
107 return CAPMGR_ERROR_NONE;
110 API int capmgr_device_destroy(capmgr_device_h device) {
112 return CAPMGR_ERROR_INVALID_PARAMETER;
116 return CAPMGR_ERROR_NONE;
119 API int capmgr_device_get_device_id(capmgr_device_h device,
121 if (!device || !device_id)
122 return CAPMGR_ERROR_INVALID_PARAMETER;
124 *device_id = strdup(device->device_id.c_str());
125 if (*device_id == nullptr)
126 return CAPMGR_ERROR_OUT_OF_MEMORY;
128 return CAPMGR_ERROR_NONE;
131 API int capmgr_device_get_model_name(capmgr_device_h device,
133 if (!device || !model_name)
134 return CAPMGR_ERROR_INVALID_PARAMETER;
136 *model_name = strdup(device->model_name.c_str());
137 if (*model_name == nullptr)
138 return CAPMGR_ERROR_OUT_OF_MEMORY;
140 return CAPMGR_ERROR_NONE;
143 API int capmgr_device_get_device_name(capmgr_device_h device,
144 char** device_name) {
145 if (!device || !device_name)
146 return CAPMGR_ERROR_INVALID_PARAMETER;
148 *device_name = strdup(device->device_name.c_str());
149 if (*device_name == nullptr)
150 return CAPMGR_ERROR_OUT_OF_MEMORY;
152 return CAPMGR_ERROR_NONE;
155 API int capmgr_device_get_platform_ver(capmgr_device_h device,
156 char** platform_ver) {
157 if (!device || !platform_ver)
158 return CAPMGR_ERROR_INVALID_PARAMETER;
160 *platform_ver = strdup(device->platform_ver.c_str());
161 if (*platform_ver == nullptr)
162 return CAPMGR_ERROR_OUT_OF_MEMORY;
164 return CAPMGR_ERROR_NONE;
167 API int capmgr_device_get_profile(capmgr_device_h device, char** profile) {
168 if (!device || !profile)
169 return CAPMGR_ERROR_INVALID_PARAMETER;
171 *profile = strdup(device->profile.c_str());
172 if (*profile == nullptr)
173 return CAPMGR_ERROR_OUT_OF_MEMORY;
175 return CAPMGR_ERROR_NONE;
178 API int capmgr_device_get_sw_ver(capmgr_device_h device,
180 if (!device || !sw_ver)
181 return CAPMGR_ERROR_INVALID_PARAMETER;
183 *sw_ver = strdup(device->sw_ver.c_str());
184 if (*sw_ver == nullptr)
185 return CAPMGR_ERROR_OUT_OF_MEMORY;
187 return CAPMGR_ERROR_NONE;
190 API int capmgr_app_control_create(capmgr_app_control_h* app_control) {
192 return CAPMGR_ERROR_INVALID_PARAMETER;
195 struct capmgr_app_control_s* control = new struct capmgr_app_control_s();
196 control->b = bundle_create();
199 return CAPMGR_ERROR_OUT_OF_MEMORY;
201 int r = aul_svc_set_operation(control->b, AUL_SVC_OPERATION_DEFAULT);
202 if (r != AUL_SVC_RET_OK) {
203 bundle_free(control->b);
205 return CAPMGR_ERROR_OUT_OF_MEMORY;
207 *app_control = control;
208 } catch (const std::bad_alloc& e) {
209 LOG(ERROR) << e.what();
210 return CAPMGR_ERROR_OUT_OF_MEMORY;
213 return CAPMGR_ERROR_NONE;
216 API int capmgr_app_control_clone(const capmgr_app_control_h app_control,
217 capmgr_app_control_h* app_control_clone) {
218 if (!app_control || !app_control_clone)
219 return CAPMGR_ERROR_INVALID_PARAMETER;
222 struct capmgr_app_control_s* clone = new struct capmgr_app_control_s();
224 int ret = capmgr_device_clone(app_control->device, &clone->device);
225 if (ret != CAPMGR_ERROR_NONE) {
227 return CAPMGR_ERROR_OUT_OF_MEMORY;
230 clone->b = bundle_dup(app_control->b);
232 capmgr_app_control_destroy(clone);
233 return CAPMGR_ERROR_OUT_OF_MEMORY;
236 *app_control_clone = clone;
237 } catch (const std::bad_alloc& e) {
238 LOG(ERROR) << e.what();
239 return CAPMGR_ERROR_OUT_OF_MEMORY;
242 return CAPMGR_ERROR_NONE;
245 API int capmgr_app_control_destroy(capmgr_app_control_h app_control) {
247 return CAPMGR_ERROR_INVALID_PARAMETER;
249 capmgr_device_destroy(app_control->device);
250 bundle_free(app_control->b);
253 return CAPMGR_ERROR_NONE;
256 API int capmgr_app_control_get_device(capmgr_app_control_h app_control,
257 capmgr_device_h* device) {
258 if (!app_control || !device)
259 return CAPMGR_ERROR_INVALID_PARAMETER;
261 int ret = capmgr_device_clone(app_control->device, device);
262 if (ret != CAPMGR_ERROR_NONE)
265 return CAPMGR_ERROR_NONE;
268 API int capmgr_app_control_get_operation(capmgr_app_control_h app_control,
270 if (!app_control || !operation)
271 return CAPMGR_ERROR_INVALID_PARAMETER;
273 const char* val = aul_svc_get_operation(app_control->b);
275 return CAPMGR_ERROR_INVALID_PARAMETER;
277 *operation = strdup(val);
278 if (*operation == nullptr)
279 return CAPMGR_ERROR_OUT_OF_MEMORY;
281 return CAPMGR_ERROR_NONE;
284 API int capmgr_app_control_get_uri(capmgr_app_control_h app_control,
286 if (!app_control || !uri)
287 return CAPMGR_ERROR_INVALID_PARAMETER;
289 const char* val = aul_svc_get_uri(app_control->b);
291 return CAPMGR_ERROR_INVALID_PARAMETER;
295 return CAPMGR_ERROR_OUT_OF_MEMORY;
297 return CAPMGR_ERROR_NONE;
300 API int capmgr_app_control_get_mime(capmgr_app_control_h app_control,
302 if (!app_control || !mime)
303 return CAPMGR_ERROR_INVALID_PARAMETER;
305 const char* val = aul_svc_get_mime(app_control->b);
307 return CAPMGR_ERROR_INVALID_PARAMETER;
310 if (*mime == nullptr)
311 return CAPMGR_ERROR_OUT_OF_MEMORY;
313 return CAPMGR_ERROR_NONE;
316 API int capmgr_app_control_get_appid(capmgr_app_control_h app_control,
318 if (!app_control || !appid)
319 return CAPMGR_ERROR_INVALID_PARAMETER;
321 const char* val = aul_svc_get_appid(app_control->b);
323 return CAPMGR_ERROR_INVALID_PARAMETER;
325 *appid = strdup(val);
326 if (*appid == nullptr)
327 return CAPMGR_ERROR_OUT_OF_MEMORY;
329 return CAPMGR_ERROR_NONE;
332 API int capmgr_app_control_get_extra_data(capmgr_app_control_h app_control,
333 const char* key, char** value) {
334 if (!app_control || !key || !value)
335 return CAPMGR_ERROR_INVALID_PARAMETER;
337 // TODO(jeremy.jang): handle reserved key
339 const char* val = aul_svc_get_data(app_control->b, key);
341 LOG(ERROR) << "There is no extra data of key(" << key << ")";
342 return CAPMGR_ERROR_INVALID_PARAMETER;
345 *value = strdup(val);
346 if (*value == nullptr)
347 return CAPMGR_ERROR_OUT_OF_MEMORY;
349 return CAPMGR_ERROR_NONE;
352 API int capmgr_app_control_set_device(capmgr_app_control_h app_control,
353 const capmgr_device_h device) {
354 if (!app_control || !device)
355 return CAPMGR_ERROR_INVALID_PARAMETER;
357 if (app_control->device)
358 capmgr_device_destroy(app_control->device);
360 int ret = capmgr_device_clone(device, &app_control->device);
361 if (ret != CAPMGR_ERROR_NONE)
362 return CAPMGR_ERROR_OUT_OF_MEMORY;
364 return CAPMGR_ERROR_NONE;
367 API int capmgr_app_control_set_operation(capmgr_app_control_h app_control,
368 const char* operation) {
369 if (!app_control || !operation)
370 return CAPMGR_ERROR_INVALID_PARAMETER;
372 int r = aul_svc_set_operation(app_control->b, operation);
373 if (r != AUL_SVC_RET_OK)
374 return CAPMGR_ERROR_OUT_OF_MEMORY;
376 return CAPMGR_ERROR_NONE;
379 API int capmgr_app_control_set_uri(capmgr_app_control_h app_control,
381 if (!app_control || !uri)
382 return CAPMGR_ERROR_INVALID_PARAMETER;
384 int r = aul_svc_set_uri(app_control->b, uri);
385 if (r != AUL_SVC_RET_OK)
386 return CAPMGR_ERROR_OUT_OF_MEMORY;
388 return CAPMGR_ERROR_NONE;
391 API int capmgr_app_control_set_mime(capmgr_app_control_h app_control,
393 if (!app_control || !mime)
394 return CAPMGR_ERROR_INVALID_PARAMETER;
396 int r = aul_svc_set_mime(app_control->b, mime);
397 if (r != AUL_SVC_RET_OK)
398 return CAPMGR_ERROR_OUT_OF_MEMORY;
400 return CAPMGR_ERROR_NONE;
403 API int capmgr_app_control_set_appid(capmgr_app_control_h app_control,
405 if (!app_control || !appid)
406 return CAPMGR_ERROR_INVALID_PARAMETER;
408 int r = aul_svc_set_appid(app_control->b, appid);
409 if (r != AUL_SVC_RET_OK)
410 return CAPMGR_ERROR_OUT_OF_MEMORY;
412 return CAPMGR_ERROR_NONE;
415 API int capmgr_app_control_add_extra_data(capmgr_app_control_h app_control,
416 const char* key, const char* value) {
417 if (!app_control || !key || !value)
418 return CAPMGR_ERROR_INVALID_PARAMETER;
420 // TODO(jeremy.jang): handle reserved key
422 int r = aul_svc_add_data(app_control->b, key, value);
423 if (r != AUL_SVC_RET_OK)
424 return CAPMGR_ERROR_OUT_OF_MEMORY;
426 return CAPMGR_ERROR_NONE;
429 API int capmgr_app_control_remove_extra_data(capmgr_app_control_h app_control,
431 if (!app_control || !key)
432 return CAPMGR_ERROR_INVALID_PARAMETER;
434 // TODO(jeremy.jang): handle reserved key
436 int r = bundle_del(app_control->b, key);
437 if (r != BUNDLE_ERROR_NONE)
438 return CAPMGR_ERROR_INVALID_PARAMETER;
440 return CAPMGR_ERROR_NONE;
444 capmgr_app_control_h request;
445 capmgr_app_control_reply_cb cb;
449 void capmgr_dbus_callback(GVariant* result, void* user_data) {
450 LOG(DEBUG) << "Dbus callback for client called";
452 // TODO(jeremy.jang): some data maybe returned
456 g_variant_get(result, "(ayu)", &iter, &len);
458 LOG(ERROR) << "Some error occurred";
460 data = reinterpret_cast<guchar*>(g_try_malloc(len));
462 LOG(ERROR) << "Out of memory";
466 for (unsigned int i = 0; i < len; i++) {
467 if (!g_variant_iter_loop(iter, "y", &data[i])) {
468 LOG(ERROR) << "Failed to get data from GVariant!";
472 g_variant_iter_free(iter);
474 struct cbdata* cbdata = reinterpret_cast<struct cbdata*>(user_data);
475 struct capmgr_app_control_s* reply = new struct capmgr_app_control_s();
476 reply->b = bundle_decode(data, len);
478 LOG(ERROR) << "Invalid bundle data!";
479 capmgr_app_control_destroy(cbdata->request);
483 reply->device = cbdata->request->device;
485 // TODO(jeremy.jang): need to receive aul_svc result code
486 cbdata->cb(cbdata->request, reply, CAPMGR_APP_CONTROL_RESULT_OK,
489 capmgr_app_control_destroy(cbdata->request);
493 API int capmgr_app_control_send(capmgr_app_control_h app_control,
494 capmgr_app_control_reply_cb cb, void* user_data) {
495 if (!app_control || !app_control->device || !cb)
496 return CAPMGR_ERROR_INVALID_PARAMETER;
500 int r = bundle_encode(app_control->b, &raw, &len);
501 if (r != BUNDLE_ERROR_NONE) {
502 LOG(ERROR) << "Failed to encode bundle: " << r;
503 return CAPMGR_ERROR_INVALID_PARAMETER;
507 GVariantBuilder* array_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
508 for (int i = 0; i < len; i++)
509 g_variant_builder_add(array_builder, "y", raw[i]);
510 GVariant* gv = g_variant_new("(sayu)",
511 app_control->device->device_id.c_str(), array_builder, len);
512 g_variant_builder_unref(array_builder);
513 bundle_free_encoded_rawdata(&raw);
515 LOG(ERROR) << "Failed to create GVariant";
516 return CAPMGR_ERROR_INVALID_PARAMETER;
518 g_variant_ref_sink(gv);
520 capmgr_app_control_h clone;
521 r = capmgr_app_control_clone(app_control, &clone);
522 if (r != CAPMGR_ERROR_NONE) {
523 LOG(ERROR) << "Failed to clone app control request: " << r;
527 struct cbdata* cbdata = new struct cbdata();
528 cbdata->request = clone;
530 cbdata->user_data = user_data;
532 if (!capmgr::ProxyCallAsync("SendRemoteAppControl", gv, capmgr_dbus_callback,
534 LOG(ERROR) << "Failed to dbus method call";
536 capmgr_app_control_destroy(clone);
539 return CAPMGR_ERROR_INVALID_PARAMETER;
544 return CAPMGR_ERROR_NONE;
547 API int capmgr_application_info_clone(
548 const capmgr_application_info_h remote_app_info,
549 capmgr_application_info_h* remote_app_info_clone) {
550 if (!remote_app_info || !remote_app_info_clone)
551 return CAPMGR_ERROR_INVALID_PARAMETER;
553 struct capmgr_application_info_s* clone;
555 clone = new struct capmgr_application_info_s();
556 } catch (const std::bad_alloc& e) {
557 LOG(ERROR) << e.what();
558 return CAPMGR_ERROR_OUT_OF_MEMORY;
561 clone->appid = remote_app_info->appid;
562 clone->pkgid = remote_app_info->pkgid;
563 clone->label = remote_app_info->label;
564 clone->version = remote_app_info->version;
566 int ret = capmgr_device_clone(remote_app_info->device, &(clone->device));
567 if (ret != CAPMGR_ERROR_NONE) {
568 LOG(ERROR) << "Failed to clone capmgr device";
573 *remote_app_info_clone = clone;
575 return CAPMGR_ERROR_NONE;
578 API int capmgr_application_info_destroy(
579 capmgr_application_info_h remote_app_info) {
580 if (!remote_app_info)
581 return CAPMGR_ERROR_INVALID_PARAMETER;
583 capmgr_device_destroy(remote_app_info->device);
584 delete remote_app_info;
586 return CAPMGR_ERROR_NONE;
589 API int capmgr_application_info_get_appid(
590 capmgr_application_info_h remote_app_info, char** appid) {
591 if (!remote_app_info || !appid || remote_app_info->appid.empty())
592 return CAPMGR_ERROR_INVALID_PARAMETER;
594 *appid = strdup(remote_app_info->appid.c_str());
595 if (*appid == nullptr)
596 return CAPMGR_ERROR_OUT_OF_MEMORY;
598 return CAPMGR_ERROR_NONE;
601 API int capmgr_application_info_get_pkgid(
602 capmgr_application_info_h remote_app_info, char** pkgid) {
603 if (!remote_app_info || !pkgid || remote_app_info->pkgid.empty())
604 return CAPMGR_ERROR_INVALID_PARAMETER;
606 *pkgid = strdup(remote_app_info->pkgid.c_str());
607 if (*pkgid == nullptr)
608 return CAPMGR_ERROR_OUT_OF_MEMORY;
610 return CAPMGR_ERROR_NONE;
613 API int capmgr_application_info_get_label(
614 capmgr_application_info_h remote_app_info, char** label) {
615 if (!remote_app_info || !label || remote_app_info->label.empty())
616 return CAPMGR_ERROR_INVALID_PARAMETER;
618 *label = strdup(remote_app_info->label.c_str());
619 if (*label == nullptr)
620 return CAPMGR_ERROR_OUT_OF_MEMORY;
622 return CAPMGR_ERROR_NONE;
625 API int capmgr_application_info_get_version(
626 capmgr_application_info_h remote_app_info, char** version) {
627 if (!remote_app_info || !version || remote_app_info->version.empty())
628 return CAPMGR_ERROR_INVALID_PARAMETER;
630 *version = strdup(remote_app_info->version.c_str());
631 if (*version == nullptr)
632 return CAPMGR_ERROR_OUT_OF_MEMORY;
634 return CAPMGR_ERROR_NONE;
637 API int capmgr_application_info_get_device(
638 capmgr_application_info_h remote_app_info,
639 capmgr_device_h* device) {
640 if (!remote_app_info || !device)
641 return CAPMGR_ERROR_INVALID_PARAMETER;
643 int ret = capmgr_device_clone(remote_app_info->device, device);
644 if (ret != CAPMGR_ERROR_NONE)
647 return CAPMGR_ERROR_NONE;
650 API int capmgr_application_info_foreach_applications(
651 const capmgr_device_h device,
652 capmgr_application_info_foreach_app_cb cb,
655 return CAPMGR_ERROR_INVALID_PARAMETER;
657 std::unique_ptr<capmgr::SQLConnection> sql_conn(
658 new capmgr::SQLiteConnection(kDBPath, true));
660 const char kQueryForeachPackages[] =
661 "SELECT appid, pkgid, label, version FROM remote_app_info WHERE "
664 std::shared_ptr<capmgr::SQLStatement> stmt = sql_conn->PrepareStatement(
665 kQueryForeachPackages);
667 return CAPMGR_ERROR_IO_ERROR;
669 if (stmt->BindString(1, device->device_id)) {
670 while (stmt->Step() == capmgr::SQLStatement::StepResult::ROW) {
671 struct capmgr_application_info_s info;
673 info.appid = stmt->GetColumnString(idx++);
674 info.pkgid = stmt->GetColumnString(idx++);
675 info.label = stmt->GetColumnString(idx++);
676 info.version = stmt->GetColumnString(idx++);
677 info.device = device;
678 if (cb(&info, user_data))
683 return CAPMGR_ERROR_NONE;