2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "application_manager.h"
21 #include <type_traits>
23 #include <app_control_internal.h>
25 #include <app_manager_extension.h>
29 #include <bundle_internal.h>
30 #include <package_manager.h>
31 #include <pkgmgr-info.h>
32 #include <pkgmgr_installer.h>
34 #include "common/current_application.h"
35 #include "common/logger.h"
36 #include "common/platform_result.h"
37 #include "common/scope_exit.h"
38 #include "common/task-queue.h"
39 #include "common/tools.h"
41 #include "application/application_instance.h"
42 #include "application/application_utils.h"
44 using namespace common;
45 using namespace tools;
48 namespace application {
51 const std::string kTizenApisFileScheme = "file://";
52 const std::string kTizenApisAppSlash = "/";
53 const std::string kTizenApisAppShared = "shared";
55 const char* kStartKey = PKGMGR_INSTALLER_START_KEY_STR;
56 const char* kEndKey = PKGMGR_INSTALLER_END_KEY_STR;
57 const char* kOkValue = PKGMGR_INSTALLER_OK_EVENT_STR;
58 const char* kInstallEvent = PKGMGR_INSTALLER_INSTALL_EVENT_STR;
59 const char* kUpdateEvent = PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
60 const char* kUninstallEvent = PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
62 const char* kAppidKey = "appid";
64 const std::string kAction = "action";
65 const std::string kCallbackId = "callbackId";
66 const std::string kOnInstalled = "oninstalled";
67 const std::string kOnUpdated = "onupdated";
68 const std::string kOnUninstalled = "onuninstalled";
69 const std::string kData = "data";
70 const std::string kStatusType = "statusType";
71 const std::string kAppId = "appId";
72 const std::string kListenerId = "listenerId";
73 const std::string kAppStatusChangeListener = "AppStatusChangeListener";
74 const std::string kAppUsageModeFrequently = "FREQUENTLY";
75 const std::string kAppUsageModeRecently = "RECENTLY";
77 const std::map<std::string, std::string> event_map_ = {
78 {SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
79 {SYSTEM_EVENT_BATTERY_LEVEL_STATUS, EVENT_KEY_BATTERY_LEVEL_STATUS},
80 {SYSTEM_EVENT_USB_STATUS, EVENT_KEY_USB_STATUS},
81 {SYSTEM_EVENT_EARJACK_STATUS, EVENT_KEY_EARJACK_STATUS},
82 {SYSTEM_EVENT_DISPLAY_STATE, EVENT_KEY_DISPLAY_STATE},
83 {SYSTEM_EVENT_LOW_MEMORY, EVENT_KEY_LOW_MEMORY},
84 {SYSTEM_EVENT_WIFI_STATE, EVENT_KEY_WIFI_STATE},
85 {SYSTEM_EVENT_BT_STATE, EVENT_KEY_BT_STATE},
86 {SYSTEM_EVENT_LOCATION_ENABLE_STATE, EVENT_KEY_LOCATION_ENABLE_STATE},
87 {SYSTEM_EVENT_GPS_ENABLE_STATE, EVENT_KEY_GPS_ENABLE_STATE},
88 {SYSTEM_EVENT_NPS_ENABLE_STATE, EVENT_KEY_NPS_ENABLE_STATE},
89 {SYSTEM_EVENT_INCOMING_MSG, EVENT_KEY_MSG_TYPE},
90 {SYSTEM_EVENT_TIME_ZONE, EVENT_KEY_TIME_ZONE},
91 {SYSTEM_EVENT_HOUR_FORMAT, EVENT_KEY_HOUR_FORMAT},
92 {SYSTEM_EVENT_LANGUAGE_SET, EVENT_KEY_LANGUAGE_SET},
93 {SYSTEM_EVENT_REGION_FORMAT, EVENT_KEY_REGION_FORMAT},
94 {SYSTEM_EVENT_SILENT_MODE, EVENT_KEY_SILENT_MODE},
95 {SYSTEM_EVENT_VIBRATION_STATE, EVENT_KEY_VIBRATION_STATE},
96 {SYSTEM_EVENT_SCREEN_AUTOROTATE_STATE, EVENT_KEY_SCREEN_AUTOROTATE_STATE},
97 {SYSTEM_EVENT_MOBILE_DATA_STATE, EVENT_KEY_MOBILE_DATA_STATE},
98 {SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
99 {SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}};
101 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
102 const int kMaximumBatteryRetrievedObjects = 30;
103 const int kMaximumAppsRetrievedObjects = 10;
104 const int kDefaultPeriodOfTime = 30;
108 ApplicationManager::ApplicationManager(ApplicationInstance& instance)
109 : pkgmgr_client_handle_(nullptr),
110 pkgmgr_client_uninstall_handle_(nullptr),
112 app_status_handle_(nullptr) {
116 ApplicationManager::~ApplicationManager() {
118 StopAppInfoEventListener();
119 StopStatusChangeListener();
121 for (auto it = event_handler_map_.begin(); it != event_handler_map_.end();) {
122 int ret = event_remove_event_handler(it->second);
123 if (EVENT_ERROR_NONE != ret) {
124 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
126 it = event_handler_map_.erase(it);
129 if (app_status_handle_) {
130 int ret = app_manager_event_destroy(app_status_handle_);
131 if (APP_MANAGER_ERROR_NONE != ret) {
132 LoggerE("app_manager_event_destroy failed, error: %d", ret);
137 void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
140 // obtain handle to application info
141 pkgmgrinfo_appinfo_h handle;
142 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
143 if (PMINFO_R_OK != ret) {
144 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app info."), out,
145 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
149 picojson::value app_info = picojson::value(picojson::object());
150 picojson::object& app_info_obj = app_info.get<picojson::object>();
152 ApplicationUtils::CreateApplicationInformation(handle, &app_info_obj);
153 pkgmgrinfo_appinfo_destroy_appinfo(handle);
155 picojson::value result = picojson::value(picojson::object());
156 picojson::object& result_obj = result.get<picojson::object>();
158 result_obj.insert(std::make_pair(
160 picojson::value(std::to_string(CurrentApplication::GetInstance().GetProcessId()))));
161 result_obj.insert(std::make_pair("appInfo", app_info));
163 ReportSuccess(result, *out);
166 class TerminateHandler {
168 TerminateHandler(int callback_id, ApplicationInstance* app_instance)
169 : callback_handle_(callback_id), pid_(-1), timeout_id_(0), app_instance_(app_instance) {
172 void set_pid(pid_t pid) {
180 void Invoke(const std::shared_ptr<picojson::value>& response) {
183 if (timeout_id_ > 0) {
184 // cancel terminate callback
185 g_source_remove(timeout_id_);
189 ApplicationInstance* app_instance = this->app_instance_;
190 int callback_id = this->callback_handle_;
191 TaskQueue::GetInstance().Async<picojson::value>(
192 [callback_id, app_instance](const std::shared_ptr<picojson::value>& response) {
193 picojson::object& obj = response->get<picojson::object>();
195 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
196 Instance::PostMessage(app_instance, response->serialize().c_str());
202 int callback_handle_;
205 ApplicationInstance* app_instance_;
208 #define CHECK_RESULT(result, response, handler) \
209 if (result.IsError()) { \
210 LogAndReportError(result, &response->get<picojson::object>()); \
211 handler->Invoke(response); \
216 void ApplicationManager::AsyncResponse(PlatformResult& result,
217 std::shared_ptr<picojson::value>* response) {
219 LogAndReportError(result, &(*response)->get<picojson::object>());
221 TaskQueue::GetInstance().Async<picojson::value>(
222 [this](const std::shared_ptr<picojson::value>& response) {
223 Instance::PostMessage(&this->instance_, response->serialize().c_str());
228 void ApplicationManager::Kill(const picojson::value& args) {
231 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
233 int callback_id = -1;
234 const auto& callback = args.get(kCallbackId);
235 if (callback.is<double>()) {
236 callback_id = static_cast<int>(callback.get<double>());
239 const auto& context = args.get("contextId");
240 if (!context.is<std::string>()) {
241 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
244 const std::string& context_id = context.get<std::string>();
246 if (context_id.empty() && result.IsSuccess()) {
247 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID is empty.");
250 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
251 picojson::object& obj = response->get<picojson::object>();
252 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
254 if (result.IsError()) {
255 LoggerE("Failed args.get");
256 AsyncResponse(result, &response);
260 auto kill = [this, callback_id, context_id]() -> void {
263 std::shared_ptr<picojson::value> response =
264 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
266 TerminateHandler* handler = new TerminateHandler(callback_id, &this->instance_);
267 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
271 pid = std::stoi(context_id);
273 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
274 CHECK_RESULT(result, response, handler)
278 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID cannot be negative value.");
279 CHECK_RESULT(result, response, handler)
282 // if kill request comes for current context, throw InvalidValuesException
283 if (CurrentApplication::GetInstance().GetProcessId() == pid) {
285 LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Cannot kill current application.");
286 CHECK_RESULT(result, response, handler)
289 LoggerD("Kill, pid: %d", pid);
291 char* app_id = nullptr;
292 int ret = app_manager_get_app_id(pid, &app_id);
293 // automatically release the memory
294 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
296 if (APP_MANAGER_ERROR_NONE != ret) {
297 result = LogAndCreateResult(
298 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
299 ("Failed to get application ID, error: %d (%s)", ret, get_error_message(ret)));
300 CHECK_RESULT(result, response, handler)
303 LoggerD("Kill, app ID: %s", app_id);
305 // acquire application context
306 app_context_h app_context = nullptr;
308 ret = app_manager_get_app_context(app_id, &app_context);
309 std::unique_ptr<std::remove_pointer<app_context_h>::type, int (*)(app_context_h)>
310 app_context_ptr(app_context, &app_context_destroy); // automatically release the memory
312 if (APP_MANAGER_ERROR_NONE != ret) {
313 result = LogAndCreateResult(
314 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
315 ("Failed to get application context handle: %d (%s)", ret, get_error_message(ret)));
316 CHECK_RESULT(result, response, handler)
319 auto terminate_callback = [](app_context_h app_context, app_context_event_e event,
321 LoggerD("terminate_callback: %d", event);
323 if (APP_CONTEXT_EVENT_TERMINATED != event) {
324 LoggerD("ignoring event");
329 int ret = app_context_get_pid(app_context, &pid);
331 if (APP_MANAGER_ERROR_NONE != ret) {
332 LoggerE("Failed to get pid of terminated app: %d (%s)", ret, get_error_message(ret));
336 TerminateHandler* handler = static_cast<TerminateHandler*>(user_data);
338 LoggerD("Expected PID: %d, got: %d", handler->pid(), pid);
340 if (handler->pid() == pid) {
341 std::shared_ptr<picojson::value> response =
342 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
343 ReportSuccess(response->get<picojson::object>());
344 handler->Invoke(response);
349 LoggerD("Kill, setting callback");
350 handler->set_pid(pid);
351 ret = app_manager_set_app_context_event_cb(terminate_callback, handler);
353 if (APP_MANAGER_ERROR_NONE != ret) {
354 result = LogAndCreateResult(
355 ErrorCode::UNKNOWN_ERR, "Failed to register termination callback.",
356 ("Error while registering app context event: %d (%s)", ret, get_error_message(ret)));
357 CHECK_RESULT(result, response, handler)
360 LoggerD("Kill, calling native function");
362 // terminate application
363 ret = app_manager_terminate_app(app_context);
365 if (APP_MANAGER_ERROR_NONE != ret) {
366 result = LogAndCreateResult(
367 ErrorCode::UNKNOWN_ERR, "Failed to terminate application.",
368 ("Failed to terminate application: %d (%s)", ret, get_error_message(ret)));
369 CHECK_RESULT(result, response, handler)
372 LoggerD("Kill, end, waiting for notification");
378 void ApplicationManager::Launch(const picojson::value& args) {
381 int callback_id = -1;
382 const auto& callback = args.get(kCallbackId);
383 if (callback.is<double>()) {
384 callback_id = static_cast<int>(callback.get<double>());
387 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
388 picojson::object& obj = response->get<picojson::object>();
389 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
391 const auto& app_id = args.get("id");
392 if (!app_id.is<std::string>()) {
394 LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
395 AsyncResponse(ret, &response);
398 const std::string& id = app_id.get<std::string>();
400 auto launch = [id](const std::shared_ptr<picojson::value>& response) -> void {
401 ScopeLogger("launch");
402 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
403 const char* app_id = id.c_str();
404 const int retry_count = 3;
409 while (retry < retry_count) {
410 ret = aul_open_app(app_id);
416 // delay 300ms for each retry
417 struct timespec sleep_time = {0, 300L * 1000L * 1000L};
418 nanosleep(&sleep_time, nullptr);
421 LoggerD("Retry launch request: %d", retry);
425 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error has occurred.");
427 LoggerD("Aul open return: %d (%s)", ret, get_error_message(ret));
433 LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Launchpad returns not found error.",
434 ("aul_open_app returns Not Found error"));
438 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Internal IPC error has occurred.",
439 ("aul_open_app returns internal IPC error"));
443 LogAndReportError(result, &response->get<picojson::object>());
445 LoggerD("Launch request success");
446 ReportSuccess(response->get<picojson::object>());
451 Instance::PostMessage(&this->instance_, response->serialize().c_str());
454 void ApplicationManager::LaunchAppControl(const picojson::value& args) {
457 int callback_id = -1;
458 const auto& callback = args.get(kCallbackId);
459 if (callback.is<double>()) {
460 callback_id = static_cast<int>(callback.get<double>());
463 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
464 picojson::object& response_obj = response->get<picojson::object>();
466 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
468 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
469 const auto& control = args.get("appControl");
470 if (!control.is<picojson::object>()) {
471 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
472 AsyncResponse(result, &response);
475 const picojson::object& app_control_obj = control.get<picojson::object>();
477 std::string launch_mode_str;
478 const auto& launch_mode = control.get("launchMode");
479 if (launch_mode.is<std::string>()) {
480 launch_mode_str = launch_mode.get<std::string>();
483 app_control_h app_control = nullptr;
484 result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
485 std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
486 app_control, &app_control_destroy); // automatically release the memory
488 if (result.IsError()) {
489 LoggerE("Application control to service failed.");
490 AsyncResponse(result, &response);
495 const auto& id = args.get("id");
496 if (id.is<std::string>()) {
497 app_id = id.get<std::string>();
500 std::string reply_callback;
501 const auto& reply = args.get("replyCallback");
502 if (reply.is<std::string>()) {
503 reply_callback = reply.get<std::string>();
506 auto launch = [this, app_control_ptr, app_id, launch_mode_str,
507 reply_callback](const std::shared_ptr<picojson::value>& response) -> void {
508 ScopeLogger("Entered into asynchronous function, launch");
510 if (!app_id.empty()) {
511 LoggerD("app_id: %s", app_id.c_str());
513 int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
515 if (APP_CONTROL_ERROR_NONE != ret) {
517 PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
518 &response->get<picojson::object>(),
519 ("Failed to set app id: %d (%s)", ret, get_error_message(ret)));
524 if (!launch_mode_str.empty()) {
525 app_control_launch_mode_e launch_mode;
527 if ("SINGLE" == launch_mode_str) {
528 launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
529 } else if ("GROUP" == launch_mode_str) {
530 launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP;
532 ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
533 &response->get<picojson::object>());
537 int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode);
538 if (APP_CONTROL_ERROR_NONE != ret) {
539 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."),
540 &response->get<picojson::object>(),
541 ("Setting launch mode failed: %d (%s)", ret, get_error_message(ret)));
546 app_control_reply_cb callback = nullptr;
547 struct ReplayCallbackData {
548 ApplicationInstance* app_instance;
549 std::string reply_callback;
552 ReplayCallbackData* user_data = nullptr;
554 if (!reply_callback.empty()) {
555 user_data = new ReplayCallbackData();
556 user_data->app_instance = &this->instance_;
557 user_data->reply_callback = reply_callback;
559 callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
561 LoggerD("send_launch_request callback");
563 picojson::value return_value = picojson::value(picojson::object());
564 picojson::object& return_value_obj = return_value.get<picojson::object>();
565 ReplayCallbackData* reply_callback = static_cast<ReplayCallbackData*>(user_data);
567 if (APP_CONTROL_RESULT_SUCCEEDED == result) {
568 const std::string data = "data";
569 return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array())));
570 if (!ApplicationUtils::ServiceToApplicationControlDataArray(
571 reply, &return_value_obj.find(data)->second.get<picojson::array>())) {
572 return_value_obj.erase(data);
574 ReportSuccess(return_value_obj);
576 ReportError(return_value_obj);
579 return_value_obj.insert(
580 std::make_pair("listenerId", picojson::value(reply_callback->reply_callback)));
581 Instance::PostMessage(reply_callback->app_instance, return_value.serialize().c_str());
582 delete reply_callback;
586 const int retry_count = 3;
591 while (retry < retry_count) {
592 LoggerD("Calling launch request. Attempt number: %d", retry);
594 ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data);
595 LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret));
596 if (APP_CONTROL_ERROR_NONE == ret) {
600 // delay 300ms for each retry
601 struct timespec sleep_time = {0, 300L * 1000L * 1000L};
602 nanosleep(&sleep_time, nullptr);
606 if (APP_CONTROL_ERROR_NONE != ret) {
610 case APP_CONTROL_ERROR_INVALID_PARAMETER:
612 PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."),
613 &response->get<picojson::object>(),
614 ("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER"));
616 case APP_CONTROL_ERROR_OUT_OF_MEMORY:
618 PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."),
619 &response->get<picojson::object>(),
620 ("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY"));
622 case APP_CONTROL_ERROR_LAUNCH_REJECTED:
623 case APP_CONTROL_ERROR_APP_NOT_FOUND:
625 PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."),
626 &response->get<picojson::object>(),
627 ("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND"));
631 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."),
632 &response->get<picojson::object>(),
633 ("app_control_send_launch_request returns: %d (%s)", ret, get_error_message(ret)));
637 ReportSuccess(response->get<picojson::object>());
641 Instance::PostMessage(&this->instance_, response->serialize().c_str());
644 // internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
645 // public CAPI did not handling APP_CONTROL_ERROR_APP_NOT_FOUND
646 int app_control_foreach_app_matched_internal(app_control_h app_control,
647 app_control_app_matched_cb callback, void* user_data) {
650 app_control_h app_control;
651 app_control_app_matched_cb callback;
654 } foreach_context_launchable_app_t_internal;
656 // internal impl of app_control_cb_broker_foreach_app_matched()
657 auto app_control_cb_broker_foreach_app_matched_internal = [](const char* package,
660 "Entered into asynchronous function, app_control_cb_broker_foreach_app_matched_internal's "
662 foreach_context_launchable_app_t_internal* foreach_context;
663 app_control_app_matched_cb app_matched_cb;
665 if (package == NULL || data == NULL) {
666 LoggerE("APP_CONTROL_ERROR_INVALID_PARAMETER");
670 foreach_context = (foreach_context_launchable_app_t_internal*)data;
671 if (foreach_context->foreach_break == true) return -1;
673 app_matched_cb = foreach_context->callback;
674 if (app_matched_cb != NULL) {
675 bool stop_foreach = false;
678 !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
680 foreach_context->foreach_break = stop_foreach;
686 foreach_context_launchable_app_t_internal foreach_context = {.app_control = app_control,
687 .callback = callback,
688 .user_data = user_data,
689 .foreach_break = false};
691 bundle* bundle_data = NULL;
692 app_control_to_bundle(app_control, &bundle_data);
694 int ret = appsvc_usr_get_list(bundle_data, app_control_cb_broker_foreach_app_matched_internal,
695 &foreach_context, getuid());
699 case APPSVC_RET_EINVAL:
700 return APP_CONTROL_ERROR_INVALID_PARAMETER;
702 case APPSVC_RET_ENOMATCH:
703 return APP_CONTROL_ERROR_APP_NOT_FOUND;
706 return APP_CONTROL_ERROR_LAUNCH_FAILED;
710 return APP_CONTROL_ERROR_NONE;
713 void ApplicationManager::FindAppControl(const picojson::value& args) {
716 int callback_id = -1;
717 const auto& callback = args.get(kCallbackId);
718 if (callback.is<double>()) {
719 callback_id = static_cast<int>(callback.get<double>());
722 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
723 picojson::object& response_obj = response->get<picojson::object>();
725 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
727 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
728 const auto& control = args.get("appControl");
729 if (!control.is<picojson::object>()) {
730 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
731 AsyncResponse(result, &response);
735 const picojson::object& app_control_obj = control.get<picojson::object>();
737 app_control_h app_control = nullptr;
738 result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
739 std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
740 app_control, &app_control_destroy); // automatically release the memory
742 if (result.IsError()) {
743 LoggerE("Application control to service failed.");
744 AsyncResponse(result, &response);
748 auto find = [app_control_ptr](const std::shared_ptr<picojson::value>& response) -> void {
749 ScopeLogger("Entered into asynchronous function, find");
750 auto app_control_matched = [](app_control_h app_control, const char* appid,
751 void* user_data) -> bool {
752 ScopeLogger("Entered into asynchronous function, app_control_matched");
753 if (nullptr == appid) {
754 LoggerD("appid is NULL");
758 pkgmgrinfo_appinfo_h handle;
759 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &handle);
760 if (PMINFO_R_OK != ret) {
761 LoggerE("Failed to get appInfo: %d (%s)", ret, get_error_message(ret));
763 picojson::array* array = static_cast<picojson::array*>(user_data);
764 array->push_back(picojson::value(picojson::object()));
766 ApplicationUtils::CreateApplicationInformation(handle,
767 &array->back().get<picojson::object>());
768 pkgmgrinfo_appinfo_destroy_appinfo(handle);
774 picojson::object& response_obj = response->get<picojson::object>();
775 auto it_result = response_obj.find("result");
776 picojson::object& result_obj = it_result->second.get<picojson::object>();
778 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())));
780 int ret = app_control_foreach_app_matched_internal(app_control_ptr.get(), app_control_matched,
781 &array.first->second.get<picojson::array>());
783 if (APP_CONTROL_ERROR_NONE != ret) {
784 if (APP_CONTROL_ERROR_APP_NOT_FOUND == ret) {
785 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Matched Application not found"),
786 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
787 get_error_message(ret)));
788 } else if (APP_CONTROL_ERROR_LAUNCH_FAILED == ret) {
790 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error"), &response_obj,
791 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
792 } else if (APP_CONTROL_ERROR_INVALID_PARAMETER == ret) {
793 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed"),
794 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
795 get_error_message(ret)));
797 // remove copied ApplicationControl from result
798 response_obj.erase(it_result);
800 ReportSuccess(response_obj);
804 auto find_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
805 ScopeLogger("Entered into asynchronous function, find_response");
806 Instance::PostMessage(&this->instance_, response->serialize().c_str());
809 // prepare result object, we need to do that here, as input parameter is passed to result callback
810 auto ret = response_obj.insert(std::make_pair("result", picojson::value(picojson::object())));
811 // reinsert application control
812 ret.first->second.get<picojson::object>().insert(
813 std::make_pair("appControl", args.get("appControl")));
815 TaskQueue::GetInstance().Queue<picojson::value>(find, find_response, response);
818 void ApplicationManager::GetAppsContext(const picojson::value& args) {
821 int callback_id = -1;
822 const auto& callback = args.get(kCallbackId);
823 if (callback.is<double>()) {
824 callback_id = static_cast<int>(callback.get<double>());
827 auto get_apps_context = [](const std::shared_ptr<picojson::value>& response) -> void {
828 picojson::object& response_obj = response->get<picojson::object>();
829 picojson::value result = picojson::value(picojson::object());
830 picojson::object& result_obj = result.get<picojson::object>();
831 picojson::array& array =
832 result_obj.insert(std::make_pair("contexts", picojson::value(picojson::array())))
833 .first->second.get<picojson::array>();
835 auto app_context_cb = [](app_context_h app_context, void* user_data) -> bool {
836 if (nullptr == user_data) {
840 picojson::array* array = static_cast<picojson::array*>(user_data);
841 array->push_back(picojson::value(picojson::object()));
843 if (!ApplicationUtils::CreateApplicationContext(app_context,
844 &array->back().get<picojson::object>())) {
852 int ret = app_manager_foreach_app_context(app_context_cb, &array);
854 if (APP_MANAGER_ERROR_NONE != ret) {
856 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
857 ("app_manager_foreach_app_context error: %d (%s)", ret, get_error_message(ret)));
859 ReportSuccess(result, response_obj);
863 auto get_apps_context_response =
864 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
865 picojson::object& obj = response->get<picojson::object>();
866 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
867 Instance::PostMessage(&this->instance_, response->serialize().c_str());
870 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
872 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_context, get_apps_context_response,
876 void ApplicationManager::GetAppContext(const picojson::value& args, picojson::object* out) {
880 const auto& context_id = args.get("contextId");
881 if (context_id.is<std::string>()) {
883 pid = std::stoi(context_id.get<std::string>());
885 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert context id."),
890 pid = CurrentApplication::GetInstance().GetProcessId();
893 char* app_id = nullptr;
895 int ret = app_manager_get_app_id(pid, &app_id);
896 // automatically release the memory
897 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
899 if (APP_MANAGER_ERROR_NONE != ret || nullptr == app_id) {
901 case APP_MANAGER_ERROR_NO_SUCH_APP:
902 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "No such application exist."), out,
903 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_NO_SUCH_APP"));
906 case APP_MANAGER_ERROR_INVALID_PARAMETER:
907 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Application not found."), out,
908 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_INVALID_PARAMETER"));
913 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), out,
914 ("app_manager_get_app_id returned: %d (%s)", ret, get_error_message(ret)));
919 picojson::value result = picojson::value(picojson::object());
920 ApplicationUtils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
922 ReportSuccess(result, *out);
925 void ApplicationManager::GetAppsInfo(const picojson::value& args) {
928 int callback_id = -1;
929 const auto& callback = args.get(kCallbackId);
930 if (callback.is<double>()) {
931 callback_id = static_cast<int>(callback.get<double>());
934 auto get_apps_info = [](const std::shared_ptr<picojson::value>& response) -> void {
935 ScopeLogger("Entered into asynchronous function, get_apps_info");
936 picojson::object& response_obj = response->get<picojson::object>();
937 picojson::value result = picojson::value(picojson::object());
938 picojson::object& result_obj = result.get<picojson::object>();
939 picojson::array& array =
940 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())))
941 .first->second.get<picojson::array>();
943 auto app_info_cb = [](pkgmgrinfo_appinfo_h handle, void* user_data) -> int {
944 ScopeLogger("Entered into asynchronous function, app_info_cb");
945 if (nullptr == user_data) {
949 picojson::array* array = static_cast<picojson::array*>(user_data);
950 array->push_back(picojson::value(picojson::object()));
952 ApplicationUtils::CreateApplicationInformation(handle,
953 &array->back().get<picojson::object>());
958 int ret = pkgmgrinfo_appinfo_get_usr_installed_list(app_info_cb, getuid(), &array);
960 if (APP_MANAGER_ERROR_NONE != ret) {
961 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
962 ("pkgmgrinfo_appinfo_get_usr_installed_list error"));
964 ReportSuccess(result, response_obj);
968 auto get_apps_info_response =
969 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
970 ScopeLogger("Entered into asynchronous function, get_apps_info_response");
971 picojson::object& obj = response->get<picojson::object>();
972 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
973 Instance::PostMessage(&this->instance_, response->serialize().c_str());
976 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
978 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_info, get_apps_info_response, data);
981 void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object* out) {
984 pkgmgrinfo_appinfo_h handle = nullptr;
986 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
987 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out);
991 picojson::value result = picojson::value(picojson::object());
992 ApplicationUtils::CreateApplicationInformation(handle, &result.get<picojson::object>());
993 pkgmgrinfo_appinfo_destroy_appinfo(handle);
995 ReportSuccess(result, *out);
998 char* ApplicationManager::GetPackageId(const std::string& app_id) {
1001 char* pkg_id = nullptr;
1003 int ret = app_manager_get_app_info(app_id.c_str(), &handle);
1004 if (APP_MANAGER_ERROR_NONE != ret) {
1005 LoggerE("Failed to get app info: %d (%s)", ret, get_error_message(ret));
1009 ret = app_info_get_package(handle, &pkg_id);
1010 if (APP_MANAGER_ERROR_NONE != ret) {
1011 LoggerE("Failed to get package id: %d (%s)", ret, get_error_message(ret));
1015 ret = app_info_destroy(handle);
1016 if (APP_MANAGER_ERROR_NONE != ret) {
1017 LoggerE("Failed to destroy app info: %d (%s)", ret, get_error_message(ret));
1023 void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object* out) {
1026 char* package_id = nullptr;
1028 package_id = GetPackageId(app_id);
1029 // automatically release the memory
1030 std::unique_ptr<char, void (*)(void*)> package_id_ptr(package_id, &std::free);
1033 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1037 package_info_h pkg_info = nullptr;
1038 int ret = package_info_create(package_id, &pkg_info);
1040 std::unique_ptr<std::remove_pointer<package_info_h>::type, int (*)(package_info_h)> pkg_info_ptr(
1041 pkg_info, &package_info_destroy); // automatically release the memory
1043 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1044 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1045 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1049 auto cert_info_cb = [](package_info_h handle, package_cert_type_e cert_type,
1050 const char* cert_value, void* user_data) -> bool {
1051 const char* cert_name = nullptr;
1053 switch (cert_type) {
1054 case PACKAGE_INFO_AUTHOR_ROOT_CERT:
1055 cert_name = "AUTHOR_ROOT";
1057 case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT:
1058 cert_name = "AUTHOR_INTERMEDIATE";
1060 case PACKAGE_INFO_AUTHOR_SIGNER_CERT:
1061 cert_name = "AUTHOR_SIGNER";
1063 case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT:
1064 cert_name = "DISTRIBUTOR_ROOT";
1066 case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT:
1067 cert_name = "DISTRIBUTOR_INTERMEDIATE";
1069 case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT:
1070 cert_name = "DISTRIBUTOR_SIGNER";
1072 case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT:
1073 cert_name = "DISTRIBUTOR2_ROOT";
1075 case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT:
1076 cert_name = "DISTRIBUTOR2_INTERMEDIATE";
1078 case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT:
1079 cert_name = "DISTRIBUTOR2_SIGNER";
1082 LoggerD("Unknown certificate type: %d", cert_type);
1086 picojson::array* array = static_cast<picojson::array*>(user_data);
1087 array->push_back(picojson::value(picojson::object()));
1089 ApplicationUtils::CreateApplicationCertificate(cert_name, cert_value,
1090 &array->back().get<picojson::object>());
1095 picojson::value result = picojson::value(picojson::array());
1097 ret = package_info_foreach_cert_info(pkg_info, cert_info_cb, &result.get<picojson::array>());
1099 if ((PACKAGE_MANAGER_ERROR_NONE != ret) && (PACKAGE_MANAGER_ERROR_IO_ERROR != ret)) {
1100 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get certificates info."),
1102 ("Failed to get certificates info: %d (%s)", ret, get_error_message(ret)));
1106 ReportSuccess(result, *out);
1109 void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::object* out) {
1111 // this implementation assumes that shared/trusted path is the obligatory member of application
1112 // and it is used to extract the parent directory 'shared'
1113 char* path = nullptr;
1114 int ret = app_manager_get_shared_trusted_path(app_id.c_str(), &path);
1115 if (APP_MANAGER_ERROR_NONE != ret) {
1116 // if the application does not exist, there is no need to check "res" directory
1117 if (APP_MANAGER_ERROR_NO_SUCH_APP == ret) {
1118 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get shared URI."), out);
1122 // if the shared_trusted directory is not properly returned, gathering the shared/res path,
1123 // which is the obligatory member. The global path could be different then:
1124 // e.g. instead of path: /opt/usr/home/owner/apps_rw/org.example.basic/shared/
1125 // returned path is: /opt/usr/globalapps/org.example.basic/shared/
1127 "app_manager_get_shared_trusted_path failed(), trying "
1128 "app_manager_get_shared_resource_path() to gather path");
1129 int ret = app_manager_get_shared_resource_path(app_id.c_str(), &path);
1130 if (APP_MANAGER_ERROR_NONE != ret) {
1131 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get shared URI."), out);
1136 std::string path_str = path;
1139 std::string shared_path = path_str.substr(0, path_str.rfind("/", path_str.length() - 2));
1141 // checking if path is valid
1142 struct stat stat_res;
1143 if (0 != stat(shared_path.c_str(), &stat_res)) {
1144 LoggerW("Path %s does not exist", shared_path.c_str());
1145 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get shared URI."), out);
1149 picojson::value result = picojson::value(kTizenApisFileScheme + shared_path);
1150 ReportSuccess(result, *out);
1153 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1154 PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args,
1155 const context_history_filter_h filter,
1156 context_history_data_e* data_type_out) {
1158 int ret = CONTEXT_HISTORY_ERROR_NONE;
1159 int limit = kMaximumBatteryRetrievedObjects;
1160 if (args.contains("limit")) {
1161 limit = static_cast<int>(args.get("limit").get<double>());
1164 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1166 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1167 return LogAndCreateResult(
1168 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1169 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1172 context_history_data_e data_type_in = CONTEXT_HISTORY_RECENT_BATTERY_USAGE;
1174 if (args.contains("days")) {
1175 const int days = static_cast<int>(args.get("days").get<double>());
1176 data_type_in = CONTEXT_HISTORY_BATTERY_USAGE;
1177 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, days);
1179 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1180 return LogAndCreateResult(
1181 ErrorCode::INVALID_VALUES_ERR, "days given with invalid value.",
1182 ("days given with invalid value: %d (%s)", ret, get_error_message(ret)));
1186 *data_type_out = data_type_in;
1188 return PlatformResult(ErrorCode::NO_ERROR);
1191 PlatformResult ApplicationManager::BatteryUsageAttributes(const context_history_record_h record,
1192 picojson::object* object) {
1195 int ret = CONTEXT_HISTORY_ERROR_NONE;
1196 double amount = 0.0;
1197 char* app_id = nullptr;
1202 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1203 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1204 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1205 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1208 ret = context_history_record_get_double(record, CONTEXT_HISTORY_TOTAL_AMOUNT, &amount);
1209 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1210 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get amount.",
1211 ("Failed to get amount: %d (%s)", ret, get_error_message(ret)));
1214 object->insert(std::make_pair("appId", picojson::value(app_id)));
1215 object->insert(std::make_pair("batteryUsage", picojson::value(amount)));
1217 return PlatformResult(ErrorCode::NO_ERROR);
1220 PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
1221 const context_history_filter_h filter,
1222 context_history_data_e* data_type_out) {
1224 int ret = CONTEXT_HISTORY_ERROR_NONE;
1225 int limit = kMaximumAppsRetrievedObjects;
1226 if (args.contains("limit")) {
1227 limit = static_cast<int>(args.get("limit").get<double>());
1230 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1231 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1232 return LogAndCreateResult(
1233 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1234 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1237 context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
1238 if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
1239 data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
1242 int time_span = kDefaultPeriodOfTime;
1243 const picojson::object& JS_filter = args.get("filter").get<picojson::object>();
1244 auto time_span_iter = JS_filter.find("timeSpan");
1245 if (JS_filter.end() != time_span_iter || (JS_filter.end() == JS_filter.find("startTime") &&
1246 JS_filter.end() == JS_filter.find("endTime"))) {
1247 // In the second case, we treat the filter object just like an empty object.
1248 // The default value of filter will be used instead.
1249 if (JS_filter.end() != time_span_iter) {
1250 time_span = static_cast<int>(time_span_iter->second.get<double>());
1252 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
1253 // context_history_filter_set_int may return only success or
1254 // CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
1255 // Although this should never happen, it's better to check ret's value
1256 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1257 return LogAndCreateResult(ErrorCode::ABORT_ERR,
1258 "Error while setting the default TIME_SPAN value.",
1259 ("Error while setting the default TIME_SPAN value: %d (%s)", ret,
1260 get_error_message(ret)));
1263 auto start_time_iter = JS_filter.find("startTime");
1264 auto end_time_iter = JS_filter.find("endTime");
1265 if (start_time_iter != JS_filter.end()) {
1266 int start_time = static_cast<int>(start_time_iter->second.get<double>());
1267 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
1268 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1269 return LogAndCreateResult(
1270 ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
1271 ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1274 if (end_time_iter != JS_filter.end()) {
1275 int end_time = static_cast<int>(end_time_iter->second.get<double>());
1276 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
1277 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1278 return LogAndCreateResult(
1279 ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
1280 ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1285 *data_type_out = data_type_in;
1287 return PlatformResult(ErrorCode::NO_ERROR);
1290 PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
1291 picojson::object* object) {
1294 int ret = CONTEXT_HISTORY_ERROR_NONE;
1295 int total_count = 0;
1296 int total_duration = 0;
1298 char* app_id = nullptr;
1303 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1304 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1305 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1306 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1309 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
1310 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1311 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
1312 ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
1315 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
1316 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1317 return LogAndCreateResult(
1318 ErrorCode::ABORT_ERR, "Failed to get total duration.",
1319 ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
1322 ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
1323 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1324 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
1325 ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
1328 object->insert(std::make_pair("appId", picojson::value(app_id)));
1329 object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
1331 std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
1332 object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
1334 return PlatformResult(ErrorCode::NO_ERROR);
1338 void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
1341 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1342 int callback_id = -1;
1343 const auto& callback = args.get(kCallbackId);
1344 if (callback.is<double>()) {
1345 callback_id = static_cast<int>(callback.get<double>());
1348 auto get_battery_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1350 PlatformResult result = ApplicationManager::GetContextHistory(
1351 args, &response.get()->get<picojson::object>(), &ApplicationManager::BatteryUsageFilter,
1352 &ApplicationManager::BatteryUsageAttributes);
1354 LogAndReportError(result, &response.get()->get<picojson::object>());
1358 auto get_battery_usage_response =
1359 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1361 picojson::object& obj = response->get<picojson::object>();
1362 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1363 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1366 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1368 TaskQueue::GetInstance().Queue<picojson::value>(get_battery_usage, get_battery_usage_response,
1371 // 20170510 Context API is supported only for mobile profile, other ones would result with
1372 // NotSupportedError
1373 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1374 "This feature is not supported on this profile."),
1375 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1379 void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
1382 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1383 int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
1385 auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1387 PlatformResult result = ApplicationManager::GetContextHistory(
1388 args, &response.get()->get<picojson::object>(), &ApplicationManager::AppsUsageFilter,
1389 &ApplicationManager::AppsUsageAttributes);
1391 LogAndReportError(result, &response.get()->get<picojson::object>());
1395 auto get_apps_usage_response =
1396 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1398 picojson::object& obj = response->get<picojson::object>();
1399 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1400 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1403 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1405 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_usage, get_apps_usage_response, data);
1407 // Context API is supported only for mobile profile, other ones would result with
1408 // NotSupportedError
1409 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1410 "This feature is not supported on this profile."),
1411 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1415 void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
1418 pkgmgrinfo_appinfo_h handle = nullptr;
1420 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
1421 std::unique_ptr<std::remove_pointer<pkgmgrinfo_appinfo_h>::type, int (*)(pkgmgrinfo_appinfo_h)>
1422 pkg_info_ptr(handle,
1423 &pkgmgrinfo_appinfo_destroy_appinfo); // automatically release the memory
1425 if (PMINFO_R_OK != ret) {
1426 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out,
1427 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
1431 auto meta_data_cb = [](const char* meta_key, const char* meta_value, void* user_data) -> int {
1432 if (nullptr == meta_key || nullptr == meta_value) {
1433 LoggerE("meta_key or meta_value is null");
1437 picojson::array* array = static_cast<picojson::array*>(user_data);
1438 array->push_back(picojson::value(picojson::object()));
1440 ApplicationUtils::CreateApplicationMetaData(meta_key, meta_value,
1441 &array->back().get<picojson::object>());
1445 picojson::value result = picojson::value(picojson::array());
1446 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, meta_data_cb, &result.get<picojson::array>());
1448 if (PMINFO_R_OK != ret) {
1449 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get metadata."), out,
1450 ("Failed to get metadata: %d (%s)", ret, get_error_message(ret)));
1454 ReportSuccess(result, *out);
1457 class ApplicationListChangedBroker {
1459 ApplicationListChangedBroker() : event_type_() {
1467 static int ClientStatusListener(unsigned int target_uid, int id, const char* type,
1468 const char* package, const char* key, const char* val,
1469 const void* msg, void* data) {
1471 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1473 if (0 == strcasecmp(key, kStartKey)) {
1474 that->HandleStart(val, package);
1475 } else if (0 == strcasecmp(key, kEndKey) && 0 == strcasecmp(val, kOkValue)) {
1476 that->HandleEnd(package);
1478 LoggerD("Ignored key: %s", key);
1484 static int AppUninstallListener(uid_t target_uid, int id, const char* type, const char* package,
1485 const char* key, const char* val, const void* msg, void* data) {
1488 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1490 if (0 == strcasecmp(key, kStartKey)) {
1491 that->HandleUninstallStart();
1492 } else if (0 == strcasecmp(key, kAppidKey)) {
1493 that->AddUninstalledAppId(val);
1494 } else if (0 == strcasecmp(key, kEndKey)) {
1495 that->HandleUninstallEnd();
1497 LoggerD("Ignored key: %s", key);
1503 void AddApplicationInstance(ApplicationInstance* app_instance) {
1505 app_instance_list_.push_back(app_instance);
1508 void RemoveApplicationInstance(ApplicationInstance* app_instance) {
1510 for (auto it = app_instance_list_.begin(); it != app_instance_list_.end(); it++) {
1511 if (*it == app_instance) {
1512 app_instance_list_.erase(it);
1519 void HandleStart(const char* event_type, const char* package) {
1522 set_event_type(event_type);
1525 void HandleEnd(const char* package) {
1528 if (Event::kUninstalled == event_type_) {
1532 GetApplicationIdsFromPackage(package);
1534 for (auto& app_id : app_list_) {
1535 picojson::value value = picojson::value(picojson::object());
1536 picojson::object& data_obj = value.get<picojson::object>();
1538 switch (event_type_) {
1539 case Event::kInstalled:
1540 data_obj.insert(std::make_pair(kAction, picojson::value(kOnInstalled)));
1543 case Event::kUpdated:
1544 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUpdated)));
1546 case Event::kUninstalled:
1547 LoggerD("Uninstalled called");
1551 switch (event_type_) {
1552 case Event::kInstalled:
1553 case Event::kUpdated: {
1554 pkgmgrinfo_appinfo_h handle = nullptr;
1556 pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1557 LoggerE("Failed to get application information handle.");
1560 auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object())));
1561 ApplicationUtils::CreateApplicationInformation(
1562 handle, &info.first->second.get<picojson::object>());
1563 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1565 case Event::kUninstalled:
1566 LoggerD("Uninstalled called");
1570 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1572 for (auto instance : app_instance_list_) {
1573 Instance::PostMessage(instance, value.serialize().c_str());
1578 void GetApplicationIdsFromPackage(const char* package) {
1580 package_info_h package_info = nullptr;
1582 int ret = package_info_create(package, &package_info);
1583 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1584 LoggerE("Failed to create package info: %d (%s)", ret, get_error_message(ret));
1588 ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_ALLAPP,
1589 ApplicationIdCallback, this);
1590 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1591 LoggerE("Failed to get application IDs: %d (%s)", ret, get_error_message(ret));
1594 ret = package_info_destroy(package_info);
1595 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1596 LoggerE("Failed to destroy package info: %d (%s)", ret, get_error_message(ret));
1600 void set_event_type(const char* type) {
1602 if (0 == strcasecmp(type, kInstallEvent)) {
1603 event_type_ = Event::kInstalled;
1604 } else if (0 == strcasecmp(type, kUpdateEvent)) {
1605 event_type_ = Event::kUpdated;
1606 } else if (0 == strcasecmp(type, kUninstallEvent)) {
1607 event_type_ = Event::kUninstalled;
1611 static bool ApplicationIdCallback(package_info_app_component_type_e comp_type, const char* app_id,
1614 if (nullptr != app_id) {
1615 static_cast<ApplicationListChangedBroker*>(user_data)->app_list_.push_back(app_id);
1620 void HandleUninstallStart() {
1623 set_event_type(kUninstallEvent);
1626 void AddUninstalledAppId(const char* app_id) {
1628 if (nullptr != app_id) {
1629 app_list_.push_back(app_id);
1633 void HandleUninstallEnd() {
1635 for (auto& app_id : app_list_) {
1636 picojson::value value = picojson::value(picojson::object());
1637 picojson::object& data_obj = value.get<picojson::object>();
1639 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUninstalled)));
1640 data_obj.insert(std::make_pair(kData, picojson::value(app_id)));
1642 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1644 for (auto instance : app_instance_list_) {
1645 Instance::PostMessage(instance, value.serialize().c_str());
1651 std::vector<std::string> app_list_;
1652 std::vector<ApplicationInstance*> app_instance_list_;
1655 static ApplicationListChangedBroker g_application_list_changed_broker;
1657 void ApplicationManager::StartAppInfoEventListener(picojson::object* out) {
1660 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1661 if (nullptr == pkgmgr_client_handle_) {
1662 pkgmgr_client_handle_ = pkgmgr_client_new(PC_LISTENING);
1664 if (nullptr == pkgmgr_client_uninstall_handle_) {
1665 pkgmgr_client_uninstall_handle_ = pkgmgr_client_new(PC_LISTENING);
1668 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1669 if (nullptr != pkgmgr_client_handle_) {
1670 pkgmgr_client_free(pkgmgr_client_handle_);
1671 pkgmgr_client_handle_ = nullptr;
1673 if (nullptr != pkgmgr_client_uninstall_handle_) {
1674 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1675 pkgmgr_client_uninstall_handle_ = nullptr;
1677 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."),
1682 #define CHECK_APPLICATION_EVENT_ERROR(result, function_name) \
1683 if (PKGMGR_R_OK > result) { \
1684 StopAppInfoEventListener(); \
1685 LogAndReportError( \
1686 PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."), out, \
1687 ("Function %s failed: %s (%d)", function_name, get_error_message(result), result)); \
1691 g_application_list_changed_broker.AddApplicationInstance(&instance_);
1693 int result = pkgmgr_client_set_status_type(
1694 pkgmgr_client_handle_,
1695 PACKAGE_MANAGER_STATUS_TYPE_INSTALL | PACKAGE_MANAGER_STATUS_TYPE_UPGRADE);
1696 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1698 result = pkgmgr_client_set_status_type(pkgmgr_client_uninstall_handle_,
1699 PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL);
1700 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1702 result = pkgmgr_client_listen_status(pkgmgr_client_handle_,
1703 ApplicationListChangedBroker::ClientStatusListener,
1704 &g_application_list_changed_broker);
1705 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1707 result = pkgmgr_client_listen_status(pkgmgr_client_uninstall_handle_,
1708 ApplicationListChangedBroker::AppUninstallListener,
1709 &g_application_list_changed_broker);
1710 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1712 #undef CHECK_APPLICATION_EVENT_ERROR
1714 LoggerD("Broker callback is already registered.");
1717 ReportSuccess(*out);
1720 void ApplicationManager::StopAppInfoEventListener() {
1723 if (nullptr != pkgmgr_client_handle_ || nullptr != pkgmgr_client_uninstall_handle_) {
1724 if (nullptr != pkgmgr_client_handle_) {
1725 pkgmgr_client_free(pkgmgr_client_handle_);
1726 pkgmgr_client_handle_ = nullptr;
1728 if (nullptr != pkgmgr_client_uninstall_handle_) {
1729 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1730 pkgmgr_client_uninstall_handle_ = nullptr;
1732 g_application_list_changed_broker.RemoveApplicationInstance(&instance_);
1734 LoggerD("Broker callback is already unregistered.");
1738 void ApplicationManager::GetApplicationInformationSize(const picojson::value& args,
1739 picojson::object* out) {
1742 const auto& package_id = args.get("packageId");
1743 if (!package_id.is<std::string>()) {
1744 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
1749 const std::string& package_id_str = package_id.get<std::string>();
1751 // get installed size from package server (to solve smack issue)
1752 pkgmgr_client* pc = pkgmgr_client_new(PC_REQUEST);
1755 if (nullptr == pc) {
1756 LoggerE("Failed to create pkgmgr client");
1758 size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL,
1759 package_id_str.c_str(), NULL, NULL, NULL);
1762 LoggerE("Failed to get installed size: %d (%s)", size, get_error_message(size));
1765 pkgmgr_client_free(pc);
1768 picojson::value result = picojson::value(picojson::object());
1769 picojson::object& result_obj = result.get<picojson::object>();
1770 result_obj.insert(std::make_pair("size", picojson::value(static_cast<double>(size))));
1772 ReportSuccess(result, *out);
1775 void ApplicationManager::BroadcastEventHelper(const picojson::value& args, picojson::object& out,
1780 std::string event_str = args.get("name").get<std::string>();
1781 const char* event_name = event_str.c_str();
1783 bundle* data = bundle_create();
1788 ret = bundle_add(data, "data", args.get("data").serialize().c_str());
1790 if (ret != EVENT_ERROR_NONE) {
1791 LoggerE("bundle_add failed, error: %d (%s)", ret, get_error_message(ret));
1797 ret = event_publish_trusted_app_event(event_name, data);
1799 ret = event_publish_app_event(event_name, data);
1802 if (ret == EVENT_ERROR_NONE) {
1805 LoggerE("event_publish_app_event failed, error: %d (%s)", ret, get_error_message(ret));
1810 void ApplicationManager::OnEvent(const char* event_name, bundle* event_data, void* user_data) {
1811 ScopeLogger("Event name is: '%s'", event_name);
1813 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1815 if (!manager->event_callback_) {
1816 LoggerD("No event listener registered, skipping.");
1820 picojson::value event = picojson::value(picojson::object());
1821 picojson::object& event_o = event.get<picojson::object>();
1824 char* val = nullptr;
1826 if (event_map_.count(event_name)) { // system event
1827 const std::string& key = event_map_.at(event_name);
1828 std::string state = "true";
1830 ret = bundle_get_str(event_data, key.c_str(), &val);
1831 if (EVENT_ERROR_NONE != ret) {
1832 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1836 state = std::string(val);
1839 LoggerD("State is %s", state.c_str());
1840 event_o["value"] = picojson::value(state);
1842 } else { // user event
1843 ret = bundle_get_str(event_data, "data", &val);
1844 if (EVENT_ERROR_NONE != ret) {
1845 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1849 picojson::value data;
1851 picojson::parse(data, val, val + strlen(val), &err);
1853 LoggerE("Failed to parse bundle data: %s", err.c_str());
1857 event_o["data"] = data;
1860 LoggerD("event_name is: %s", event_name);
1861 event_o["name"] = picojson::value(event_name);
1863 manager->event_callback_(&event);
1866 PlatformResult ApplicationManager::StartEventListener(const std::string& event_name,
1867 const JsonCallback& callback) {
1871 event_handler_h event_handler;
1873 ret = event_add_event_handler(event_name.c_str(), OnEvent, this, &event_handler);
1874 LoggerD("event_add_event_handler() result: %d (%s)", ret, get_error_message(ret));
1875 if (EVENT_ERROR_PERMISSION_DENIED == ret) {
1876 return LogAndCreateResult(ErrorCode::SECURITY_ERR, "The privilege is required",
1877 ("event_add_event_handler failed, error: %d", ret));
1878 } else if (EVENT_ERROR_NONE != ret) {
1879 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error setting event listener",
1880 ("event_add_event_handler failed, error: %d", ret));
1883 event_handler_map_[event_name] = event_handler;
1885 event_callback_ = callback;
1886 LoggerD("event_add_event_handler success");
1887 return PlatformResult(ErrorCode::NO_ERROR);
1890 void ApplicationManager::StopEventListener(const std::string& event_name) {
1894 event_handler_h event_handler;
1896 if (event_handler_map_.find(event_name) != event_handler_map_.end()) {
1897 event_handler = event_handler_map_[event_name];
1899 ret = event_remove_event_handler(event_handler);
1900 if (EVENT_ERROR_NONE != ret) {
1901 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
1905 event_handler_map_.erase(event_name);
1909 void ApplicationManager::OnStatusEvent(const char* type, const char* app_id,
1910 app_manager_event_type_e event_type,
1911 app_manager_event_state_e event_state,
1912 app_manager_event_h handle, void* user_data) {
1915 if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
1916 LoggerD("State different from completed");
1920 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1922 if (!manager || !manager->status_callback_) {
1923 LoggerD("No event listener registered, skipping.");
1928 switch (event_type) {
1929 case APP_MANAGER_EVENT_ENABLE_APP:
1932 case APP_MANAGER_EVENT_DISABLE_APP:
1933 status_type = false;
1936 LoggerD("Uknown status type skipping.");
1940 picojson::value event = picojson::value(picojson::object());
1941 picojson::object& event_o = event.get<picojson::object>();
1943 event_o[kStatusType] = picojson::value(status_type);
1944 event_o[kAppId] = picojson::value(app_id);
1945 event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
1947 manager->status_callback_(&event);
1950 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1951 PlatformResult ApplicationManager::GetContextHistory(
1952 const picojson::value& args, picojson::object* out,
1953 common::PlatformResult (*modify_filter_cb)(const picojson::value&,
1954 const context_history_filter_h,
1955 context_history_data_e* data_type),
1956 common::PlatformResult (*add_attributes_to_object)(const context_history_record_h,
1957 picojson::object*)) {
1959 context_history_list_h list = nullptr;
1960 context_history_h handle = nullptr;
1961 context_history_filter_h filter = nullptr;
1964 context_history_list_destroy(list);
1965 context_history_destroy(handle);
1966 context_history_filter_destroy(filter);
1969 int ret = context_history_create(&handle);
1970 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1971 return LogAndCreateResult(
1972 ErrorCode::ABORT_ERR, "Failed to create context handle.",
1973 ("Failed to create context handle: %d (%s)", ret, get_error_message(ret)));
1976 ret = context_history_filter_create(&filter);
1977 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1978 return LogAndCreateResult(
1979 ErrorCode::ABORT_ERR, "Failed to create filter handle.",
1980 ("Failed to create filter handle: %d (%s)", ret, get_error_message(ret)));
1983 context_history_data_e data_type;
1985 PlatformResult result = modify_filter_cb(args, filter, &data_type);
1990 picojson::value result_array = picojson::value(picojson::array());
1991 picojson::array& array_obj = result_array.get<picojson::array>();
1993 ret = context_history_get_list(handle, data_type, filter, &list);
1994 if (CONTEXT_HISTORY_ERROR_NO_DATA == ret) {
1995 ReportSuccess(result_array, *out);
1996 return PlatformResult(ErrorCode::NO_ERROR);
1997 } else if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1998 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list.",
1999 ("Failed to get list: %d (%s)", ret, get_error_message(ret)));
2003 ret = context_history_list_get_count(list, &size);
2004 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2005 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list size.",
2006 ("Failed to get list size: %d (%s)", ret, get_error_message(ret)));
2009 array_obj.resize(size, picojson::value(picojson::object()));
2011 for (int i = 0; i < size; ++i) {
2012 context_history_record_h record = nullptr;
2014 context_history_record_destroy(record);
2017 ret = context_history_list_get_current(list, &record);
2018 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2019 return LogAndCreateResult(
2020 ErrorCode::ABORT_ERR, "Failed to get current record.",
2021 ("Failed to get current record: %d (%s)", ret, get_error_message(ret)));
2024 result = add_attributes_to_object(record, &array_obj[i].get<picojson::object>());
2029 ret = context_history_list_move_next(list);
2030 if (CONTEXT_HISTORY_ERROR_NONE != ret && CONTEXT_HISTORY_ERROR_NO_DATA != ret) {
2031 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to move iterator.",
2032 ("Failed to move iterator: %d (%s)", ret, get_error_message(ret)));
2036 ReportSuccess(result_array, *out);
2037 return PlatformResult(ErrorCode::NO_ERROR);
2041 PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
2044 int ret = APP_MANAGER_ERROR_NONE;
2046 if (!app_status_handle_) {
2047 ret = app_manager_event_create(&app_status_handle_);
2048 if (APP_MANAGER_ERROR_NONE != ret) {
2049 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
2050 ("app_manager_event_create failed, error: %d", ret));
2053 ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
2054 if (APP_MANAGER_ERROR_NONE != ret) {
2055 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
2056 ("app_manager_event_set_status failed, error: %d", ret));
2060 status_callback_ = callback;
2061 ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
2062 if (APP_MANAGER_ERROR_NONE != ret) {
2063 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
2064 ("app_manager_set_event_cb failed, error: %d", ret));
2067 return PlatformResult(ErrorCode::NO_ERROR);
2070 PlatformResult ApplicationManager::StopStatusChangeListener() {
2073 if (app_status_handle_) {
2074 int ret = app_manager_unset_event_cb(app_status_handle_);
2075 if (APP_MANAGER_ERROR_NONE != ret) {
2076 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
2077 ("app_manager_unset_event_cb failed, error: %d", ret));
2081 return PlatformResult(ErrorCode::NO_ERROR);
2084 } // namespace application
2085 } // namespace extension