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"
20 #include <type_traits>
22 #include <app_control_internal.h>
24 #include <app_manager_extension.h>
28 #include <bundle_internal.h>
29 #include <package_manager.h>
30 #include <pkgmgr-info.h>
31 #include <pkgmgr_installer.h>
33 #include "common/current_application.h"
34 #include "common/logger.h"
35 #include "common/platform_result.h"
36 #include "common/scope_exit.h"
37 #include "common/task-queue.h"
38 #include "common/tools.h"
40 #include "application/application_instance.h"
41 #include "application/application_utils.h"
43 using namespace common;
44 using namespace tools;
47 namespace application {
50 const std::string kTizenApisFileScheme = "file://";
51 const std::string kTizenApisAppSlash = "/";
52 const std::string kTizenApisAppShared = "shared";
54 const char* kStartKey = PKGMGR_INSTALLER_START_KEY_STR;
55 const char* kEndKey = PKGMGR_INSTALLER_END_KEY_STR;
56 const char* kOkValue = PKGMGR_INSTALLER_OK_EVENT_STR;
57 const char* kInstallEvent = PKGMGR_INSTALLER_INSTALL_EVENT_STR;
58 const char* kUpdateEvent = PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
59 const char* kUninstallEvent = PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
61 const char* kAppidKey = "appid";
63 const std::string kAction = "action";
64 const std::string kCallbackId = "callbackId";
65 const std::string kOnInstalled = "oninstalled";
66 const std::string kOnUpdated = "onupdated";
67 const std::string kOnUninstalled = "onuninstalled";
68 const std::string kData = "data";
69 const std::string kStatusType = "statusType";
70 const std::string kAppId = "appId";
71 const std::string kListenerId = "listenerId";
72 const std::string kAppStatusChangeListener = "AppStatusChangeListener";
73 const std::string kAppUsageModeFrequently = "FREQUENTLY";
74 const std::string kAppUsageModeRecently = "RECENTLY";
76 const std::map<std::string, std::string> event_map_ = {
77 {SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
78 {SYSTEM_EVENT_BATTERY_LEVEL_STATUS, EVENT_KEY_BATTERY_LEVEL_STATUS},
79 {SYSTEM_EVENT_USB_STATUS, EVENT_KEY_USB_STATUS},
80 {SYSTEM_EVENT_EARJACK_STATUS, EVENT_KEY_EARJACK_STATUS},
81 {SYSTEM_EVENT_DISPLAY_STATE, EVENT_KEY_DISPLAY_STATE},
82 {SYSTEM_EVENT_LOW_MEMORY, EVENT_KEY_LOW_MEMORY},
83 {SYSTEM_EVENT_WIFI_STATE, EVENT_KEY_WIFI_STATE},
84 {SYSTEM_EVENT_BT_STATE, EVENT_KEY_BT_STATE},
85 {SYSTEM_EVENT_LOCATION_ENABLE_STATE, EVENT_KEY_LOCATION_ENABLE_STATE},
86 {SYSTEM_EVENT_GPS_ENABLE_STATE, EVENT_KEY_GPS_ENABLE_STATE},
87 {SYSTEM_EVENT_NPS_ENABLE_STATE, EVENT_KEY_NPS_ENABLE_STATE},
88 {SYSTEM_EVENT_INCOMING_MSG, EVENT_KEY_MSG_TYPE},
89 {SYSTEM_EVENT_TIME_ZONE, EVENT_KEY_TIME_ZONE},
90 {SYSTEM_EVENT_HOUR_FORMAT, EVENT_KEY_HOUR_FORMAT},
91 {SYSTEM_EVENT_LANGUAGE_SET, EVENT_KEY_LANGUAGE_SET},
92 {SYSTEM_EVENT_REGION_FORMAT, EVENT_KEY_REGION_FORMAT},
93 {SYSTEM_EVENT_SILENT_MODE, EVENT_KEY_SILENT_MODE},
94 {SYSTEM_EVENT_VIBRATION_STATE, EVENT_KEY_VIBRATION_STATE},
95 {SYSTEM_EVENT_SCREEN_AUTOROTATE_STATE, EVENT_KEY_SCREEN_AUTOROTATE_STATE},
96 {SYSTEM_EVENT_MOBILE_DATA_STATE, EVENT_KEY_MOBILE_DATA_STATE},
97 {SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
98 {SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}};
100 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
101 const int kMaximumBatteryRetrievedObjects = 30;
102 const int kMaximumAppsRetrievedObjects = 10;
103 const int kDefaultPeriodOfTime = 30;
107 ApplicationManager::ApplicationManager(ApplicationInstance& instance)
108 : pkgmgr_client_handle_(nullptr),
109 pkgmgr_client_uninstall_handle_(nullptr),
111 app_status_handle_(nullptr) {
115 ApplicationManager::~ApplicationManager() {
117 StopAppInfoEventListener();
118 StopStatusChangeListener();
120 for (auto it = event_handler_map_.begin(); it != event_handler_map_.end();) {
121 int ret = event_remove_event_handler(it->second);
122 if (EVENT_ERROR_NONE != ret) {
123 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
125 it = event_handler_map_.erase(it);
128 if (app_status_handle_) {
129 int ret = app_manager_event_destroy(app_status_handle_);
130 if (APP_MANAGER_ERROR_NONE != ret) {
131 LoggerE("app_manager_event_destroy failed, error: %d", ret);
136 void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
139 // obtain handle to application info
140 pkgmgrinfo_appinfo_h handle;
141 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
142 if (PMINFO_R_OK != ret) {
143 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app info."), out,
144 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
148 picojson::value app_info = picojson::value(picojson::object());
149 picojson::object& app_info_obj = app_info.get<picojson::object>();
151 ApplicationUtils::CreateApplicationInformation(handle, &app_info_obj);
152 pkgmgrinfo_appinfo_destroy_appinfo(handle);
154 picojson::value result = picojson::value(picojson::object());
155 picojson::object& result_obj = result.get<picojson::object>();
157 result_obj.insert(std::make_pair(
159 picojson::value(std::to_string(CurrentApplication::GetInstance().GetProcessId()))));
160 result_obj.insert(std::make_pair("appInfo", app_info));
162 ReportSuccess(result, *out);
165 class TerminateHandler {
167 TerminateHandler(int callback_id, ApplicationInstance* app_instance)
168 : callback_handle_(callback_id), pid_(-1), timeout_id_(0), app_instance_(app_instance) {
171 void set_pid(pid_t pid) {
179 void Invoke(const std::shared_ptr<picojson::value>& response) {
182 if (timeout_id_ > 0) {
183 // cancel terminate callback
184 g_source_remove(timeout_id_);
188 ApplicationInstance* app_instance = this->app_instance_;
189 int callback_id = this->callback_handle_;
190 TaskQueue::GetInstance().Async<picojson::value>(
191 [callback_id, app_instance](const std::shared_ptr<picojson::value>& response) {
192 picojson::object& obj = response->get<picojson::object>();
194 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
195 Instance::PostMessage(app_instance, response->serialize().c_str());
201 int callback_handle_;
204 ApplicationInstance* app_instance_;
207 #define CHECK_RESULT(result, response, handler) \
208 if (result.IsError()) { \
209 LogAndReportError(result, &response->get<picojson::object>()); \
210 handler->Invoke(response); \
215 void ApplicationManager::AsyncResponse(PlatformResult& result,
216 std::shared_ptr<picojson::value>* response) {
218 LogAndReportError(result, &(*response)->get<picojson::object>());
220 TaskQueue::GetInstance().Async<picojson::value>(
221 [this](const std::shared_ptr<picojson::value>& response) {
222 Instance::PostMessage(&this->instance_, response->serialize().c_str());
227 void ApplicationManager::Kill(const picojson::value& args) {
230 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
232 int callback_id = -1;
233 const auto& callback = args.get(kCallbackId);
234 if (callback.is<double>()) {
235 callback_id = static_cast<int>(callback.get<double>());
238 const auto& context = args.get("contextId");
239 if (!context.is<std::string>()) {
240 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
243 const std::string& context_id = context.get<std::string>();
245 if (context_id.empty() && result.IsSuccess()) {
246 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID is empty.");
249 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
250 picojson::object& obj = response->get<picojson::object>();
251 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
253 if (result.IsError()) {
254 LoggerE("Failed args.get");
255 AsyncResponse(result, &response);
259 auto kill = [this, callback_id, context_id]() -> void {
262 std::shared_ptr<picojson::value> response =
263 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
265 TerminateHandler* handler = new TerminateHandler(callback_id, &this->instance_);
266 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
270 pid = std::stoi(context_id);
272 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
273 CHECK_RESULT(result, response, handler)
277 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID cannot be negative value.");
278 CHECK_RESULT(result, response, handler)
281 // if kill request comes for current context, throw InvalidValuesException
282 if (CurrentApplication::GetInstance().GetProcessId() == pid) {
284 LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Cannot kill current application.");
285 CHECK_RESULT(result, response, handler)
288 LoggerD("Kill, pid: %d", pid);
290 char* app_id = nullptr;
291 int ret = app_manager_get_app_id(pid, &app_id);
292 // automatically release the memory
293 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
295 if (APP_MANAGER_ERROR_NONE != ret) {
296 result = LogAndCreateResult(
297 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
298 ("Failed to get application ID, error: %d (%s)", ret, get_error_message(ret)));
299 CHECK_RESULT(result, response, handler)
302 LoggerD("Kill, app ID: %s", app_id);
304 // acquire application context
305 app_context_h app_context = nullptr;
307 ret = app_manager_get_app_context(app_id, &app_context);
308 std::unique_ptr<std::remove_pointer<app_context_h>::type, int (*)(app_context_h)>
309 app_context_ptr(app_context, &app_context_destroy); // automatically release the memory
311 if (APP_MANAGER_ERROR_NONE != ret) {
312 result = LogAndCreateResult(
313 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
314 ("Failed to get application context handle: %d (%s)", ret, get_error_message(ret)));
315 CHECK_RESULT(result, response, handler)
318 auto terminate_callback = [](app_context_h app_context, app_context_event_e event,
320 LoggerD("terminate_callback: %d", event);
322 if (APP_CONTEXT_EVENT_TERMINATED != event) {
323 LoggerD("ignoring event");
328 int ret = app_context_get_pid(app_context, &pid);
330 if (APP_MANAGER_ERROR_NONE != ret) {
331 LoggerE("Failed to get pid of terminated app: %d (%s)", ret, get_error_message(ret));
335 TerminateHandler* handler = static_cast<TerminateHandler*>(user_data);
337 LoggerD("Expected PID: %d, got: %d", handler->pid(), pid);
339 if (handler->pid() == pid) {
340 std::shared_ptr<picojson::value> response =
341 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
342 ReportSuccess(response->get<picojson::object>());
343 handler->Invoke(response);
348 LoggerD("Kill, setting callback");
349 handler->set_pid(pid);
350 ret = app_manager_set_app_context_event_cb(terminate_callback, handler);
352 if (APP_MANAGER_ERROR_NONE != ret) {
353 result = LogAndCreateResult(
354 ErrorCode::UNKNOWN_ERR, "Failed to register termination callback.",
355 ("Error while registering app context event: %d (%s)", ret, get_error_message(ret)));
356 CHECK_RESULT(result, response, handler)
359 LoggerD("Kill, calling native function");
361 // terminate application
362 ret = app_manager_terminate_app(app_context);
364 if (APP_MANAGER_ERROR_NONE != ret) {
365 result = LogAndCreateResult(
366 ErrorCode::UNKNOWN_ERR, "Failed to terminate application.",
367 ("Failed to terminate application: %d (%s)", ret, get_error_message(ret)));
368 CHECK_RESULT(result, response, handler)
371 LoggerD("Kill, end, waiting for notification");
377 void ApplicationManager::Launch(const picojson::value& args) {
380 int callback_id = -1;
381 const auto& callback = args.get(kCallbackId);
382 if (callback.is<double>()) {
383 callback_id = static_cast<int>(callback.get<double>());
386 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
387 picojson::object& obj = response->get<picojson::object>();
388 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
390 const auto& app_id = args.get("id");
391 if (!app_id.is<std::string>()) {
393 LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
394 AsyncResponse(ret, &response);
397 const std::string& id = app_id.get<std::string>();
399 auto launch = [id](const std::shared_ptr<picojson::value>& response) -> void {
400 ScopeLogger("launch");
401 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
402 const char* app_id = id.c_str();
403 const int retry_count = 3;
408 while (retry < retry_count) {
409 ret = aul_open_app(app_id);
415 // delay 300ms for each retry
416 struct timespec sleep_time = {0, 300L * 1000L * 1000L};
417 nanosleep(&sleep_time, nullptr);
420 LoggerD("Retry launch request: %d", retry);
424 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error has occurred.");
426 LoggerD("Aul open return: %d (%s)", ret, get_error_message(ret));
432 LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Launchpad returns not found error.",
433 ("aul_open_app returns Not Found error"));
437 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Internal IPC error has occurred.",
438 ("aul_open_app returns internal IPC error"));
442 LogAndReportError(result, &response->get<picojson::object>());
444 LoggerD("Launch request success");
445 ReportSuccess(response->get<picojson::object>());
450 Instance::PostMessage(&this->instance_, response->serialize().c_str());
453 void ApplicationManager::LaunchAppControl(const picojson::value& args) {
456 int callback_id = -1;
457 const auto& callback = args.get(kCallbackId);
458 if (callback.is<double>()) {
459 callback_id = static_cast<int>(callback.get<double>());
462 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
463 picojson::object& response_obj = response->get<picojson::object>();
465 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
467 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
468 const auto& control = args.get("appControl");
469 if (!control.is<picojson::object>()) {
470 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
471 AsyncResponse(result, &response);
474 const picojson::object& app_control_obj = control.get<picojson::object>();
476 std::string launch_mode_str;
477 const auto& launch_mode = control.get("launchMode");
478 if (launch_mode.is<std::string>()) {
479 launch_mode_str = launch_mode.get<std::string>();
482 app_control_h app_control = nullptr;
483 result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
484 std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
485 app_control, &app_control_destroy); // automatically release the memory
487 if (result.IsError()) {
488 LoggerE("Application control to service failed.");
489 AsyncResponse(result, &response);
494 const auto& id = args.get("id");
495 if (id.is<std::string>()) {
496 app_id = id.get<std::string>();
499 std::string reply_callback;
500 const auto& reply = args.get("replyCallback");
501 if (reply.is<std::string>()) {
502 reply_callback = reply.get<std::string>();
505 auto launch = [this, app_control_ptr, app_id, launch_mode_str,
506 reply_callback](const std::shared_ptr<picojson::value>& response) -> void {
507 ScopeLogger("Entered into asynchronous function, launch");
509 if (!app_id.empty()) {
510 LoggerD("app_id: %s", app_id.c_str());
512 int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
514 if (APP_CONTROL_ERROR_NONE != ret) {
516 PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
517 &response->get<picojson::object>(),
518 ("Failed to set app id: %d (%s)", ret, get_error_message(ret)));
523 if (!launch_mode_str.empty()) {
524 app_control_launch_mode_e launch_mode;
526 if ("SINGLE" == launch_mode_str) {
527 launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
528 } else if ("GROUP" == launch_mode_str) {
529 launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP;
531 ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
532 &response->get<picojson::object>());
536 int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode);
537 if (APP_CONTROL_ERROR_NONE != ret) {
538 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."),
539 &response->get<picojson::object>(),
540 ("Setting launch mode failed: %d (%s)", ret, get_error_message(ret)));
545 app_control_reply_cb callback = nullptr;
546 struct ReplayCallbackData {
547 ApplicationInstance* app_instance;
548 std::string reply_callback;
551 ReplayCallbackData* user_data = nullptr;
553 if (!reply_callback.empty()) {
554 user_data = new ReplayCallbackData();
555 user_data->app_instance = &this->instance_;
556 user_data->reply_callback = reply_callback;
558 callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
560 LoggerD("send_launch_request callback");
562 picojson::value return_value = picojson::value(picojson::object());
563 picojson::object& return_value_obj = return_value.get<picojson::object>();
564 ReplayCallbackData* reply_callback = static_cast<ReplayCallbackData*>(user_data);
566 if (APP_CONTROL_RESULT_SUCCEEDED == result) {
567 const std::string data = "data";
568 return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array())));
569 if (!ApplicationUtils::ServiceToApplicationControlDataArray(
570 reply, &return_value_obj.find(data)->second.get<picojson::array>())) {
571 return_value_obj.erase(data);
573 ReportSuccess(return_value_obj);
575 ReportError(return_value_obj);
578 return_value_obj.insert(
579 std::make_pair("listenerId", picojson::value(reply_callback->reply_callback)));
580 Instance::PostMessage(reply_callback->app_instance, return_value.serialize().c_str());
581 delete reply_callback;
585 const int retry_count = 3;
590 while (retry < retry_count) {
591 LoggerD("Calling launch request. Attempt number: %d", retry);
593 ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data);
594 LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret));
595 if (APP_CONTROL_ERROR_NONE == ret) {
599 // delay 300ms for each retry
600 struct timespec sleep_time = {0, 300L * 1000L * 1000L};
601 nanosleep(&sleep_time, nullptr);
605 if (APP_CONTROL_ERROR_NONE != ret) {
609 case APP_CONTROL_ERROR_INVALID_PARAMETER:
611 PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."),
612 &response->get<picojson::object>(),
613 ("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER"));
615 case APP_CONTROL_ERROR_OUT_OF_MEMORY:
617 PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."),
618 &response->get<picojson::object>(),
619 ("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY"));
621 case APP_CONTROL_ERROR_LAUNCH_REJECTED:
622 case APP_CONTROL_ERROR_APP_NOT_FOUND:
624 PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."),
625 &response->get<picojson::object>(),
626 ("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND"));
630 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."),
631 &response->get<picojson::object>(),
632 ("app_control_send_launch_request returns: %d (%s)", ret, get_error_message(ret)));
636 ReportSuccess(response->get<picojson::object>());
640 Instance::PostMessage(&this->instance_, response->serialize().c_str());
643 // internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
644 // public CAPI did not handling APP_CONTROL_ERROR_APP_NOT_FOUND
645 int app_control_foreach_app_matched_internal(app_control_h app_control,
646 app_control_app_matched_cb callback, void* user_data) {
649 app_control_h app_control;
650 app_control_app_matched_cb callback;
653 } foreach_context_launchable_app_t_internal;
655 // internal impl of app_control_cb_broker_foreach_app_matched()
656 auto app_control_cb_broker_foreach_app_matched_internal = [](const char* package,
659 "Entered into asynchronous function, app_control_cb_broker_foreach_app_matched_internal's "
661 foreach_context_launchable_app_t_internal* foreach_context;
662 app_control_app_matched_cb app_matched_cb;
664 if (package == NULL || data == NULL) {
665 LoggerE("APP_CONTROL_ERROR_INVALID_PARAMETER");
669 foreach_context = (foreach_context_launchable_app_t_internal*)data;
670 if (foreach_context->foreach_break == true) return -1;
672 app_matched_cb = foreach_context->callback;
673 if (app_matched_cb != NULL) {
674 bool stop_foreach = false;
677 !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
679 foreach_context->foreach_break = stop_foreach;
685 foreach_context_launchable_app_t_internal foreach_context = {.app_control = app_control,
686 .callback = callback,
687 .user_data = user_data,
688 .foreach_break = false};
690 bundle* bundle_data = NULL;
691 app_control_to_bundle(app_control, &bundle_data);
693 int ret = appsvc_usr_get_list(bundle_data, app_control_cb_broker_foreach_app_matched_internal,
694 &foreach_context, getuid());
698 case APPSVC_RET_EINVAL:
699 return APP_CONTROL_ERROR_INVALID_PARAMETER;
701 case APPSVC_RET_ENOMATCH:
702 return APP_CONTROL_ERROR_APP_NOT_FOUND;
705 return APP_CONTROL_ERROR_LAUNCH_FAILED;
709 return APP_CONTROL_ERROR_NONE;
712 void ApplicationManager::FindAppControl(const picojson::value& args) {
715 int callback_id = -1;
716 const auto& callback = args.get(kCallbackId);
717 if (callback.is<double>()) {
718 callback_id = static_cast<int>(callback.get<double>());
721 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
722 picojson::object& response_obj = response->get<picojson::object>();
724 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
726 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
727 const auto& control = args.get("appControl");
728 if (!control.is<picojson::object>()) {
729 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
730 AsyncResponse(result, &response);
734 const picojson::object& app_control_obj = control.get<picojson::object>();
736 app_control_h app_control = nullptr;
737 result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
738 std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
739 app_control, &app_control_destroy); // automatically release the memory
741 if (result.IsError()) {
742 LoggerE("Application control to service failed.");
743 AsyncResponse(result, &response);
747 auto find = [app_control_ptr](const std::shared_ptr<picojson::value>& response) -> void {
748 ScopeLogger("Entered into asynchronous function, find");
749 auto app_control_matched = [](app_control_h app_control, const char* appid,
750 void* user_data) -> bool {
751 ScopeLogger("Entered into asynchronous function, app_control_matched");
752 if (nullptr == appid) {
753 LoggerD("appid is NULL");
757 pkgmgrinfo_appinfo_h handle;
758 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &handle);
759 if (PMINFO_R_OK != ret) {
760 LoggerE("Failed to get appInfo: %d (%s)", ret, get_error_message(ret));
762 picojson::array* array = static_cast<picojson::array*>(user_data);
763 array->push_back(picojson::value(picojson::object()));
765 ApplicationUtils::CreateApplicationInformation(handle,
766 &array->back().get<picojson::object>());
767 pkgmgrinfo_appinfo_destroy_appinfo(handle);
773 picojson::object& response_obj = response->get<picojson::object>();
774 auto it_result = response_obj.find("result");
775 picojson::object& result_obj = it_result->second.get<picojson::object>();
777 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())));
779 int ret = app_control_foreach_app_matched_internal(app_control_ptr.get(), app_control_matched,
780 &array.first->second.get<picojson::array>());
782 if (APP_CONTROL_ERROR_NONE != ret) {
783 if (APP_CONTROL_ERROR_APP_NOT_FOUND == ret) {
784 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Matched Application not found"),
785 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
786 get_error_message(ret)));
787 } else if (APP_CONTROL_ERROR_LAUNCH_FAILED == ret) {
789 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error"), &response_obj,
790 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
791 } else if (APP_CONTROL_ERROR_INVALID_PARAMETER == ret) {
792 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed"),
793 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
794 get_error_message(ret)));
796 // remove copied ApplicationControl from result
797 response_obj.erase(it_result);
799 ReportSuccess(response_obj);
803 auto find_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
804 ScopeLogger("Entered into asynchronous function, find_response");
805 Instance::PostMessage(&this->instance_, response->serialize().c_str());
808 // prepare result object, we need to do that here, as input parameter is passed to result callback
809 auto ret = response_obj.insert(std::make_pair("result", picojson::value(picojson::object())));
810 // reinsert application control
811 ret.first->second.get<picojson::object>().insert(
812 std::make_pair("appControl", args.get("appControl")));
814 TaskQueue::GetInstance().Queue<picojson::value>(find, find_response, response);
817 void ApplicationManager::GetAppsContext(const picojson::value& args) {
820 int callback_id = -1;
821 const auto& callback = args.get(kCallbackId);
822 if (callback.is<double>()) {
823 callback_id = static_cast<int>(callback.get<double>());
826 auto get_apps_context = [](const std::shared_ptr<picojson::value>& response) -> void {
827 picojson::object& response_obj = response->get<picojson::object>();
828 picojson::value result = picojson::value(picojson::object());
829 picojson::object& result_obj = result.get<picojson::object>();
830 picojson::array& array =
831 result_obj.insert(std::make_pair("contexts", picojson::value(picojson::array())))
832 .first->second.get<picojson::array>();
834 auto app_context_cb = [](app_context_h app_context, void* user_data) -> bool {
835 if (nullptr == user_data) {
839 picojson::array* array = static_cast<picojson::array*>(user_data);
840 array->push_back(picojson::value(picojson::object()));
842 if (!ApplicationUtils::CreateApplicationContext(app_context,
843 &array->back().get<picojson::object>())) {
851 int ret = app_manager_foreach_app_context(app_context_cb, &array);
853 if (APP_MANAGER_ERROR_NONE != ret) {
855 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
856 ("app_manager_foreach_app_context error: %d (%s)", ret, get_error_message(ret)));
858 ReportSuccess(result, response_obj);
862 auto get_apps_context_response =
863 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
864 picojson::object& obj = response->get<picojson::object>();
865 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
866 Instance::PostMessage(&this->instance_, response->serialize().c_str());
869 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
871 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_context, get_apps_context_response,
875 void ApplicationManager::GetAppContext(const picojson::value& args, picojson::object* out) {
879 const auto& context_id = args.get("contextId");
880 if (context_id.is<std::string>()) {
882 pid = std::stoi(context_id.get<std::string>());
884 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert context id."),
889 pid = CurrentApplication::GetInstance().GetProcessId();
892 char* app_id = nullptr;
894 int ret = app_manager_get_app_id(pid, &app_id);
895 // automatically release the memory
896 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
898 if (APP_MANAGER_ERROR_NONE != ret || nullptr == app_id) {
900 case APP_MANAGER_ERROR_NO_SUCH_APP:
901 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "No such application exist."), out,
902 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_NO_SUCH_APP"));
905 case APP_MANAGER_ERROR_INVALID_PARAMETER:
906 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Application not found."), out,
907 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_INVALID_PARAMETER"));
912 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), out,
913 ("app_manager_get_app_id returned: %d (%s)", ret, get_error_message(ret)));
918 picojson::value result = picojson::value(picojson::object());
919 ApplicationUtils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
921 ReportSuccess(result, *out);
924 void ApplicationManager::GetAppsInfo(const picojson::value& args) {
927 int callback_id = -1;
928 const auto& callback = args.get(kCallbackId);
929 if (callback.is<double>()) {
930 callback_id = static_cast<int>(callback.get<double>());
933 auto get_apps_info = [](const std::shared_ptr<picojson::value>& response) -> void {
934 ScopeLogger("Entered into asynchronous function, get_apps_info");
935 picojson::object& response_obj = response->get<picojson::object>();
936 picojson::value result = picojson::value(picojson::object());
937 picojson::object& result_obj = result.get<picojson::object>();
938 picojson::array& array =
939 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())))
940 .first->second.get<picojson::array>();
942 auto app_info_cb = [](pkgmgrinfo_appinfo_h handle, void* user_data) -> int {
943 ScopeLogger("Entered into asynchronous function, app_info_cb");
944 if (nullptr == user_data) {
948 picojson::array* array = static_cast<picojson::array*>(user_data);
949 array->push_back(picojson::value(picojson::object()));
951 ApplicationUtils::CreateApplicationInformation(handle,
952 &array->back().get<picojson::object>());
957 int ret = pkgmgrinfo_appinfo_get_usr_installed_list(app_info_cb, getuid(), &array);
959 if (APP_MANAGER_ERROR_NONE != ret) {
960 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
961 ("pkgmgrinfo_appinfo_get_usr_installed_list error"));
963 ReportSuccess(result, response_obj);
967 auto get_apps_info_response =
968 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
969 ScopeLogger("Entered into asynchronous function, get_apps_info_response");
970 picojson::object& obj = response->get<picojson::object>();
971 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
972 Instance::PostMessage(&this->instance_, response->serialize().c_str());
975 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
977 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_info, get_apps_info_response, data);
980 void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object* out) {
983 pkgmgrinfo_appinfo_h handle = nullptr;
985 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
986 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out);
990 picojson::value result = picojson::value(picojson::object());
991 ApplicationUtils::CreateApplicationInformation(handle, &result.get<picojson::object>());
992 pkgmgrinfo_appinfo_destroy_appinfo(handle);
994 ReportSuccess(result, *out);
997 char* ApplicationManager::GetPackageId(const std::string& app_id) {
1000 char* pkg_id = nullptr;
1002 int ret = app_manager_get_app_info(app_id.c_str(), &handle);
1003 if (APP_MANAGER_ERROR_NONE != ret) {
1004 LoggerE("Failed to get app info: %d (%s)", ret, get_error_message(ret));
1008 ret = app_info_get_package(handle, &pkg_id);
1009 if (APP_MANAGER_ERROR_NONE != ret) {
1010 LoggerE("Failed to get package id: %d (%s)", ret, get_error_message(ret));
1014 ret = app_info_destroy(handle);
1015 if (APP_MANAGER_ERROR_NONE != ret) {
1016 LoggerE("Failed to destroy app info: %d (%s)", ret, get_error_message(ret));
1022 void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object* out) {
1025 char* package_id = nullptr;
1027 package_id = GetPackageId(app_id);
1028 // automatically release the memory
1029 std::unique_ptr<char, void (*)(void*)> package_id_ptr(package_id, &std::free);
1032 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1036 package_info_h pkg_info = nullptr;
1037 int ret = package_info_create(package_id, &pkg_info);
1039 std::unique_ptr<std::remove_pointer<package_info_h>::type, int (*)(package_info_h)> pkg_info_ptr(
1040 pkg_info, &package_info_destroy); // automatically release the memory
1042 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1043 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1044 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1048 auto cert_info_cb = [](package_info_h handle, package_cert_type_e cert_type,
1049 const char* cert_value, void* user_data) -> bool {
1050 const char* cert_name = nullptr;
1052 switch (cert_type) {
1053 case PACKAGE_INFO_AUTHOR_ROOT_CERT:
1054 cert_name = "AUTHOR_ROOT";
1056 case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT:
1057 cert_name = "AUTHOR_INTERMEDIATE";
1059 case PACKAGE_INFO_AUTHOR_SIGNER_CERT:
1060 cert_name = "AUTHOR_SIGNER";
1062 case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT:
1063 cert_name = "DISTRIBUTOR_ROOT";
1065 case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT:
1066 cert_name = "DISTRIBUTOR_INTERMEDIATE";
1068 case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT:
1069 cert_name = "DISTRIBUTOR_SIGNER";
1071 case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT:
1072 cert_name = "DISTRIBUTOR2_ROOT";
1074 case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT:
1075 cert_name = "DISTRIBUTOR2_INTERMEDIATE";
1077 case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT:
1078 cert_name = "DISTRIBUTOR2_SIGNER";
1081 LoggerD("Unknown certificate type: %d", cert_type);
1085 picojson::array* array = static_cast<picojson::array*>(user_data);
1086 array->push_back(picojson::value(picojson::object()));
1088 ApplicationUtils::CreateApplicationCertificate(cert_name, cert_value,
1089 &array->back().get<picojson::object>());
1094 picojson::value result = picojson::value(picojson::array());
1096 ret = package_info_foreach_cert_info(pkg_info, cert_info_cb, &result.get<picojson::array>());
1098 if ((PACKAGE_MANAGER_ERROR_NONE != ret) && (PACKAGE_MANAGER_ERROR_IO_ERROR != ret)) {
1099 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get certificates info."),
1101 ("Failed to get certificates info: %d (%s)", ret, get_error_message(ret)));
1105 ReportSuccess(result, *out);
1108 void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::object* out) {
1111 char* package_id = nullptr;
1113 package_id = GetPackageId(app_id);
1114 // automatically release the memory
1115 std::unique_ptr<char, void (*)(void*)> package_id_ptr(package_id, &std::free);
1118 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1122 pkgmgrinfo_pkginfo_h pkg_info = nullptr;
1124 int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(package_id, getuid(), &pkg_info);
1125 std::unique_ptr<std::remove_pointer<pkgmgrinfo_pkginfo_h>::type, int (*)(pkgmgrinfo_pkginfo_h)>
1126 pkg_info_ptr(pkg_info,
1127 &pkgmgrinfo_pkginfo_destroy_pkginfo); // automatically release the memory
1129 if (PMINFO_R_OK != ret) {
1130 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1131 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1135 char* root_path = nullptr;
1136 ret = pkgmgrinfo_pkginfo_get_root_path(pkg_info, &root_path);
1138 if (PMINFO_R_OK != ret || nullptr == root_path) {
1139 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get root path."), out,
1140 ("Failed to get root path: %d (%s)", ret, get_error_message(ret)));
1144 picojson::value result = picojson::value(kTizenApisFileScheme + root_path + kTizenApisAppSlash +
1145 kTizenApisAppShared + kTizenApisAppSlash);
1146 ReportSuccess(result, *out);
1149 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1150 PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args,
1151 const context_history_filter_h filter,
1152 context_history_data_e* data_type_out) {
1154 int ret = CONTEXT_HISTORY_ERROR_NONE;
1155 int limit = kMaximumBatteryRetrievedObjects;
1156 if (args.contains("limit")) {
1157 limit = static_cast<int>(args.get("limit").get<double>());
1160 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1162 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1163 return LogAndCreateResult(
1164 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1165 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1168 context_history_data_e data_type_in = CONTEXT_HISTORY_RECENT_BATTERY_USAGE;
1170 if (args.contains("days")) {
1171 const int days = static_cast<int>(args.get("days").get<double>());
1172 data_type_in = CONTEXT_HISTORY_BATTERY_USAGE;
1173 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, days);
1175 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1176 return LogAndCreateResult(
1177 ErrorCode::INVALID_VALUES_ERR, "days given with invalid value.",
1178 ("days given with invalid value: %d (%s)", ret, get_error_message(ret)));
1182 *data_type_out = data_type_in;
1184 return PlatformResult(ErrorCode::NO_ERROR);
1187 PlatformResult ApplicationManager::BatteryUsageAttributes(const context_history_record_h record,
1188 picojson::object* object) {
1191 int ret = CONTEXT_HISTORY_ERROR_NONE;
1192 double amount = 0.0;
1193 char* app_id = nullptr;
1198 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1199 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1200 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1201 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1204 ret = context_history_record_get_double(record, CONTEXT_HISTORY_TOTAL_AMOUNT, &amount);
1205 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1206 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get amount.",
1207 ("Failed to get amount: %d (%s)", ret, get_error_message(ret)));
1210 object->insert(std::make_pair("appId", picojson::value(app_id)));
1211 object->insert(std::make_pair("batteryUsage", picojson::value(amount)));
1213 return PlatformResult(ErrorCode::NO_ERROR);
1216 PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
1217 const context_history_filter_h filter,
1218 context_history_data_e* data_type_out) {
1220 int ret = CONTEXT_HISTORY_ERROR_NONE;
1221 int limit = kMaximumAppsRetrievedObjects;
1222 if (args.contains("limit")) {
1223 limit = static_cast<int>(args.get("limit").get<double>());
1226 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1227 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1228 return LogAndCreateResult(
1229 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1230 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1233 context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
1234 if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
1235 data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
1238 int time_span = kDefaultPeriodOfTime;
1239 const picojson::object& JS_filter = args.get("filter").get<picojson::object>();
1240 auto time_span_iter = JS_filter.find("timeSpan");
1241 if (JS_filter.end() != time_span_iter || (JS_filter.end() == JS_filter.find("startTime") &&
1242 JS_filter.end() == JS_filter.find("endTime"))) {
1243 // In the second case, we treat the filter object just like an empty object.
1244 // The default value of filter will be used instead.
1245 if (JS_filter.end() != time_span_iter) {
1246 time_span = static_cast<int>(time_span_iter->second.get<double>());
1248 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
1249 // context_history_filter_set_int may return only success or
1250 // CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
1251 // Although this should never happen, it's better to check ret's value
1252 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1253 return LogAndCreateResult(ErrorCode::ABORT_ERR,
1254 "Error while setting the default TIME_SPAN value.",
1255 ("Error while setting the default TIME_SPAN value: %d (%s)", ret,
1256 get_error_message(ret)));
1259 auto start_time_iter = JS_filter.find("startTime");
1260 auto end_time_iter = JS_filter.find("endTime");
1261 if (start_time_iter != JS_filter.end()) {
1262 int start_time = static_cast<int>(start_time_iter->second.get<double>());
1263 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
1264 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1265 return LogAndCreateResult(
1266 ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
1267 ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1270 if (end_time_iter != JS_filter.end()) {
1271 int end_time = static_cast<int>(end_time_iter->second.get<double>());
1272 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
1273 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1274 return LogAndCreateResult(
1275 ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
1276 ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1281 *data_type_out = data_type_in;
1283 return PlatformResult(ErrorCode::NO_ERROR);
1286 PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
1287 picojson::object* object) {
1290 int ret = CONTEXT_HISTORY_ERROR_NONE;
1291 int total_count = 0;
1292 int total_duration = 0;
1294 char* app_id = nullptr;
1299 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1300 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1301 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1302 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1305 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
1306 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1307 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
1308 ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
1311 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
1312 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1313 return LogAndCreateResult(
1314 ErrorCode::ABORT_ERR, "Failed to get total duration.",
1315 ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
1318 ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
1319 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1320 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
1321 ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
1324 object->insert(std::make_pair("appId", picojson::value(app_id)));
1325 object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
1327 std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
1328 object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
1330 return PlatformResult(ErrorCode::NO_ERROR);
1334 void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
1337 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1338 int callback_id = -1;
1339 const auto& callback = args.get(kCallbackId);
1340 if (callback.is<double>()) {
1341 callback_id = static_cast<int>(callback.get<double>());
1344 auto get_battery_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1346 PlatformResult result = ApplicationManager::GetContextHistory(
1347 args, &response.get()->get<picojson::object>(), &ApplicationManager::BatteryUsageFilter,
1348 &ApplicationManager::BatteryUsageAttributes);
1350 LogAndReportError(result, &response.get()->get<picojson::object>());
1354 auto get_battery_usage_response =
1355 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1357 picojson::object& obj = response->get<picojson::object>();
1358 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1359 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1362 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1364 TaskQueue::GetInstance().Queue<picojson::value>(get_battery_usage, get_battery_usage_response,
1367 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1368 "This feature is not supported on this profile."),
1369 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1373 void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
1376 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1377 int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
1379 auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1381 PlatformResult result = ApplicationManager::GetContextHistory(
1382 args, &response.get()->get<picojson::object>(), &ApplicationManager::AppsUsageFilter,
1383 &ApplicationManager::AppsUsageAttributes);
1385 LogAndReportError(result, &response.get()->get<picojson::object>());
1389 auto get_apps_usage_response =
1390 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1392 picojson::object& obj = response->get<picojson::object>();
1393 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1394 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1397 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1399 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_usage, get_apps_usage_response, data);
1401 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1402 "This feature is not supported on this profile."),
1403 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1407 void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
1410 pkgmgrinfo_appinfo_h handle = nullptr;
1412 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
1413 std::unique_ptr<std::remove_pointer<pkgmgrinfo_appinfo_h>::type, int (*)(pkgmgrinfo_appinfo_h)>
1414 pkg_info_ptr(handle,
1415 &pkgmgrinfo_appinfo_destroy_appinfo); // automatically release the memory
1417 if (PMINFO_R_OK != ret) {
1418 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out,
1419 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
1423 auto meta_data_cb = [](const char* meta_key, const char* meta_value, void* user_data) -> int {
1424 if (nullptr == meta_key || nullptr == meta_value) {
1425 LoggerE("meta_key or meta_value is null");
1429 picojson::array* array = static_cast<picojson::array*>(user_data);
1430 array->push_back(picojson::value(picojson::object()));
1432 ApplicationUtils::CreateApplicationMetaData(meta_key, meta_value,
1433 &array->back().get<picojson::object>());
1437 picojson::value result = picojson::value(picojson::array());
1438 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, meta_data_cb, &result.get<picojson::array>());
1440 if (PMINFO_R_OK != ret) {
1441 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get metadata."), out,
1442 ("Failed to get metadata: %d (%s)", ret, get_error_message(ret)));
1446 ReportSuccess(result, *out);
1449 class ApplicationListChangedBroker {
1451 ApplicationListChangedBroker() : event_type_() {
1459 static int ClientStatusListener(unsigned int target_uid, int id, const char* type,
1460 const char* package, const char* key, const char* val,
1461 const void* msg, void* data) {
1463 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1465 if (0 == strcasecmp(key, kStartKey)) {
1466 that->HandleStart(val, package);
1467 } else if (0 == strcasecmp(key, kEndKey) && 0 == strcasecmp(val, kOkValue)) {
1468 that->HandleEnd(package);
1470 LoggerD("Ignored key: %s", key);
1476 static int AppUninstallListener(uid_t target_uid, int id, const char* type, const char* package,
1477 const char* key, const char* val, const void* msg, void* data) {
1480 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1482 if (0 == strcasecmp(key, kStartKey)) {
1483 that->HandleUninstallStart();
1484 } else if (0 == strcasecmp(key, kAppidKey)) {
1485 that->AddUninstalledAppId(val);
1486 } else if (0 == strcasecmp(key, kEndKey)) {
1487 that->HandleUninstallEnd();
1489 LoggerD("Ignored key: %s", key);
1495 void AddApplicationInstance(ApplicationInstance* app_instance) {
1497 app_instance_list_.push_back(app_instance);
1500 void RemoveApplicationInstance(ApplicationInstance* app_instance) {
1502 for (auto it = app_instance_list_.begin(); it != app_instance_list_.end(); it++) {
1503 if (*it == app_instance) {
1504 app_instance_list_.erase(it);
1511 void HandleStart(const char* event_type, const char* package) {
1514 set_event_type(event_type);
1517 void HandleEnd(const char* package) {
1520 if (Event::kUninstalled == event_type_) {
1524 GetApplicationIdsFromPackage(package);
1526 for (auto& app_id : app_list_) {
1527 picojson::value value = picojson::value(picojson::object());
1528 picojson::object& data_obj = value.get<picojson::object>();
1530 switch (event_type_) {
1531 case Event::kInstalled:
1532 data_obj.insert(std::make_pair(kAction, picojson::value(kOnInstalled)));
1535 case Event::kUpdated:
1536 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUpdated)));
1538 case Event::kUninstalled:
1539 LoggerD("Uninstalled called");
1543 switch (event_type_) {
1544 case Event::kInstalled:
1545 case Event::kUpdated: {
1546 pkgmgrinfo_appinfo_h handle = nullptr;
1548 pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1549 LoggerE("Failed to get application information handle.");
1552 auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object())));
1553 ApplicationUtils::CreateApplicationInformation(
1554 handle, &info.first->second.get<picojson::object>());
1555 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1557 case Event::kUninstalled:
1558 LoggerD("Uninstalled called");
1562 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1564 for (auto instance : app_instance_list_) {
1565 Instance::PostMessage(instance, value.serialize().c_str());
1570 void GetApplicationIdsFromPackage(const char* package) {
1572 package_info_h package_info = nullptr;
1574 int ret = package_info_create(package, &package_info);
1575 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1576 LoggerE("Failed to create package info: %d (%s)", ret, get_error_message(ret));
1580 ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_ALLAPP,
1581 ApplicationIdCallback, this);
1582 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1583 LoggerE("Failed to get application IDs: %d (%s)", ret, get_error_message(ret));
1586 ret = package_info_destroy(package_info);
1587 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1588 LoggerE("Failed to destroy package info: %d (%s)", ret, get_error_message(ret));
1592 void set_event_type(const char* type) {
1594 if (0 == strcasecmp(type, kInstallEvent)) {
1595 event_type_ = Event::kInstalled;
1596 } else if (0 == strcasecmp(type, kUpdateEvent)) {
1597 event_type_ = Event::kUpdated;
1598 } else if (0 == strcasecmp(type, kUninstallEvent)) {
1599 event_type_ = Event::kUninstalled;
1603 static bool ApplicationIdCallback(package_info_app_component_type_e comp_type, const char* app_id,
1606 if (nullptr != app_id) {
1607 static_cast<ApplicationListChangedBroker*>(user_data)->app_list_.push_back(app_id);
1612 void HandleUninstallStart() {
1615 set_event_type(kUninstallEvent);
1618 void AddUninstalledAppId(const char* app_id) {
1620 if (nullptr != app_id) {
1621 app_list_.push_back(app_id);
1625 void HandleUninstallEnd() {
1627 for (auto& app_id : app_list_) {
1628 picojson::value value = picojson::value(picojson::object());
1629 picojson::object& data_obj = value.get<picojson::object>();
1631 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUninstalled)));
1632 data_obj.insert(std::make_pair(kData, picojson::value(app_id)));
1634 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1636 for (auto instance : app_instance_list_) {
1637 Instance::PostMessage(instance, value.serialize().c_str());
1643 std::vector<std::string> app_list_;
1644 std::vector<ApplicationInstance*> app_instance_list_;
1647 static ApplicationListChangedBroker g_application_list_changed_broker;
1649 void ApplicationManager::StartAppInfoEventListener(picojson::object* out) {
1652 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1653 if (nullptr == pkgmgr_client_handle_) {
1654 pkgmgr_client_handle_ = pkgmgr_client_new(PC_LISTENING);
1656 if (nullptr == pkgmgr_client_uninstall_handle_) {
1657 pkgmgr_client_uninstall_handle_ = pkgmgr_client_new(PC_LISTENING);
1660 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1661 if (nullptr != pkgmgr_client_handle_) {
1662 pkgmgr_client_free(pkgmgr_client_handle_);
1663 pkgmgr_client_handle_ = nullptr;
1665 if (nullptr != pkgmgr_client_uninstall_handle_) {
1666 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1667 pkgmgr_client_uninstall_handle_ = nullptr;
1669 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."),
1674 #define CHECK_APPLICATION_EVENT_ERROR(result, function_name) \
1675 if (PKGMGR_R_OK > result) { \
1676 StopAppInfoEventListener(); \
1677 LogAndReportError( \
1678 PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."), out, \
1679 ("Function %s failed: %s (%d)", function_name, get_error_message(result), result)); \
1683 g_application_list_changed_broker.AddApplicationInstance(&instance_);
1685 int result = pkgmgr_client_set_status_type(
1686 pkgmgr_client_handle_,
1687 PACKAGE_MANAGER_STATUS_TYPE_INSTALL | PACKAGE_MANAGER_STATUS_TYPE_UPGRADE);
1688 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1690 result = pkgmgr_client_set_status_type(pkgmgr_client_uninstall_handle_,
1691 PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL);
1692 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1694 result = pkgmgr_client_listen_status(pkgmgr_client_handle_,
1695 ApplicationListChangedBroker::ClientStatusListener,
1696 &g_application_list_changed_broker);
1697 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1699 result = pkgmgr_client_listen_status(pkgmgr_client_uninstall_handle_,
1700 ApplicationListChangedBroker::AppUninstallListener,
1701 &g_application_list_changed_broker);
1702 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1704 #undef CHECK_APPLICATION_EVENT_ERROR
1706 LoggerD("Broker callback is already registered.");
1709 ReportSuccess(*out);
1712 void ApplicationManager::StopAppInfoEventListener() {
1715 if (nullptr != pkgmgr_client_handle_ || nullptr != pkgmgr_client_uninstall_handle_) {
1716 if (nullptr != pkgmgr_client_handle_) {
1717 pkgmgr_client_free(pkgmgr_client_handle_);
1718 pkgmgr_client_handle_ = nullptr;
1720 if (nullptr != pkgmgr_client_uninstall_handle_) {
1721 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1722 pkgmgr_client_uninstall_handle_ = nullptr;
1724 g_application_list_changed_broker.RemoveApplicationInstance(&instance_);
1726 LoggerD("Broker callback is already unregistered.");
1730 void ApplicationManager::GetApplicationInformationSize(const picojson::value& args,
1731 picojson::object* out) {
1734 const auto& package_id = args.get("packageId");
1735 if (!package_id.is<std::string>()) {
1736 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
1741 const std::string& package_id_str = package_id.get<std::string>();
1743 // get installed size from package server (to solve smack issue)
1744 pkgmgr_client* pc = pkgmgr_client_new(PC_REQUEST);
1747 if (nullptr == pc) {
1748 LoggerE("Failed to create pkgmgr client");
1750 size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL,
1751 package_id_str.c_str(), NULL, NULL, NULL);
1754 LoggerE("Failed to get installed size: %d (%s)", size, get_error_message(size));
1757 pkgmgr_client_free(pc);
1760 picojson::value result = picojson::value(picojson::object());
1761 picojson::object& result_obj = result.get<picojson::object>();
1762 result_obj.insert(std::make_pair("size", picojson::value(static_cast<double>(size))));
1764 ReportSuccess(result, *out);
1767 void ApplicationManager::BroadcastEventHelper(const picojson::value& args, picojson::object& out,
1772 std::string event_str = args.get("name").get<std::string>();
1773 const char* event_name = event_str.c_str();
1775 bundle* data = bundle_create();
1780 ret = bundle_add(data, "data", args.get("data").serialize().c_str());
1782 if (ret != EVENT_ERROR_NONE) {
1783 LoggerE("bundle_add failed, error: %d (%s)", ret, get_error_message(ret));
1789 ret = event_publish_trusted_app_event(event_name, data);
1791 ret = event_publish_app_event(event_name, data);
1794 if (ret == EVENT_ERROR_NONE) {
1797 LoggerE("event_publish_app_event failed, error: %d (%s)", ret, get_error_message(ret));
1802 void ApplicationManager::OnEvent(const char* event_name, bundle* event_data, void* user_data) {
1803 ScopeLogger("Event name is: '%s'", event_name);
1805 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1807 if (!manager->event_callback_) {
1808 LoggerD("No event listener registered, skipping.");
1812 picojson::value event = picojson::value(picojson::object());
1813 picojson::object& event_o = event.get<picojson::object>();
1816 char* val = nullptr;
1818 if (event_map_.count(event_name)) { // system event
1819 const std::string& key = event_map_.at(event_name);
1820 std::string state = "true";
1822 ret = bundle_get_str(event_data, key.c_str(), &val);
1823 if (EVENT_ERROR_NONE != ret) {
1824 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1828 state = std::string(val);
1831 LoggerD("State is %s", state.c_str());
1832 event_o["value"] = picojson::value(state);
1834 } else { // user event
1835 ret = bundle_get_str(event_data, "data", &val);
1836 if (EVENT_ERROR_NONE != ret) {
1837 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1841 picojson::value data;
1843 picojson::parse(data, val, val + strlen(val), &err);
1845 LoggerE("Failed to parse bundle data: %s", err.c_str());
1849 event_o["data"] = data;
1852 LoggerD("event_name is: %s", event_name);
1853 event_o["name"] = picojson::value(event_name);
1855 manager->event_callback_(&event);
1858 PlatformResult ApplicationManager::StartEventListener(const std::string& event_name,
1859 const JsonCallback& callback) {
1863 event_handler_h event_handler;
1865 ret = event_add_event_handler(event_name.c_str(), OnEvent, this, &event_handler);
1866 LoggerD("event_add_event_handler() result: %d (%s)", ret, get_error_message(ret));
1867 if (EVENT_ERROR_PERMISSION_DENIED == ret) {
1868 return LogAndCreateResult(ErrorCode::SECURITY_ERR, "The privilege is required",
1869 ("event_add_event_handler failed, error: %d", ret));
1870 } else if (EVENT_ERROR_NONE != ret) {
1871 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error setting event listener",
1872 ("event_add_event_handler failed, error: %d", ret));
1875 event_handler_map_[event_name] = event_handler;
1877 event_callback_ = callback;
1878 LoggerD("event_add_event_handler success");
1879 return PlatformResult(ErrorCode::NO_ERROR);
1882 void ApplicationManager::StopEventListener(const std::string& event_name) {
1886 event_handler_h event_handler;
1888 if (event_handler_map_.find(event_name) != event_handler_map_.end()) {
1889 event_handler = event_handler_map_[event_name];
1891 ret = event_remove_event_handler(event_handler);
1892 if (EVENT_ERROR_NONE != ret) {
1893 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
1897 event_handler_map_.erase(event_name);
1901 void ApplicationManager::OnStatusEvent(const char* type, const char* app_id,
1902 app_manager_event_type_e event_type,
1903 app_manager_event_state_e event_state,
1904 app_manager_event_h handle, void* user_data) {
1907 if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
1908 LoggerD("State different from completed");
1912 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1914 if (!manager || !manager->status_callback_) {
1915 LoggerD("No event listener registered, skipping.");
1920 switch (event_type) {
1921 case APP_MANAGER_EVENT_ENABLE_APP:
1924 case APP_MANAGER_EVENT_DISABLE_APP:
1925 status_type = false;
1928 LoggerD("Uknown status type skipping.");
1932 picojson::value event = picojson::value(picojson::object());
1933 picojson::object& event_o = event.get<picojson::object>();
1935 event_o[kStatusType] = picojson::value(status_type);
1936 event_o[kAppId] = picojson::value(app_id);
1937 event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
1939 manager->status_callback_(&event);
1942 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1943 PlatformResult ApplicationManager::GetContextHistory(
1944 const picojson::value& args, picojson::object* out,
1945 common::PlatformResult (*modify_filter_cb)(const picojson::value&,
1946 const context_history_filter_h,
1947 context_history_data_e* data_type),
1948 common::PlatformResult (*add_attributes_to_object)(const context_history_record_h,
1949 picojson::object*)) {
1951 context_history_list_h list = nullptr;
1952 context_history_h handle = nullptr;
1953 context_history_filter_h filter = nullptr;
1956 context_history_list_destroy(list);
1957 context_history_destroy(handle);
1958 context_history_filter_destroy(filter);
1961 int ret = context_history_create(&handle);
1962 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1963 return LogAndCreateResult(
1964 ErrorCode::ABORT_ERR, "Failed to create context handle.",
1965 ("Failed to create context handle: %d (%s)", ret, get_error_message(ret)));
1968 ret = context_history_filter_create(&filter);
1969 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1970 return LogAndCreateResult(
1971 ErrorCode::ABORT_ERR, "Failed to create filter handle.",
1972 ("Failed to create filter handle: %d (%s)", ret, get_error_message(ret)));
1975 context_history_data_e data_type;
1977 PlatformResult result = modify_filter_cb(args, filter, &data_type);
1982 picojson::value result_array = picojson::value(picojson::array());
1983 picojson::array& array_obj = result_array.get<picojson::array>();
1985 ret = context_history_get_list(handle, data_type, filter, &list);
1986 if (CONTEXT_HISTORY_ERROR_NO_DATA == ret) {
1987 ReportSuccess(result_array, *out);
1988 return PlatformResult(ErrorCode::NO_ERROR);
1989 } else if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1990 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list.",
1991 ("Failed to get list: %d (%s)", ret, get_error_message(ret)));
1995 ret = context_history_list_get_count(list, &size);
1996 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1997 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list size.",
1998 ("Failed to get list size: %d (%s)", ret, get_error_message(ret)));
2001 array_obj.resize(size, picojson::value(picojson::object()));
2003 for (int i = 0; i < size; ++i) {
2004 context_history_record_h record = nullptr;
2006 context_history_record_destroy(record);
2009 ret = context_history_list_get_current(list, &record);
2010 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2011 return LogAndCreateResult(
2012 ErrorCode::ABORT_ERR, "Failed to get current record.",
2013 ("Failed to get current record: %d (%s)", ret, get_error_message(ret)));
2016 result = add_attributes_to_object(record, &array_obj[i].get<picojson::object>());
2021 ret = context_history_list_move_next(list);
2022 if (CONTEXT_HISTORY_ERROR_NONE != ret && CONTEXT_HISTORY_ERROR_NO_DATA != ret) {
2023 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to move iterator.",
2024 ("Failed to move iterator: %d (%s)", ret, get_error_message(ret)));
2028 ReportSuccess(result_array, *out);
2029 return PlatformResult(ErrorCode::NO_ERROR);
2033 PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
2036 int ret = APP_MANAGER_ERROR_NONE;
2038 if (!app_status_handle_) {
2039 ret = app_manager_event_create(&app_status_handle_);
2040 if (APP_MANAGER_ERROR_NONE != ret) {
2041 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
2042 ("app_manager_event_create failed, error: %d", ret));
2045 ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
2046 if (APP_MANAGER_ERROR_NONE != ret) {
2047 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
2048 ("app_manager_event_set_status failed, error: %d", ret));
2052 status_callback_ = callback;
2053 ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
2054 if (APP_MANAGER_ERROR_NONE != ret) {
2055 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
2056 ("app_manager_set_event_cb failed, error: %d", ret));
2059 return PlatformResult(ErrorCode::NO_ERROR);
2062 PlatformResult ApplicationManager::StopStatusChangeListener() {
2065 if (app_status_handle_) {
2066 int ret = app_manager_unset_event_cb(app_status_handle_);
2067 if (APP_MANAGER_ERROR_NONE != ret) {
2068 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
2069 ("app_manager_unset_event_cb failed, error: %d", ret));
2073 return PlatformResult(ErrorCode::NO_ERROR);
2076 } // namespace application
2077 } // namespace extension