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"
19 #include <type_traits>
23 #include <app_manager_extension.h>
25 #include <pkgmgr_installer.h>
26 #include <package_manager.h>
27 #include <pkgmgr-info.h>
29 #include <bundle_internal.h>
31 #include <app_control_internal.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";
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}
103 const int kMaximumBatteryRetrievedObjects = 30;
104 const int kMaximumAppsRetrievedObjects = 10;
105 const int kDefaultPeriodOfTime = 30;
109 ApplicationManager::ApplicationManager(ApplicationInstance& instance) :
110 pkgmgr_client_handle_(nullptr),
111 pkgmgr_client_uninstall_handle_(nullptr),
113 app_status_handle_(nullptr) {
117 ApplicationManager::~ApplicationManager() {
119 StopAppInfoEventListener();
120 StopStatusChangeListener();
122 if (app_status_handle_) {
123 int ret = app_manager_event_destroy(app_status_handle_);
124 if (APP_MANAGER_ERROR_NONE != ret) {
125 LoggerE ("app_manager_event_destroy failed, error: %d", ret);
130 void ApplicationManager::GetCurrentApplication(const std::string& app_id,
131 picojson::object* out) {
134 // obtain handle to application info
135 pkgmgrinfo_appinfo_h handle;
136 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
137 if (PMINFO_R_OK != ret) {
138 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app info."), out,
139 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
143 picojson::value app_info = picojson::value(picojson::object());
144 picojson::object& app_info_obj = app_info.get<picojson::object>();
146 ApplicationUtils::CreateApplicationInformation(handle, &app_info_obj);
147 pkgmgrinfo_appinfo_destroy_appinfo(handle);
149 picojson::value result = picojson::value(picojson::object());
150 picojson::object& result_obj = result.get<picojson::object>();
152 result_obj.insert(std::make_pair(
153 "contextId", picojson::value(std::to_string(CurrentApplication::GetInstance().GetProcessId()))));
154 result_obj.insert(std::make_pair("appInfo", app_info));
156 ReportSuccess(result, *out);
159 class TerminateHandler {
161 TerminateHandler(int callback_id, ApplicationInstance* app_instance) :
162 callback_handle_(callback_id),
165 app_instance_(app_instance) {
168 void set_pid(pid_t pid) {
176 void Invoke(const std::shared_ptr<picojson::value>& response) {
179 if (timeout_id_ > 0) {
180 // cancel terminate callback
181 g_source_remove(timeout_id_);
185 ApplicationInstance* app_instance = this->app_instance_;
186 int callback_id = this->callback_handle_;
187 TaskQueue::GetInstance().Async<picojson::value>([callback_id, app_instance](
188 const std::shared_ptr<picojson::value>& response) {
189 picojson::object& obj = response->get<picojson::object>();
190 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
191 Instance::PostMessage(app_instance, response->serialize().c_str());
195 void LaunchCheckTerminate() {
197 timeout_id_ = g_timeout_add(3000, CheckTerminate, this);
202 static gboolean CheckTerminate(gpointer user_data) {
204 TerminateHandler* that = static_cast<TerminateHandler*>(user_data);
205 LoggerD("PID: %d", that->pid_);
207 // we're canceling the callback by returning false, no need for Invoke() to do that again
208 that->timeout_id_ = 0;
210 char* app_id = nullptr;
211 std::shared_ptr<picojson::value> response{new picojson::value(picojson::object())};
213 LoggerD("checking if application is still alive");
214 int ret = app_manager_get_app_id(that->pid_, &app_id);
215 if (APP_MANAGER_ERROR_NONE == ret) {
217 // context is still alive, report error
218 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to kill application."),
219 &response->get<picojson::object>(),
220 ("application is alive - failure"));
222 LoggerD("application is dead - success: %d (%s)", ret, get_error_message(ret));
223 ReportSuccess(response->get<picojson::object>());
226 that->Invoke(response);
232 int callback_handle_;
235 ApplicationInstance* app_instance_;
238 #define CHECK_RESULT(result, response, handler) \
239 if (result.IsError()) { \
240 LogAndReportError(result, &response->get<picojson::object>()); \
241 handler->Invoke(response); \
246 void ApplicationManager::AsyncResponse(PlatformResult& result,
247 std::shared_ptr<picojson::value>* response) {
250 LogAndReportError(result, &(*response)->get<picojson::object>());
252 TaskQueue::GetInstance().Async<picojson::value>([this](
253 const std::shared_ptr<picojson::value>& response) {
254 Instance::PostMessage(&this->instance_, response->serialize().c_str());
258 void ApplicationManager::Kill(const picojson::value& args) {
261 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
263 int callback_id = -1;
264 const auto& callback = args.get(kCallbackId);
265 if (callback.is<double>()) {
266 callback_id = static_cast<int>(callback.get<double>());
269 const auto& context = args.get("contextId");
270 if (!context.is<std::string>()) {
271 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
274 const std::string& context_id = context.get<std::string>();
276 if (context_id.empty() && result.IsSuccess()) {
277 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID is empty.");
280 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
281 picojson::object& obj = response->get<picojson::object>();
282 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
284 if (result.IsError()) {
285 LoggerE("Failed args.get");
286 AsyncResponse(result, &response);
290 auto kill = [this, callback_id, context_id]() -> void {
291 LoggerD("Entered Kill async");
293 std::shared_ptr<picojson::value> response =
294 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
296 TerminateHandler* handler = new TerminateHandler(callback_id, &this->instance_);
297 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
301 pid = std::stoi(context_id);
303 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
304 CHECK_RESULT(result, response, handler)
308 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID cannot be negative value.");
309 CHECK_RESULT(result, response, handler)
312 // if kill request comes for current context, throw InvalidValuesException
313 if (CurrentApplication::GetInstance().GetProcessId() == pid) {
314 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Cannot kill current application.");
315 CHECK_RESULT(result, response, handler)
318 LoggerD("Kill async, pid: %d", pid);
320 char* app_id = nullptr;
321 int ret = app_manager_get_app_id(pid, &app_id);
322 // automatically release the memory
323 std::unique_ptr<char, void(*)(void*)> app_id_ptr(app_id, &std::free);
325 if (APP_MANAGER_ERROR_NONE != ret) {
326 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
327 ("Failed to get application ID, error: %d (%s)", ret, get_error_message(ret)));
328 CHECK_RESULT(result, response, handler)
331 LoggerD("Kill async, app ID: %s", app_id);
333 // acquire application context
334 app_context_h app_context = nullptr;
336 ret = app_manager_get_app_context(app_id, &app_context);
337 std::unique_ptr<std::remove_pointer<app_context_h>::type, int(*)(app_context_h)>
338 app_context_ptr(app_context, &app_context_destroy); // automatically release the memory
340 if (APP_MANAGER_ERROR_NONE != ret) {
341 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
342 ("Failed to get application context handle: %d (%s)", ret, get_error_message(ret)));
343 CHECK_RESULT(result, response, handler)
346 auto terminate_callback = [](app_context_h app_context,
347 app_context_event_e event,
349 LoggerD("terminate_callback: %d", event);
351 if (APP_CONTEXT_EVENT_TERMINATED != event) {
352 LoggerD("ignoring event");
357 int ret = app_context_get_pid(app_context, &pid);
359 if (APP_MANAGER_ERROR_NONE != ret) {
360 LoggerE("Failed to get pid of terminated app: %d (%s)", ret, get_error_message(ret));
364 TerminateHandler* handler = static_cast<TerminateHandler*>(user_data);
366 LoggerD("Expected PID: %d, got: %d", handler->pid(), pid);
368 if (handler->pid() == pid) {
369 std::shared_ptr<picojson::value> response =
370 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
371 ReportSuccess(response->get<picojson::object>());
372 handler->Invoke(response);
377 LoggerD("Kill async, setting callback");
378 handler->set_pid(pid);
379 ret = app_manager_set_app_context_event_cb(terminate_callback, handler);
381 if (APP_MANAGER_ERROR_NONE != ret) {
382 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to register termination callback.",
383 ("Error while registering app context event: %d (%s)", ret, get_error_message(ret)));
384 CHECK_RESULT(result, response, handler)
387 // due to platform issue, sometimes termination event is not reported to callback
388 // registered with app_manager_set_app_context_event_cb()
389 // this is a workaround, it should be removed when issue is solved
390 //handler->LaunchCheckTerminate();
392 LoggerD("Kill async, KILL!!!!!!!!!");
394 // terminate application
395 ret = app_manager_terminate_app(app_context);
397 if (APP_MANAGER_ERROR_NONE != ret) {
398 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to terminate application.",
399 ("Failed to terminate application: %d (%s)", ret, get_error_message(ret)));
400 CHECK_RESULT(result, response, handler)
403 LoggerD("Kill async, end, waiting for notification");
406 TaskQueue::GetInstance().Queue(kill);
409 void ApplicationManager::Launch(const picojson::value& args) {
412 int callback_id = -1;
413 const auto& callback = args.get(kCallbackId);
414 if (callback.is<double>()) {
415 callback_id = static_cast<int>(callback.get<double>());
418 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
419 picojson::object& obj = response->get<picojson::object>();
420 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
422 const auto& app_id = args.get("id");
423 if (!app_id.is<std::string>()) {
424 PlatformResult ret = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
425 AsyncResponse(ret, &response);
428 const std::string& id = app_id.get<std::string>();
430 auto launch = [id](const std::shared_ptr<picojson::value>& response) -> void {
431 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
432 const char* app_id = id.c_str();
433 const int retry_count = 3;
438 while (retry < retry_count) {
439 ret = aul_open_app(app_id);
445 // delay 300ms for each retry
446 struct timespec sleep_time = { 0, 300L * 1000L * 1000L };
447 nanosleep(&sleep_time, nullptr);
450 LoggerD("Retry launch request: %d", retry);
454 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error has occurred.");
456 LoggerD("Aul open return: %d (%s)", ret, get_error_message(ret));
461 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Launchpad returns not found error.",
462 ("aul_open_app returns Not Found error"));
466 result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Internal IPC error has occurred.",
467 ("aul_open_app returns internal IPC error"));
471 LogAndReportError(result, &response->get<picojson::object>());
473 LoggerD("Launch request success");
474 ReportSuccess(response->get<picojson::object>());
478 auto launch_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
479 Instance::PostMessage(&this->instance_, response->serialize().c_str());
482 TaskQueue::GetInstance().Queue<picojson::value>(launch, launch_response, response);
485 void ApplicationManager::LaunchAppControl(const picojson::value& args) {
488 int callback_id = -1;
489 const auto& callback = args.get(kCallbackId);
490 if (callback.is<double>()) {
491 callback_id = static_cast<int>(callback.get<double>());
494 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
495 picojson::object& response_obj = response->get<picojson::object>();
497 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
499 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
500 const auto& control = args.get("appControl");
501 if (!control.is<picojson::object>()) {
502 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
503 AsyncResponse(result, &response);
506 const picojson::object& app_control_obj = control.get<picojson::object>();
508 std::string launch_mode_str;
509 const auto& launch_mode = control.get("launchMode");
510 if (launch_mode.is<std::string>()) {
511 launch_mode_str = launch_mode.get<std::string>();
514 app_control_h app_control = nullptr;
515 result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
516 std::shared_ptr<std::remove_pointer<app_control_h>::type>
517 app_control_ptr(app_control, &app_control_destroy); // automatically release the memory
519 if (result.IsError()) {
520 LoggerE("Application control to service failed.");
521 AsyncResponse(result, &response);
526 const auto& id = args.get("id");
527 if (id.is<std::string>()) {
528 app_id = id.get<std::string>();
531 std::string reply_callback;
532 const auto& reply = args.get("replyCallback");
533 if (reply.is<std::string>()) {
534 reply_callback = reply.get<std::string>();
537 auto launch = [this, app_control_ptr, app_id, launch_mode_str, reply_callback](
538 const std::shared_ptr<picojson::value>& response) -> void {
541 if (!app_id.empty()) {
542 LoggerD("app_id: %s", app_id.c_str());
544 int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
546 if (APP_CONTROL_ERROR_NONE != ret) {
547 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
548 &response->get<picojson::object>(),
549 ("Failed to set app id: %d (%s)", ret, get_error_message(ret)));
554 if (!launch_mode_str.empty()) {
555 app_control_launch_mode_e launch_mode;
557 if ("SINGLE" == launch_mode_str) {
558 launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
559 } else if ("GROUP" == launch_mode_str) {
560 launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP;
562 ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
563 &response->get<picojson::object>());
567 int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode);
568 if (APP_CONTROL_ERROR_NONE != ret) {
569 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."),
570 &response->get<picojson::object>(),
571 ("Setting launch mode failed: %d (%s)", ret, get_error_message(ret)));
576 app_control_reply_cb callback = nullptr;
577 struct ReplayCallbackData {
578 ApplicationInstance* app_instance;
579 std::string reply_callback;
582 ReplayCallbackData* user_data = nullptr;
584 if (!reply_callback.empty()) {
585 user_data = new ReplayCallbackData();
586 user_data->app_instance = &this->instance_;
587 user_data->reply_callback = reply_callback;
589 callback = [](app_control_h request,
590 app_control_h reply, app_control_result_e result, void* user_data) {
591 LoggerD("send_launch_request callback");
593 picojson::value return_value = picojson::value(picojson::object());
594 picojson::object& return_value_obj = return_value.get<picojson::object>();
595 ReplayCallbackData* reply_callback = static_cast<ReplayCallbackData*>(user_data);
597 if (APP_CONTROL_RESULT_SUCCEEDED == result) {
598 const std::string data = "data";
599 return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array())));
600 if (!ApplicationUtils::ServiceToApplicationControlDataArray(
601 reply, &return_value_obj.find(data)->second.get<picojson::array>())) {
602 return_value_obj.erase(data);
604 ReportSuccess(return_value_obj);
606 ReportError(return_value_obj);
609 return_value_obj.insert(
610 std::make_pair("listenerId", picojson::value(reply_callback->reply_callback)));
611 Instance::PostMessage(reply_callback->app_instance, return_value.serialize().c_str());
612 delete reply_callback;
616 const int retry_count = 3;
621 while (retry < retry_count) {
622 LoggerD("Calling launch request. Attempt number: %d", retry);
624 ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data);
625 LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret));
626 if (APP_CONTROL_ERROR_NONE == ret) {
630 // delay 300ms for each retry
631 struct timespec sleep_time = { 0, 300L * 1000L * 1000L };
632 nanosleep(&sleep_time, nullptr);
636 if (APP_CONTROL_ERROR_NONE != ret) {
640 case APP_CONTROL_ERROR_INVALID_PARAMETER:
641 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."),
642 &response->get<picojson::object>(),
643 ("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER"));
645 case APP_CONTROL_ERROR_OUT_OF_MEMORY:
646 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."),
647 &response->get<picojson::object>(),
648 ("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY"));
650 case APP_CONTROL_ERROR_LAUNCH_REJECTED:
651 case APP_CONTROL_ERROR_APP_NOT_FOUND:
652 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."),
653 &response->get<picojson::object>(),
654 ("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND"));
657 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."),
658 &response->get<picojson::object>(),
659 ("app_control_send_launch_request returns: %d (%s)", ret, get_error_message(ret)));
663 ReportSuccess(response->get<picojson::object>());
666 auto launch_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
667 LoggerD("Entered launch_response");
669 Instance::PostMessage(&this->instance_, response->serialize().c_str());
672 TaskQueue::GetInstance().Queue<picojson::value>(launch, launch_response, response);
675 //internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
676 //public CAPI did not handling APP_CONTROL_ERROR_APP_NOT_FOUND
677 int app_control_foreach_app_matched_internal(app_control_h app_control, app_control_app_matched_cb callback, void* user_data){
679 app_control_h app_control;
680 app_control_app_matched_cb callback;
683 } foreach_context_launchable_app_t_internal;
685 //internal impl of app_control_cb_broker_foreach_app_matched()
686 auto app_control_cb_broker_foreach_app_matched_internal = [](const char *package, void *data) -> int {
687 foreach_context_launchable_app_t_internal *foreach_context;
688 app_control_app_matched_cb app_matched_cb;
690 if (package == NULL || data == NULL) {
691 LoggerE("APP_CONTROL_ERROR_INVALID_PARAMETER");
695 foreach_context = (foreach_context_launchable_app_t_internal *)data;
696 if (foreach_context->foreach_break == true)
699 app_matched_cb = foreach_context->callback;
700 if (app_matched_cb != NULL) {
701 bool stop_foreach = false;
703 stop_foreach = !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
705 foreach_context->foreach_break = stop_foreach;
711 foreach_context_launchable_app_t_internal foreach_context = {
712 .app_control = app_control,
713 .callback = callback,
714 .user_data = user_data,
715 .foreach_break = false
718 bundle *bundle_data = NULL;
719 app_control_to_bundle(app_control, &bundle_data);
721 int ret = appsvc_usr_get_list(bundle_data, app_control_cb_broker_foreach_app_matched_internal, &foreach_context, getuid());
725 case APPSVC_RET_EINVAL:
726 return APP_CONTROL_ERROR_INVALID_PARAMETER;
728 case APPSVC_RET_ENOMATCH:
729 return APP_CONTROL_ERROR_APP_NOT_FOUND;
732 return APP_CONTROL_ERROR_LAUNCH_FAILED;
736 return APP_CONTROL_ERROR_NONE;
740 void ApplicationManager::FindAppControl(const picojson::value& args) {
743 int callback_id = -1;
744 const auto& callback = args.get(kCallbackId);
745 if (callback.is<double>()) {
746 callback_id = static_cast<int>(callback.get<double>());
749 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
750 picojson::object& response_obj = response->get<picojson::object>();
752 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
754 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
755 const auto& control = args.get("appControl");
756 if (!control.is<picojson::object>()) {
757 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
758 AsyncResponse(result, &response);
762 const picojson::object& app_control_obj = control.get<picojson::object>();
764 app_control_h app_control = nullptr;
765 result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
766 std::shared_ptr<std::remove_pointer<app_control_h>::type>
767 app_control_ptr(app_control, &app_control_destroy); // automatically release the memory
769 if (result.IsError()) {
770 LoggerE("Application control to service failed.");
771 AsyncResponse(result, &response);
775 auto find = [app_control_ptr](const std::shared_ptr<picojson::value>& response) -> void {
776 auto app_control_matched = [](app_control_h app_control, const char* appid, void* user_data) -> bool {
777 if (nullptr == appid) {
778 LoggerD("appid is NULL");
782 pkgmgrinfo_appinfo_h handle;
783 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &handle);
784 if (PMINFO_R_OK != ret) {
785 LoggerE("Failed to get appInfo: %d (%s)", ret, get_error_message(ret));
787 picojson::array* array = static_cast<picojson::array*>(user_data);
788 array->push_back(picojson::value(picojson::object()));
790 ApplicationUtils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
791 pkgmgrinfo_appinfo_destroy_appinfo(handle);
797 picojson::object& response_obj = response->get<picojson::object>();
798 auto it_result = response_obj.find("result");
799 picojson::object& result_obj = it_result->second.get<picojson::object>();
800 auto array = result_obj.insert(
801 std::make_pair("informationArray", picojson::value(picojson::array())));
803 int ret = app_control_foreach_app_matched_internal(
804 app_control_ptr.get(), app_control_matched, &array.first->second.get<picojson::array>());
806 if (APP_CONTROL_ERROR_NONE != ret) {
807 if(APP_CONTROL_ERROR_APP_NOT_FOUND == ret){
808 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR,"Matched Application not found"), &response_obj,
809 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
810 }else if(APP_CONTROL_ERROR_LAUNCH_FAILED == ret){
811 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR,"Unknown error"), &response_obj,
812 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
813 }else if(APP_CONTROL_ERROR_INVALID_PARAMETER == ret){
814 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR,"Invalid parameter passed"), &response_obj,
815 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
817 // remove copied ApplicationControl from result
818 response_obj.erase(it_result);
820 ReportSuccess(response_obj);
824 auto find_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
825 Instance::PostMessage(&this->instance_, response->serialize().c_str());
828 // prepare result object, we need to do that here, as input parameter is passed to result callback
829 auto ret = response_obj.insert(std::make_pair("result", picojson::value(picojson::object())));
830 // reinsert application control
831 ret.first->second.get<picojson::object>().insert(std::make_pair("appControl", args.get("appControl")));
833 TaskQueue::GetInstance().Queue<picojson::value>(find, find_response, response);
836 void ApplicationManager::GetAppsContext(const picojson::value& args) {
839 int callback_id = -1;
840 const auto& callback = args.get(kCallbackId);
841 if (callback.is<double>()) {
842 callback_id = static_cast<int>(callback.get<double>());
845 auto get_apps_context = [](const std::shared_ptr<picojson::value>& response) -> void {
846 picojson::object& response_obj = response->get<picojson::object>();
847 picojson::value result = picojson::value(picojson::object());
848 picojson::object& result_obj = result.get<picojson::object>();
849 picojson::array& array =
850 result_obj.insert(std::make_pair("contexts", picojson::value(
851 picojson::array()))).first->second.get<picojson::array>();
853 auto app_context_cb = [](app_context_h app_context, void* user_data) -> bool {
854 if (nullptr == user_data) {
858 picojson::array* array = static_cast<picojson::array*>(user_data);
859 array->push_back(picojson::value(picojson::object()));
861 if (!ApplicationUtils::CreateApplicationContext(
862 app_context, &array->back().get<picojson::object>())) {
870 int ret = app_manager_foreach_app_context(app_context_cb, &array);
872 if (APP_MANAGER_ERROR_NONE != ret) {
873 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
874 ("app_manager_foreach_app_context error: %d (%s)", ret, get_error_message(ret)));
876 ReportSuccess(result, response_obj);
880 auto get_apps_context_response = [this, callback_id](
881 const std::shared_ptr<picojson::value>& response) -> void {
882 picojson::object& obj = response->get<picojson::object>();
883 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
884 Instance::PostMessage(&this->instance_, response->serialize().c_str());
887 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
889 TaskQueue::GetInstance().Queue<picojson::value>(
891 get_apps_context_response,
895 void ApplicationManager::GetAppContext(const picojson::value& args, picojson::object* out) {
899 const auto& context_id = args.get("contextId");
900 if (context_id.is<std::string>()) {
902 pid = std::stoi(context_id.get<std::string>());
904 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert context id."), out);
908 pid = CurrentApplication::GetInstance().GetProcessId();
911 char* app_id = nullptr;
913 int ret = app_manager_get_app_id(pid, &app_id);
914 // automatically release the memory
915 std::unique_ptr<char, void(*)(void*)> app_id_ptr(app_id, &std::free);
917 if (APP_MANAGER_ERROR_NONE != ret || nullptr == app_id) {
919 case APP_MANAGER_ERROR_NO_SUCH_APP:
920 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "No such application exist."), out,
921 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_NO_SUCH_APP"));
924 case APP_MANAGER_ERROR_INVALID_PARAMETER:
925 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Application not found."), out,
926 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_INVALID_PARAMETER"));
930 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), out,
931 ("app_manager_get_app_id returned: %d (%s)", ret, get_error_message(ret)));
936 picojson::value result = picojson::value(picojson::object());
937 ApplicationUtils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
939 ReportSuccess(result, *out);
942 void ApplicationManager::GetAppsInfo(const picojson::value& args) {
945 int callback_id = -1;
946 const auto& callback = args.get(kCallbackId);
947 if (callback.is<double>()) {
948 callback_id = static_cast<int>(callback.get<double>());
951 auto get_apps_info = [](const std::shared_ptr<picojson::value>& response) -> void {
952 picojson::object& response_obj = response->get<picojson::object>();
953 picojson::value result = picojson::value(picojson::object());
954 picojson::object& result_obj = result.get<picojson::object>();
955 picojson::array& array =
956 result_obj.insert(std::make_pair("informationArray", picojson::value(
957 picojson::array()))).first->second.get<picojson::array>();
959 auto app_info_cb = [](pkgmgrinfo_appinfo_h handle, void* user_data) -> int {
960 if (nullptr == user_data) {
964 picojson::array* array = static_cast<picojson::array*>(user_data);
965 array->push_back(picojson::value(picojson::object()));
967 ApplicationUtils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
972 int ret = pkgmgrinfo_appinfo_get_usr_installed_list(app_info_cb, getuid(), &array);
974 if (APP_MANAGER_ERROR_NONE != ret) {
975 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
976 ("pkgmgrinfo_appinfo_get_usr_installed_list error"));
978 ReportSuccess(result, response_obj);
982 auto get_apps_info_response = [this, callback_id](
983 const std::shared_ptr<picojson::value>& response) -> void {
984 picojson::object& obj = response->get<picojson::object>();
985 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
986 Instance::PostMessage(&this->instance_, response->serialize().c_str());
989 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
991 TaskQueue::GetInstance().Queue<picojson::value>(
993 get_apps_info_response,
997 void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object* out) {
1000 pkgmgrinfo_appinfo_h handle = nullptr;
1002 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1003 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out);
1007 picojson::value result = picojson::value(picojson::object());
1008 ApplicationUtils::CreateApplicationInformation(handle, &result.get<picojson::object>());
1009 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1011 ReportSuccess(result, *out);
1014 char* ApplicationManager::GetPackageId(const std::string& app_id) {
1017 char* pkg_id = nullptr;
1019 int ret = app_manager_get_app_info(app_id.c_str(), &handle);
1020 if (APP_MANAGER_ERROR_NONE != ret) {
1021 LoggerE("Failed to get app info: %d (%s)", ret, get_error_message(ret));
1025 ret = app_info_get_package(handle, &pkg_id);
1026 if (APP_MANAGER_ERROR_NONE != ret) {
1027 LoggerE("Failed to get package id: %d (%s)", ret, get_error_message(ret));
1031 ret = app_info_destroy(handle);
1032 if (APP_MANAGER_ERROR_NONE != ret) {
1033 LoggerE("Failed to destroy app info: %d (%s)", ret, get_error_message(ret));
1039 void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object* out) {
1042 char* package_id = nullptr;
1044 package_id = GetPackageId(app_id);
1045 // automatically release the memory
1046 std::unique_ptr<char, void(*)(void*)> package_id_ptr(package_id, &std::free);
1049 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1053 package_info_h pkg_info = nullptr;
1054 int ret = package_info_create(package_id, &pkg_info);
1056 std::unique_ptr<std::remove_pointer<package_info_h>::type, int(*)(package_info_h)>
1057 pkg_info_ptr(pkg_info, &package_info_destroy); // automatically release the memory
1059 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1060 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1061 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1065 auto cert_info_cb = [](package_info_h handle, package_cert_type_e cert_type,
1066 const char* cert_value, void* user_data) -> bool {
1067 const char* cert_name = nullptr;
1070 case PACKAGE_INFO_AUTHOR_ROOT_CERT:
1071 cert_name = "AUTHOR_ROOT";
1073 case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT:
1074 cert_name = "AUTHOR_INTERMEDIATE";
1076 case PACKAGE_INFO_AUTHOR_SIGNER_CERT:
1077 cert_name = "AUTHOR_SIGNER";
1079 case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT:
1080 cert_name = "DISTRIBUTOR_ROOT";
1082 case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT:
1083 cert_name = "DISTRIBUTOR_INTERMEDIATE";
1085 case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT:
1086 cert_name = "DISTRIBUTOR_SIGNER";
1088 case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT:
1089 cert_name = "DISTRIBUTOR2_ROOT";
1091 case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT:
1092 cert_name = "DISTRIBUTOR2_INTERMEDIATE";
1094 case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT:
1095 cert_name = "DISTRIBUTOR2_SIGNER";
1098 LoggerD("Unknown certificate type: %d", cert_type);
1102 picojson::array* array = static_cast<picojson::array*>(user_data);
1103 array->push_back(picojson::value(picojson::object()));
1105 ApplicationUtils::CreateApplicationCertificate(
1106 cert_name, cert_value, &array->back().get<picojson::object>());
1111 picojson::value result = picojson::value(picojson::array());
1113 ret = package_info_foreach_cert_info(pkg_info, cert_info_cb, &result.get<picojson::array>());
1115 if ((PACKAGE_MANAGER_ERROR_NONE != ret) && (PACKAGE_MANAGER_ERROR_IO_ERROR != ret)) {
1116 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get certificates info."), out,
1117 ("Failed to get certificates info: %d (%s)", ret, get_error_message(ret)));
1121 ReportSuccess(result, *out);
1124 void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::object* out) {
1127 char* package_id = nullptr;
1129 package_id = GetPackageId(app_id);
1130 // automatically release the memory
1131 std::unique_ptr<char, void(*)(void*)> package_id_ptr(package_id, &std::free);
1134 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1138 pkgmgrinfo_pkginfo_h pkg_info = nullptr;
1140 int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(package_id, getuid(), &pkg_info);
1141 std::unique_ptr<std::remove_pointer<pkgmgrinfo_pkginfo_h>::type, int(*)(pkgmgrinfo_pkginfo_h)>
1142 pkg_info_ptr(pkg_info, &pkgmgrinfo_pkginfo_destroy_pkginfo); // automatically release the memory
1144 if (PMINFO_R_OK != ret) {
1145 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1146 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1150 char* root_path = nullptr;
1151 ret = pkgmgrinfo_pkginfo_get_root_path(pkg_info, &root_path);
1153 if (PMINFO_R_OK != ret || nullptr == root_path) {
1154 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get root path."), out,
1155 ("Failed to get root path: %d (%s)", ret, get_error_message(ret)));
1159 picojson::value result = picojson::value(kTizenApisFileScheme +
1161 kTizenApisAppSlash +
1162 kTizenApisAppShared +
1163 kTizenApisAppSlash);
1164 ReportSuccess(result, *out);
1168 PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args, const context_history_filter_h filter,
1169 context_history_data_e* data_type_out) {
1171 int ret = CONTEXT_HISTORY_ERROR_NONE;
1172 int limit = kMaximumBatteryRetrievedObjects;
1173 if (args.contains("limit")) {
1174 limit = static_cast<int>(args.get("limit").get<double>());
1177 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1179 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1180 return LogAndCreateResult(
1181 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1182 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1185 context_history_data_e data_type_in = CONTEXT_HISTORY_RECENT_BATTERY_USAGE;
1187 if (args.contains("days")) {
1188 const int days = static_cast<int>(args.get("days").get<double>());
1189 data_type_in = CONTEXT_HISTORY_BATTERY_USAGE;
1190 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, days);
1192 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1193 return LogAndCreateResult(
1194 ErrorCode::INVALID_VALUES_ERR, "days given with invalid value.",
1195 ("days given with invalid value: %d (%s)", ret, get_error_message(ret)));
1199 *data_type_out = data_type_in;
1201 return PlatformResult(ErrorCode::NO_ERROR);
1204 PlatformResult ApplicationManager::BatteryUsageAttributes(const context_history_record_h record, picojson::object* object) {
1207 int ret = CONTEXT_HISTORY_ERROR_NONE;
1208 double amount = 0.0;
1209 char* app_id = nullptr;
1214 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1215 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1216 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1217 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1220 ret = context_history_record_get_double(record, CONTEXT_HISTORY_TOTAL_AMOUNT, &amount);
1221 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1222 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get amount.",
1223 ("Failed to get amount: %d (%s)", ret, get_error_message(ret)));
1226 object->insert(std::make_pair("appId", picojson::value(app_id)));
1227 object->insert(std::make_pair("batteryUsage", picojson::value(amount)));
1229 return PlatformResult(ErrorCode::NO_ERROR);
1232 PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
1233 const context_history_filter_h filter,
1234 context_history_data_e* data_type_out) {
1236 int ret = CONTEXT_HISTORY_ERROR_NONE;
1237 int limit = kMaximumAppsRetrievedObjects;
1238 if (args.contains("limit")) {
1239 limit = static_cast<int>(args.get("limit").get<double>());
1242 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1243 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1244 return LogAndCreateResult(
1245 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1246 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1249 context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
1250 if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
1251 data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
1254 int time_span = kDefaultPeriodOfTime;
1255 const picojson::object &JS_filter = args.get("filter").get<picojson::object>();
1256 auto time_span_iter = JS_filter.find("timeSpan");
1257 if (JS_filter.end() != time_span_iter
1258 || (JS_filter.end() == JS_filter.find("startTime")
1259 && JS_filter.end() == JS_filter.find("endTime"))) {
1260 //In the second case, we treat the filter object just like an empty object.
1261 //The default value of filter will be used instead.
1262 if (JS_filter.end() != time_span_iter) {
1263 time_span = static_cast<int>(time_span_iter->second.get<double>());
1265 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
1266 //context_history_filter_set_int may return only success or CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
1267 //Although this should never happen, it's better to check ret's value
1268 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1269 return LogAndCreateResult(
1270 ErrorCode::ABORT_ERR, "Error while setting the default TIME_SPAN value.",
1271 ("Error while setting the default TIME_SPAN value: %d (%s)", ret, get_error_message(ret)));
1274 auto start_time_iter = JS_filter.find("startTime");
1275 auto end_time_iter = JS_filter.find("endTime");
1276 if (start_time_iter != JS_filter.end()) {
1277 int start_time = static_cast<int>(start_time_iter->second.get<double>());
1278 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
1279 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1280 return LogAndCreateResult(
1281 ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
1282 ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1285 if (end_time_iter != JS_filter.end()) {
1286 int end_time = static_cast<int>(end_time_iter->second.get<double>());
1287 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
1288 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1289 return LogAndCreateResult(
1290 ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
1291 ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1296 *data_type_out = data_type_in;
1298 return PlatformResult(ErrorCode::NO_ERROR);
1301 PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
1302 picojson::object* object) {
1305 int ret = CONTEXT_HISTORY_ERROR_NONE;
1306 int total_count = 0;
1307 int total_duration = 0;
1309 char* app_id = nullptr;
1314 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1315 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1316 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1317 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1320 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
1321 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1322 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
1323 ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
1326 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
1327 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1328 return LogAndCreateResult(
1329 ErrorCode::ABORT_ERR, "Failed to get total duration.",
1330 ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
1333 ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
1334 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1335 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
1336 ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
1339 object->insert(std::make_pair("appId", picojson::value(app_id)));
1340 object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
1342 std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
1343 object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
1345 return PlatformResult(ErrorCode::NO_ERROR);
1349 void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
1353 int callback_id = -1;
1354 const auto& callback = args.get(kCallbackId);
1355 if (callback.is<double>()) {
1356 callback_id = static_cast<int>(callback.get<double>());
1359 auto get_battery_usage = [args](const std::shared_ptr<picojson::value>& response)-> void {
1361 PlatformResult result = ApplicationManager::GetContextHistory(args, &response.get()->get<picojson::object>(),
1362 &ApplicationManager::BatteryUsageFilter,
1363 &ApplicationManager::BatteryUsageAttributes);
1365 LogAndReportError(result, &response.get()->get<picojson::object>());
1369 auto get_battery_usage_response = [this, callback_id](
1370 const std::shared_ptr<picojson::value>& response) -> void {
1372 picojson::object& obj = response->get<picojson::object>();
1373 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1374 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1377 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1379 TaskQueue::GetInstance().Queue<picojson::value>(
1381 get_battery_usage_response,
1384 // 20170510 Context API is supported only for mobile profile, other ones would result with NotSupportedError
1385 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "This feature is not supported on this profile."), out,
1386 ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1390 void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
1394 int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
1396 auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response)-> void {
1398 PlatformResult result = ApplicationManager::GetContextHistory(args, &response.get()->get<picojson::object>(),
1399 &ApplicationManager::AppsUsageFilter,
1400 &ApplicationManager::AppsUsageAttributes);
1402 LogAndReportError(result, &response.get()->get<picojson::object>());
1406 auto get_apps_usage_response = [this, callback_id](
1407 const std::shared_ptr<picojson::value>& response) -> void {
1409 picojson::object& obj = response->get<picojson::object>();
1410 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1411 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1414 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1416 TaskQueue::GetInstance().Queue<picojson::value>(
1418 get_apps_usage_response,
1421 // Context API is supported only for mobile profile, other ones would result with NotSupportedError
1422 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "This feature is not supported on this profile."), out,
1423 ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1427 void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
1430 pkgmgrinfo_appinfo_h handle = nullptr;
1432 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
1433 std::unique_ptr<std::remove_pointer<pkgmgrinfo_appinfo_h>::type, int(*)(pkgmgrinfo_appinfo_h)>
1434 pkg_info_ptr(handle, &pkgmgrinfo_appinfo_destroy_appinfo); // automatically release the memory
1436 if (PMINFO_R_OK != ret) {
1437 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out,
1438 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
1442 auto meta_data_cb = [](const char* meta_key, const char* meta_value, void* user_data) -> int {
1443 if (nullptr == meta_key || nullptr == meta_value) {
1444 LoggerE("meta_key or meta_value is null");
1448 picojson::array* array = static_cast<picojson::array*>(user_data);
1449 array->push_back(picojson::value(picojson::object()));
1451 ApplicationUtils::CreateApplicationMetaData(meta_key, meta_value,
1452 &array->back().get<picojson::object>());
1456 picojson::value result = picojson::value(picojson::array());
1457 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, meta_data_cb, &result.get<picojson::array>());
1459 if (PMINFO_R_OK != ret) {
1460 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get metadata."), out,
1461 ("Failed to get metadata: %d (%s)", ret, get_error_message(ret)));
1465 ReportSuccess(result, *out);
1468 class ApplicationListChangedBroker {
1470 ApplicationListChangedBroker() : event_type_() {}
1477 static int ClientStatusListener(unsigned int target_uid, int id,
1478 const char* type, const char* package,
1480 const char* val, const void* msg,
1483 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1485 if (0 == strcasecmp(key, kStartKey)) {
1486 that->HandleStart(val, package);
1487 } else if (0 == strcasecmp(key, kEndKey) && 0 == strcasecmp(val, kOkValue)) {
1488 that->HandleEnd(package);
1490 LoggerD("Ignored key: %s", key);
1496 static int AppUninstallListener(uid_t target_uid, int id, const char* type, const char* package, const char* key,
1497 const char* val, const void* msg, void* data) {
1500 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1502 if (0 == strcasecmp(key, kStartKey)) {
1503 that->HandleUninstallStart();
1504 } else if (0 == strcasecmp(key, kAppidKey)) {
1505 that->AddUninstalledAppId(val);
1506 } else if (0 == strcasecmp(key, kEndKey)) {
1507 that->HandleUninstallEnd();
1509 LoggerD("Ignored key: %s", key);
1515 void AddApplicationInstance(ApplicationInstance* app_instance) {
1517 app_instance_list_.push_back(app_instance);
1520 void RemoveApplicationInstance(ApplicationInstance* app_instance) {
1522 for (auto it = app_instance_list_.begin(); it != app_instance_list_.end(); it++) {
1523 if (*it == app_instance) {
1524 app_instance_list_.erase(it);
1530 void HandleStart(const char* event_type, const char* package) {
1533 set_event_type(event_type);
1536 void HandleEnd(const char* package) {
1539 if (Event::kUninstalled == event_type_) {
1543 GetApplicationIdsFromPackage(package);
1545 for (auto& app_id : app_list_) {
1546 picojson::value value = picojson::value(picojson::object());
1547 picojson::object& data_obj = value.get<picojson::object>();
1549 switch (event_type_) {
1550 case Event::kInstalled:
1551 data_obj.insert(std::make_pair(kAction, picojson::value(kOnInstalled)));
1554 case Event::kUpdated:
1555 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUpdated)));
1557 case Event::kUninstalled:
1558 LoggerD("Uninstalled called");
1562 switch (event_type_) {
1563 case Event::kInstalled:
1564 case Event::kUpdated:
1566 pkgmgrinfo_appinfo_h handle = nullptr;
1567 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1568 LoggerE("Failed to get application information handle.");
1571 auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object())));
1572 ApplicationUtils::CreateApplicationInformation(
1573 handle, &info.first->second.get<picojson::object>());
1574 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1577 case Event::kUninstalled:
1578 LoggerD("Uninstalled called");
1582 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1584 for (auto instance : app_instance_list_) {
1585 Instance::PostMessage(instance, value.serialize().c_str());
1590 void GetApplicationIdsFromPackage(const char* package) {
1592 package_info_h package_info = nullptr;
1594 int ret = package_info_create(package, &package_info);
1595 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1596 LoggerE("Failed to create package info: %d (%s)", ret, get_error_message(ret));
1600 ret = package_info_foreach_app_from_package(package_info,
1601 PACKAGE_INFO_ALLAPP,
1602 ApplicationIdCallback,
1604 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1605 LoggerE("Failed to get application IDs: %d (%s)", ret, get_error_message(ret));
1608 ret = package_info_destroy(package_info);
1609 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1610 LoggerE("Failed to destroy package info: %d (%s)", ret, get_error_message(ret));
1614 void set_event_type(const char* type) {
1616 if (0 == strcasecmp(type, kInstallEvent)) {
1617 event_type_ = Event::kInstalled;
1618 } else if (0 == strcasecmp(type, kUpdateEvent)) {
1619 event_type_ = Event::kUpdated;
1620 } else if (0 == strcasecmp(type, kUninstallEvent)) {
1621 event_type_ = Event::kUninstalled;
1625 static bool ApplicationIdCallback(package_info_app_component_type_e comp_type,
1626 const char* app_id, void* user_data) {
1628 if (nullptr != app_id) {
1629 static_cast<ApplicationListChangedBroker*>(user_data)->app_list_.push_back(app_id);
1634 void HandleUninstallStart() {
1637 set_event_type(kUninstallEvent);
1640 void AddUninstalledAppId(const char* app_id) {
1642 if (nullptr != app_id) {
1643 app_list_.push_back(app_id);
1647 void HandleUninstallEnd() {
1649 for (auto& app_id : app_list_) {
1650 picojson::value value = picojson::value(picojson::object());
1651 picojson::object& data_obj = value.get<picojson::object>();
1653 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUninstalled)));
1654 data_obj.insert(std::make_pair(kData, picojson::value(app_id)));
1656 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1658 for (auto instance : app_instance_list_) {
1659 Instance::PostMessage(instance, value.serialize().c_str());
1665 std::vector<std::string> app_list_;
1666 std::vector<ApplicationInstance*> app_instance_list_;
1669 static ApplicationListChangedBroker g_application_list_changed_broker;
1671 void ApplicationManager::StartAppInfoEventListener(picojson::object* out) {
1674 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1675 if(nullptr == pkgmgr_client_handle_) {
1676 pkgmgr_client_handle_ = pkgmgr_client_new(PC_LISTENING);
1678 if(nullptr == pkgmgr_client_uninstall_handle_) {
1679 pkgmgr_client_uninstall_handle_ = pkgmgr_client_new(PC_LISTENING);
1682 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1683 if(nullptr != pkgmgr_client_handle_) {
1684 pkgmgr_client_free(pkgmgr_client_handle_);
1685 pkgmgr_client_handle_ = nullptr;
1687 if(nullptr != pkgmgr_client_uninstall_handle_) {
1688 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1689 pkgmgr_client_uninstall_handle_ = nullptr;
1691 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."), out);
1695 g_application_list_changed_broker.AddApplicationInstance(&instance_);
1697 pkgmgr_client_set_status_type(pkgmgr_client_handle_,
1698 PACKAGE_MANAGER_STATUS_TYPE_INSTALL | PACKAGE_MANAGER_STATUS_TYPE_UPGRADE);
1699 pkgmgr_client_set_status_type(pkgmgr_client_uninstall_handle_,
1700 PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL);
1702 pkgmgr_client_listen_status(pkgmgr_client_handle_,
1703 ApplicationListChangedBroker::ClientStatusListener,
1704 &g_application_list_changed_broker);
1705 pkgmgr_client_listen_status(pkgmgr_client_uninstall_handle_,
1706 ApplicationListChangedBroker::AppUninstallListener,
1707 &g_application_list_changed_broker);
1710 LoggerD("Broker callback is already registered.");
1713 ReportSuccess(*out);
1716 void ApplicationManager::StopAppInfoEventListener() {
1719 if (nullptr != pkgmgr_client_handle_ || nullptr != pkgmgr_client_uninstall_handle_) {
1720 if(nullptr != pkgmgr_client_handle_) {
1721 pkgmgr_client_free(pkgmgr_client_handle_);
1722 pkgmgr_client_handle_ = nullptr;
1724 if(nullptr != pkgmgr_client_uninstall_handle_) {
1725 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1726 pkgmgr_client_uninstall_handle_ = nullptr;
1728 g_application_list_changed_broker.RemoveApplicationInstance(&instance_);
1730 LoggerD("Broker callback is already unregistered.");
1734 void ApplicationManager::GetApplicationInformationSize(const picojson::value& args,
1735 picojson::object* out) {
1738 const auto& package_id = args.get("packageId");
1739 if (!package_id.is<std::string>()) {
1740 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), out);
1744 const std::string& package_id_str = package_id.get<std::string>();
1746 // get installed size from package server (to solve smack issue)
1747 pkgmgr_client* pc = pkgmgr_client_new(PC_REQUEST);
1750 if (nullptr == pc) {
1751 LoggerE("Failed to create pkgmgr client");
1753 size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL,
1754 package_id_str.c_str(), NULL, NULL, NULL);
1757 LoggerE("Failed to get installed size: %d (%s)", size, get_error_message(size));
1760 pkgmgr_client_free(pc);
1764 picojson::value result = picojson::value(picojson::object());
1765 picojson::object& result_obj = result.get<picojson::object>();
1766 result_obj.insert(std::make_pair("size", picojson::value(static_cast<double>(size))));
1768 ReportSuccess(result, *out);
1771 void ApplicationManager::BroadcastEventHelper(
1772 const picojson::value& args,
1773 picojson::object& out, bool trusted) {
1778 std::string event_str = args.get("name").get<std::string>();
1779 const char* event_name = event_str.c_str();
1781 bundle* data = bundle_create();
1786 ret = bundle_add(data, "data", args.get("data").serialize().c_str());
1788 if (ret != EVENT_ERROR_NONE) {
1789 LoggerE("bundle_add failed, error: %d (%s)", ret, get_error_message(ret));
1795 ret = event_publish_trusted_app_event(event_name, data);
1797 ret = event_publish_app_event(event_name, data);
1800 if (ret == EVENT_ERROR_NONE) {
1803 LoggerE("event_publish_app_event failed, error: %d (%s)", ret, get_error_message(ret));
1808 void ApplicationManager::OnEvent(const char* event_name,
1812 LOGGER(DEBUG) << event_name;
1814 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1816 if (!manager->event_callback_) {
1817 LOGGER(DEBUG) << "No event listener registered, skipping.";
1821 picojson::value event = picojson::value(picojson::object());
1822 picojson::object& event_o = event.get<picojson::object>();
1825 char* val = nullptr;
1827 if (event_map_.count(event_name)) { // system event
1828 const std::string& key = event_map_.at(event_name);
1829 std::string state = "true";
1831 ret = bundle_get_str(event_data, key.c_str(), &val);
1832 if (EVENT_ERROR_NONE != ret) {
1833 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1837 state = std::string(val);
1840 LoggerD("State is %s", state.c_str());
1841 event_o["value"] = picojson::value(state);
1843 } else { // user event
1844 ret = bundle_get_str(event_data, "data", &val);
1845 if (EVENT_ERROR_NONE != ret) {
1846 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1850 picojson::value data;
1852 picojson::parse(data, val, val + strlen(val), &err);
1854 LOGGER(ERROR) << "Failed to parse bundle data: " << err;
1858 event_o["data"] = data;
1861 LOGGER(DEBUG) << "event_name is: " << event_name;
1862 event_o["name"] = picojson::value(event_name);
1864 manager->event_callback_(&event);
1867 PlatformResult ApplicationManager::StartEventListener(const std::string& event_name,
1868 const JsonCallback& callback) {
1872 event_handler_h event_handler;
1874 ret = event_add_event_handler(event_name.c_str(), OnEvent, this, &event_handler);
1875 LoggerD("event_add_event_handler() result: %d (%s)", ret, get_error_message(ret));
1876 if (EVENT_ERROR_PERMISSION_DENIED == ret) {
1877 return LogAndCreateResult(ErrorCode::SECURITY_ERR, "The privilege is required",
1878 ("event_add_event_handler failed, error: %d", ret));
1879 } else if (EVENT_ERROR_NONE != ret) {
1880 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error setting event listener",
1881 ("event_add_event_handler failed, error: %d", ret));
1884 event_handler_map_[event_name] = event_handler;
1886 event_callback_ = callback;
1887 LOGGER(DEBUG) << "event_add_event_handler success";
1888 return PlatformResult(ErrorCode::NO_ERROR);
1891 void ApplicationManager::StopEventListener(const std::string& event_name) {
1895 event_handler_h event_handler;
1897 if (event_handler_map_.find(event_name) != event_handler_map_.end()) {
1898 event_handler = event_handler_map_[event_name];
1900 ret = event_remove_event_handler(event_handler);
1901 if (EVENT_ERROR_NONE != ret) {
1902 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
1906 event_handler_map_.erase(event_name);
1910 void ApplicationManager::OnStatusEvent(const char *type, const char *app_id,
1911 app_manager_event_type_e event_type,
1912 app_manager_event_state_e event_state,
1913 app_manager_event_h handle, void *user_data) {
1916 if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
1917 LoggerD("State different from completed");
1921 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1923 if (!manager || !manager->status_callback_) {
1924 LoggerD("No event listener registered, skipping.");
1929 switch (event_type) {
1930 case APP_MANAGER_EVENT_ENABLE_APP:
1933 case APP_MANAGER_EVENT_DISABLE_APP:
1934 status_type = false;
1937 LoggerD("Uknown status type skipping.");
1941 picojson::value event = picojson::value(picojson::object());
1942 picojson::object& event_o = event.get<picojson::object>();
1944 event_o[kStatusType] = picojson::value(status_type);
1945 event_o[kAppId] = picojson::value(app_id);
1946 event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
1948 manager->status_callback_(&event);
1952 PlatformResult ApplicationManager::GetContextHistory(const picojson::value& args, picojson::object* out,
1953 common::PlatformResult (*modify_filter_cb)(const picojson::value&, const context_history_filter_h, context_history_data_e* data_type),
1954 common::PlatformResult (*add_attributes_to_object)(const context_history_record_h, picojson::object*)) {
1956 context_history_list_h list = nullptr;
1957 context_history_h handle = nullptr;
1958 context_history_filter_h filter = nullptr;
1961 context_history_list_destroy(list);
1962 context_history_destroy(handle);
1963 context_history_filter_destroy(filter);
1966 int ret = context_history_create(&handle);
1967 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1968 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to create context handle.",
1969 ("Failed to create context handle: %d (%s)", ret, get_error_message(ret)));
1972 ret = context_history_filter_create(&filter);
1973 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1974 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to create filter handle.",
1975 ("Failed to create filter handle: %d (%s)", ret, get_error_message(ret)));
1978 context_history_data_e data_type;
1980 PlatformResult result = modify_filter_cb(args, filter, &data_type);
1985 picojson::value result_array = picojson::value(picojson::array());
1986 picojson::array& array_obj = result_array.get<picojson::array>();
1988 ret = context_history_get_list(handle, data_type, filter, &list);
1989 if (CONTEXT_HISTORY_ERROR_NO_DATA == ret) {
1990 ReportSuccess(result_array, *out);
1991 return PlatformResult(ErrorCode::NO_ERROR);
1992 } else if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1993 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list.",
1994 ("Failed to get list: %d (%s)", ret, get_error_message(ret)));
1998 ret = context_history_list_get_count(list, &size);
1999 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2000 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list size.",
2001 ("Failed to get list size: %d (%s)", ret, get_error_message(ret)));
2004 array_obj.resize(size, picojson::value(picojson::object()));
2006 for (int i = 0; i < size; ++i) {
2007 context_history_record_h record = nullptr;
2009 context_history_record_destroy(record);
2012 ret = context_history_list_get_current(list, &record);
2013 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2014 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get current record.",
2015 ("Failed to get current record: %d (%s)", ret, get_error_message(ret)));
2018 result = add_attributes_to_object(record, &array_obj[i].get<picojson::object>());
2023 ret = context_history_list_move_next(list);
2024 if (CONTEXT_HISTORY_ERROR_NONE != ret && CONTEXT_HISTORY_ERROR_NO_DATA != ret) {
2025 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to move iterator.",
2026 ("Failed to move iterator: %d (%s)", ret, get_error_message(ret)));
2030 ReportSuccess(result_array, *out);
2031 return PlatformResult(ErrorCode::NO_ERROR);
2035 PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
2038 int ret = APP_MANAGER_ERROR_NONE;
2040 if (!app_status_handle_) {
2041 ret = app_manager_event_create(&app_status_handle_);
2042 if (APP_MANAGER_ERROR_NONE != ret) {
2043 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
2044 ("app_manager_event_create failed, error: %d", ret));
2047 ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
2048 if (APP_MANAGER_ERROR_NONE != ret) {
2049 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
2050 ("app_manager_event_set_status failed, error: %d", ret));
2054 status_callback_ = callback;
2055 ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
2056 if (APP_MANAGER_ERROR_NONE != ret) {
2057 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
2058 ("app_manager_set_event_cb failed, error: %d", ret));
2061 return PlatformResult(ErrorCode::NO_ERROR);
2064 PlatformResult ApplicationManager::StopStatusChangeListener() {
2067 if (app_status_handle_) {
2068 int ret = app_manager_unset_event_cb(app_status_handle_);
2069 if (APP_MANAGER_ERROR_NONE != ret) {
2070 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
2071 ("app_manager_unset_event_cb failed, error: %d", ret));
2075 return PlatformResult(ErrorCode::NO_ERROR);
2078 } // namespace application
2079 } // namespace extension