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"
22 #include <type_traits>
24 #include <app_control_internal.h>
26 #include <app_manager_extension.h>
30 #include <bundle_internal.h>
31 #include <package_manager.h>
32 #include <pkgmgr-info.h>
33 #include <pkgmgr_installer.h>
35 #include "common/current_application.h"
36 #include "common/logger.h"
37 #include "common/platform_result.h"
38 #include "common/scope_exit.h"
39 #include "common/task-queue.h"
40 #include "common/tools.h"
42 #include "application/application_instance.h"
43 #include "application/application_utils.h"
45 using namespace common;
46 using namespace tools;
49 namespace application {
52 const std::string kTizenApisFileScheme = "file://";
53 const std::string kTizenApisAppSlash = "/";
54 const std::string kTizenApisAppShared = "shared";
56 const char* kStartKey = PKGMGR_INSTALLER_START_KEY_STR;
57 const char* kEndKey = PKGMGR_INSTALLER_END_KEY_STR;
58 const char* kOkValue = PKGMGR_INSTALLER_OK_EVENT_STR;
59 const char* kInstallEvent = PKGMGR_INSTALLER_INSTALL_EVENT_STR;
60 const char* kUpdateEvent = PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
61 const char* kUninstallEvent = PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
63 const char* kAppidKey = "appid";
65 const std::string kAction = "action";
66 const std::string kCallbackId = "callbackId";
67 const std::string kOnInstalled = "oninstalled";
68 const std::string kOnUpdated = "onupdated";
69 const std::string kOnUninstalled = "onuninstalled";
70 const std::string kData = "data";
71 const std::string kStatusType = "statusType";
72 const std::string kAppId = "appId";
73 const std::string kListenerId = "listenerId";
74 const std::string kAppStatusChangeListener = "AppStatusChangeListener";
75 const std::string kAppUsageModeFrequently = "FREQUENTLY";
76 const std::string kAppUsageModeRecently = "RECENTLY";
78 const std::map<std::string, std::string> event_map_ = {
79 {SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
80 {SYSTEM_EVENT_BATTERY_LEVEL_STATUS, EVENT_KEY_BATTERY_LEVEL_STATUS},
81 {SYSTEM_EVENT_USB_STATUS, EVENT_KEY_USB_STATUS},
82 {SYSTEM_EVENT_EARJACK_STATUS, EVENT_KEY_EARJACK_STATUS},
83 {SYSTEM_EVENT_DISPLAY_STATE, EVENT_KEY_DISPLAY_STATE},
84 {SYSTEM_EVENT_LOW_MEMORY, EVENT_KEY_LOW_MEMORY},
85 {SYSTEM_EVENT_WIFI_STATE, EVENT_KEY_WIFI_STATE},
86 {SYSTEM_EVENT_BT_STATE, EVENT_KEY_BT_STATE},
87 {SYSTEM_EVENT_LOCATION_ENABLE_STATE, EVENT_KEY_LOCATION_ENABLE_STATE},
88 {SYSTEM_EVENT_GPS_ENABLE_STATE, EVENT_KEY_GPS_ENABLE_STATE},
89 {SYSTEM_EVENT_NPS_ENABLE_STATE, EVENT_KEY_NPS_ENABLE_STATE},
90 {SYSTEM_EVENT_INCOMING_MSG, EVENT_KEY_MSG_TYPE},
91 {SYSTEM_EVENT_TIME_ZONE, EVENT_KEY_TIME_ZONE},
92 {SYSTEM_EVENT_HOUR_FORMAT, EVENT_KEY_HOUR_FORMAT},
93 {SYSTEM_EVENT_LANGUAGE_SET, EVENT_KEY_LANGUAGE_SET},
94 {SYSTEM_EVENT_REGION_FORMAT, EVENT_KEY_REGION_FORMAT},
95 {SYSTEM_EVENT_SILENT_MODE, EVENT_KEY_SILENT_MODE},
96 {SYSTEM_EVENT_VIBRATION_STATE, EVENT_KEY_VIBRATION_STATE},
97 {SYSTEM_EVENT_SCREEN_AUTOROTATE_STATE, EVENT_KEY_SCREEN_AUTOROTATE_STATE},
98 {SYSTEM_EVENT_MOBILE_DATA_STATE, EVENT_KEY_MOBILE_DATA_STATE},
99 {SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
100 {SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}};
102 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
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 for (auto it = event_handler_map_.begin(); it != event_handler_map_.end();) {
123 int ret = event_remove_event_handler(it->second);
124 if (EVENT_ERROR_NONE != ret) {
125 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
127 it = event_handler_map_.erase(it);
130 if (app_status_handle_) {
131 int ret = app_manager_event_destroy(app_status_handle_);
132 if (APP_MANAGER_ERROR_NONE != ret) {
133 LoggerE("app_manager_event_destroy failed, error: %d", ret);
138 void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
141 // obtain handle to application info
142 pkgmgrinfo_appinfo_h handle;
143 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
144 if (PMINFO_R_OK != ret) {
145 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app info."), out,
146 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
150 picojson::value app_info = picojson::value(picojson::object());
151 picojson::object& app_info_obj = app_info.get<picojson::object>();
153 utils::CreateApplicationInformation(handle, &app_info_obj);
154 pkgmgrinfo_appinfo_destroy_appinfo(handle);
156 picojson::value result = picojson::value(picojson::object());
157 picojson::object& result_obj = result.get<picojson::object>();
159 result_obj.insert(std::make_pair(
161 picojson::value(std::to_string(CurrentApplication::GetInstance().GetProcessId()))));
162 result_obj.insert(std::make_pair("appInfo", app_info));
164 ReportSuccess(result, *out);
167 class TerminateHandler {
169 TerminateHandler(int callback_id, ApplicationInstance* app_instance)
170 : callback_handle_(callback_id), pid_(-1), timeout_id_(0), app_instance_(app_instance) {
173 void set_pid(pid_t pid) {
181 void Invoke(const std::shared_ptr<picojson::value>& response) {
184 if (timeout_id_ > 0) {
185 // cancel terminate callback
186 g_source_remove(timeout_id_);
190 ApplicationInstance* app_instance = this->app_instance_;
191 int callback_id = this->callback_handle_;
192 TaskQueue::GetInstance().Async<picojson::value>(
193 [callback_id, app_instance](const std::shared_ptr<picojson::value>& response) {
194 picojson::object& obj = response->get<picojson::object>();
196 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
197 Instance::PostMessage(app_instance, response->serialize().c_str());
203 int callback_handle_;
206 ApplicationInstance* app_instance_;
209 #define CHECK_RESULT(result, response, handler) \
210 if (result.IsError()) { \
211 LogAndReportError(result, &response->get<picojson::object>()); \
212 handler->Invoke(response); \
217 void ApplicationManager::AsyncResponse(const PlatformResult& result,
218 std::shared_ptr<picojson::value>* response) {
220 LogAndReportError(result, &(*response)->get<picojson::object>());
222 TaskQueue::GetInstance().Async<picojson::value>(
223 [this](const std::shared_ptr<picojson::value>& response) {
224 Instance::PostMessage(&this->instance_, response->serialize().c_str());
229 void ApplicationManager::Kill(const picojson::value& args) {
232 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
234 int callback_id = -1;
235 const auto& callback = args.get(kCallbackId);
236 if (callback.is<double>()) {
237 callback_id = static_cast<int>(callback.get<double>());
240 const auto& context = args.get("contextId");
241 if (!context.is<std::string>()) {
242 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
245 const std::string& context_id = context.get<std::string>();
247 if (context_id.empty() && result.IsSuccess()) {
248 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID is empty.");
251 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
252 picojson::object& obj = response->get<picojson::object>();
253 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
255 if (result.IsError()) {
256 LoggerE("Failed args.get");
257 AsyncResponse(result, &response);
261 auto kill = [this, callback_id, context_id]() -> void {
264 std::shared_ptr<picojson::value> response =
265 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
267 TerminateHandler* handler = new TerminateHandler(callback_id, &this->instance_);
268 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
272 pid = std::stoi(context_id);
274 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
275 CHECK_RESULT(result, response, handler)
279 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID cannot be negative value.");
280 CHECK_RESULT(result, response, handler)
283 // if kill request comes for current context, throw InvalidValuesException
284 if (CurrentApplication::GetInstance().GetProcessId() == pid) {
286 LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Cannot kill current application.");
287 CHECK_RESULT(result, response, handler)
290 LoggerD("Kill, pid: %d", pid);
292 char* app_id = nullptr;
293 int ret = app_manager_get_app_id(pid, &app_id);
294 // automatically release the memory
295 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
297 if (APP_MANAGER_ERROR_NONE != ret) {
298 result = LogAndCreateResult(
299 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
300 ("Failed to get application ID, error: %d (%s)", ret, get_error_message(ret)));
301 CHECK_RESULT(result, response, handler)
304 LoggerD("Kill, app ID: %s", app_id);
306 // acquire application context
307 app_context_h app_context = nullptr;
309 ret = app_manager_get_app_context(app_id, &app_context);
310 std::unique_ptr<std::remove_pointer<app_context_h>::type, int (*)(app_context_h)>
311 app_context_ptr(app_context, &app_context_destroy); // automatically release the memory
313 if (APP_MANAGER_ERROR_NONE != ret) {
314 result = LogAndCreateResult(
315 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
316 ("Failed to get application context handle: %d (%s)", ret, get_error_message(ret)));
317 CHECK_RESULT(result, response, handler)
320 auto terminate_callback = [](app_context_h app_context, app_context_event_e event,
322 LoggerD("terminate_callback: %d", event);
324 if (APP_CONTEXT_EVENT_TERMINATED != event) {
325 LoggerD("ignoring event");
330 int ret = app_context_get_pid(app_context, &pid);
332 if (APP_MANAGER_ERROR_NONE != ret) {
333 LoggerE("Failed to get pid of terminated app: %d (%s)", ret, get_error_message(ret));
337 TerminateHandler* handler = static_cast<TerminateHandler*>(user_data);
339 LoggerD("Expected PID: %d, got: %d", handler->pid(), pid);
341 if (handler->pid() == pid) {
342 std::shared_ptr<picojson::value> response =
343 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
344 ReportSuccess(response->get<picojson::object>());
345 handler->Invoke(response);
350 LoggerD("Kill, setting callback");
351 handler->set_pid(pid);
352 ret = app_manager_set_app_context_event_cb(terminate_callback, handler);
354 if (APP_MANAGER_ERROR_NONE != ret) {
355 result = LogAndCreateResult(
356 ErrorCode::UNKNOWN_ERR, "Failed to register termination callback.",
357 ("Error while registering app context event: %d (%s)", ret, get_error_message(ret)));
358 CHECK_RESULT(result, response, handler)
361 LoggerD("Kill, calling native function");
363 // terminate application
364 ret = app_manager_terminate_app(app_context);
366 if (APP_MANAGER_ERROR_NONE != ret) {
367 result = LogAndCreateResult(
368 ErrorCode::UNKNOWN_ERR, "Failed to terminate application.",
369 ("Failed to terminate application: %d (%s)", ret, get_error_message(ret)));
370 CHECK_RESULT(result, response, handler)
373 LoggerD("Kill, end, waiting for notification");
381 PlatformResult PrepareAppControlForLaunchAppControl(const picojson::value& args,
382 app_control_h* app_control) {
385 const auto& control = args.get("appControl");
386 if (!control.is<picojson::object>()) {
387 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
389 const picojson::object& app_control_obj = control.get<picojson::object>();
391 app_control_h tmp_app_control = nullptr;
392 auto result = utils::ApplicationControlToService(app_control_obj, &tmp_app_control);
393 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
394 app_control_ptr(tmp_app_control, &app_control_destroy);
396 if (result.IsError()) {
397 LoggerE("Application control to service failed.");
402 const auto& id = args.get("id");
403 if (id.is<std::string>()) {
404 app_id = id.get<std::string>();
407 if (!app_id.empty()) {
408 LoggerD("app_id: %s", app_id.c_str());
410 int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
412 if (APP_CONTROL_ERROR_NONE != ret) {
413 LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
414 return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
418 *app_control = app_control_ptr.release();
420 return PlatformResult(ErrorCode::NO_ERROR);
425 void ApplicationManager::LaunchAppControl(const picojson::value& args) {
428 int callback_id = -1;
429 const auto& callback = args.get(kCallbackId);
430 if (callback.is<double>()) {
431 callback_id = static_cast<int>(callback.get<double>());
434 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
435 picojson::object& response_obj = response->get<picojson::object>();
437 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
439 app_control_h app_control = nullptr;
440 auto prepare_app_control_result = PrepareAppControlForLaunchAppControl(args, &app_control);
441 if (prepare_app_control_result.IsError()) {
442 AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
446 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
447 app_control_ptr(app_control, &app_control_destroy);
449 std::string reply_callback_id;
450 const auto& reply = args.get("replyCallback");
451 if (reply.is<std::string>()) {
452 reply_callback_id = reply.get<std::string>();
455 struct LaunchAppControlCallbackData {
456 ApplicationInstance* instance;
457 std::shared_ptr<picojson::value> response;
458 std::string reply_callback_id;
459 }* launch_app_user_data = new (std::nothrow)
460 LaunchAppControlCallbackData{&this->instance_, response, reply_callback_id};
462 if (!launch_app_user_data) {
463 LoggerE("Memory allocation fail!");
464 AsyncResponse(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response);
468 app_control_reply_cb reply_callback = nullptr;
469 if (!reply_callback_id.empty()) {
470 launch_app_user_data->reply_callback_id = reply_callback_id;
472 reply_callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
474 ScopeLogger("reply_callback");
476 LaunchAppControlCallbackData* callback_data =
477 static_cast<LaunchAppControlCallbackData*>(user_data);
478 if (!callback_data) {
479 LoggerD("reply_callback failed: user_data is nullptr");
483 picojson::value return_value = picojson::value(picojson::object());
484 picojson::object& return_value_obj = return_value.get<picojson::object>();
485 return_value_obj.insert(
486 std::make_pair(kListenerId, picojson::value(callback_data->reply_callback_id)));
488 if (APP_CONTROL_RESULT_SUCCEEDED == result) {
489 LoggerD("App started");
490 return_value_obj.insert(std::make_pair("data", picojson::value(picojson::array())));
491 if (!utils::ServiceToApplicationControlDataArray(
492 reply, &return_value_obj.find("data")->second.get<picojson::array>())) {
493 return_value_obj.erase("data");
495 ReportSuccess(return_value_obj);
497 ReportError(return_value_obj);
500 Instance::PostMessage(callback_data->instance, return_value.serialize().c_str());
501 delete callback_data;
505 app_control_result_cb result_callback = [](app_control_h launch_request,
506 app_control_error_e launch_result, void* user_data) {
507 ScopeLogger("LaunchAppControl result_callback");
509 LaunchAppControlCallbackData* callback_data =
510 static_cast<LaunchAppControlCallbackData*>(user_data);
512 auto result = utils::TranslateAppControlError(launch_result);
514 if (result.IsError()) {
515 LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
517 ReportSuccess(callback_data->response->get<picojson::object>());
520 Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
522 if (result.IsError() || (callback_data->reply_callback_id).empty()) {
523 delete callback_data;
528 * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
529 * Previous implementation, using synchronous app_control_send_launch_request,
530 * tries to launch the application 3 times, before reporting an error.
531 * New implementation, using app_control_send_launch_request_async makes only one attempt.
532 * If problems, such as failed application start occur, multiple attempts may solve the problem.
534 auto launch_result = utils::TranslateAppControlError(
535 static_cast<app_control_error_e>(app_control_send_launch_request_async(
536 app_control_ptr.get(), result_callback, reply_callback, launch_app_user_data)));
538 if (launch_result.IsError()) {
539 delete launch_app_user_data;
540 AsyncResponse(launch_result, &response);
542 LoggerD("App launched");
548 PlatformResult TranslateLaunchError(app_control_error_e return_code) {
551 auto result = utils::TranslateAppControlError(return_code);
552 if (ErrorCode::SECURITY_ERR == result.error_code()) {
553 result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
559 PlatformResult PrepareAppControlForLaunch(const picojson::value& args, app_control_h* app_control) {
562 const auto& app_id = args.get("id");
563 if (!app_id.is<std::string>()) {
564 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
566 const auto app_id_str = app_id.get<std::string>();
568 app_control_h tmp_app_control = nullptr;
569 int result = app_control_create(&tmp_app_control);
570 if (APP_CONTROL_ERROR_NONE != result) {
571 LoggerD("app_control_create() failed: %d (%s)", result, get_error_message(result));
572 return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
575 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
576 app_control_ptr(tmp_app_control, &app_control_destroy);
578 if (!app_id_str.empty()) {
579 LoggerD("app_id: %s", app_id_str.c_str());
581 int ret = app_control_set_app_id(app_control_ptr.get(), app_id_str.c_str());
583 if (APP_CONTROL_ERROR_NONE != ret) {
584 LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
585 return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
589 *app_control = app_control_ptr.release();
591 return PlatformResult(ErrorCode::NO_ERROR);
595 void ApplicationManager::Launch(const picojson::value& args) {
598 int callback_id = -1;
599 const auto& callback = args.get(kCallbackId);
600 if (callback.is<double>()) {
601 callback_id = static_cast<int>(callback.get<double>());
604 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
605 picojson::object& response_obj = response->get<picojson::object>();
607 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
609 app_control_h app_control = nullptr;
610 auto prepare_app_control_result = PrepareAppControlForLaunch(args, &app_control);
611 if (prepare_app_control_result.IsError()) {
612 AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
616 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
617 app_control_ptr(app_control, &app_control_destroy);
619 struct LaunchCallbackData {
620 ApplicationInstance* instance;
621 std::shared_ptr<picojson::value> response;
622 }* launch_user_data = new (std::nothrow) LaunchCallbackData{&this->instance_, response};
624 app_control_result_cb result_callback = [](app_control_h launch_request,
625 app_control_error_e launch_result, void* user_data) {
626 ScopeLogger("Launch result_callback");
628 LaunchCallbackData* callback_data = static_cast<LaunchCallbackData*>(user_data);
630 auto result = TranslateLaunchError(launch_result);
632 if (result.IsError()) {
633 LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
635 ReportSuccess(callback_data->response->get<picojson::object>());
638 Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
640 delete callback_data;
644 * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
645 * Previous implementation, using synchronous app_control_send_launch_request,
646 * tries to launch the application 3 times, before reporting an error.
647 * New implementation, using app_control_send_launch_request_async makes only one attempt.
648 * If problems, such as failed application start occur, multiple attempts may solve the problem.
650 auto launch_result = TranslateLaunchError(static_cast<app_control_error_e>(
651 app_control_send_resume_request(app_control_ptr.get(), result_callback, launch_user_data)));
653 if (launch_result.IsError()) {
654 delete launch_user_data;
655 AsyncResponse(launch_result, &response);
657 LoggerD("App launched");
661 // internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
662 // public CAPI did not handling APP_CONTROL_ERROR_APP_NOT_FOUND
663 int app_control_foreach_app_matched_internal(app_control_h app_control,
664 app_control_app_matched_cb callback, void* user_data) {
667 app_control_h app_control;
668 app_control_app_matched_cb callback;
671 } foreach_context_launchable_app_t_internal;
673 // internal impl of app_control_cb_broker_foreach_app_matched()
674 auto app_control_cb_broker_foreach_app_matched_internal = [](const char* package,
677 "Entered into asynchronous function, app_control_cb_broker_foreach_app_matched_internal's "
679 foreach_context_launchable_app_t_internal* foreach_context;
680 app_control_app_matched_cb app_matched_cb;
682 if (package == NULL || data == NULL) {
683 LoggerE("APP_CONTROL_ERROR_INVALID_PARAMETER");
687 foreach_context = (foreach_context_launchable_app_t_internal*)data;
688 if (foreach_context->foreach_break == true) return -1;
690 app_matched_cb = foreach_context->callback;
691 if (app_matched_cb != NULL) {
692 bool stop_foreach = false;
695 !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
697 foreach_context->foreach_break = stop_foreach;
703 foreach_context_launchable_app_t_internal foreach_context = {.app_control = app_control,
704 .callback = callback,
705 .user_data = user_data,
706 .foreach_break = false};
708 bundle* bundle_data = NULL;
709 app_control_to_bundle(app_control, &bundle_data);
711 int ret = appsvc_usr_get_list(bundle_data, app_control_cb_broker_foreach_app_matched_internal,
712 &foreach_context, getuid());
716 case APPSVC_RET_EINVAL:
717 return APP_CONTROL_ERROR_INVALID_PARAMETER;
719 case APPSVC_RET_ENOMATCH:
720 return APP_CONTROL_ERROR_APP_NOT_FOUND;
723 return APP_CONTROL_ERROR_LAUNCH_FAILED;
727 return APP_CONTROL_ERROR_NONE;
730 void ApplicationManager::FindAppControl(const picojson::value& args) {
733 int callback_id = -1;
734 const auto& callback = args.get(kCallbackId);
735 if (callback.is<double>()) {
736 callback_id = static_cast<int>(callback.get<double>());
739 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
740 picojson::object& response_obj = response->get<picojson::object>();
742 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
744 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
745 const auto& control = args.get("appControl");
746 if (!control.is<picojson::object>()) {
747 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
748 AsyncResponse(result, &response);
752 const picojson::object& app_control_obj = control.get<picojson::object>();
754 app_control_h app_control = nullptr;
755 result = utils::ApplicationControlToService(app_control_obj, &app_control);
756 std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
757 app_control, &app_control_destroy); // automatically release the memory
759 if (result.IsError()) {
760 LoggerE("Application control to service failed.");
761 AsyncResponse(result, &response);
765 auto find = [app_control_ptr](const std::shared_ptr<picojson::value>& response) -> void {
766 ScopeLogger("Entered into asynchronous function, find");
767 auto app_control_matched = [](app_control_h app_control, const char* appid,
768 void* user_data) -> bool {
769 ScopeLogger("Entered into asynchronous function, app_control_matched");
770 if (nullptr == appid) {
771 LoggerD("appid is NULL");
775 pkgmgrinfo_appinfo_h handle;
776 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &handle);
777 if (PMINFO_R_OK != ret) {
778 LoggerE("Failed to get appInfo: %d (%s)", ret, get_error_message(ret));
780 picojson::array* array = static_cast<picojson::array*>(user_data);
781 array->push_back(picojson::value(picojson::object()));
783 utils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
784 pkgmgrinfo_appinfo_destroy_appinfo(handle);
790 picojson::object& response_obj = response->get<picojson::object>();
791 auto it_result = response_obj.find("result");
792 picojson::object& result_obj = it_result->second.get<picojson::object>();
794 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())));
796 int ret = app_control_foreach_app_matched_internal(app_control_ptr.get(), app_control_matched,
797 &array.first->second.get<picojson::array>());
799 if (APP_CONTROL_ERROR_NONE != ret) {
800 if (APP_CONTROL_ERROR_APP_NOT_FOUND == ret) {
801 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Matched Application not found"),
802 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
803 get_error_message(ret)));
804 } else if (APP_CONTROL_ERROR_LAUNCH_FAILED == ret) {
806 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error"), &response_obj,
807 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
808 } else if (APP_CONTROL_ERROR_INVALID_PARAMETER == ret) {
809 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed"),
810 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
811 get_error_message(ret)));
813 // remove copied ApplicationControl from result
814 response_obj.erase(it_result);
816 ReportSuccess(response_obj);
820 auto find_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
821 ScopeLogger("Entered into asynchronous function, find_response");
822 Instance::PostMessage(&this->instance_, response->serialize().c_str());
825 // prepare result object, we need to do that here, as input parameter is passed to result callback
826 auto ret = response_obj.insert(std::make_pair("result", picojson::value(picojson::object())));
827 // reinsert application control
828 ret.first->second.get<picojson::object>().insert(
829 std::make_pair("appControl", args.get("appControl")));
831 TaskQueue::GetInstance().Queue<picojson::value>(find, find_response, response);
834 void ApplicationManager::GetAppsContext(const picojson::value& args) {
837 int callback_id = -1;
838 const auto& callback = args.get(kCallbackId);
839 if (callback.is<double>()) {
840 callback_id = static_cast<int>(callback.get<double>());
843 auto get_apps_context = [](const std::shared_ptr<picojson::value>& response) -> void {
844 picojson::object& response_obj = response->get<picojson::object>();
845 picojson::value result = picojson::value(picojson::object());
846 picojson::object& result_obj = result.get<picojson::object>();
847 picojson::array& array =
848 result_obj.insert(std::make_pair("contexts", picojson::value(picojson::array())))
849 .first->second.get<picojson::array>();
851 auto app_context_cb = [](app_context_h app_context, void* user_data) -> bool {
852 if (nullptr == user_data) {
856 picojson::array* array = static_cast<picojson::array*>(user_data);
857 array->push_back(picojson::value(picojson::object()));
859 if (!utils::CreateApplicationContext(app_context, &array->back().get<picojson::object>())) {
867 int ret = app_manager_foreach_app_context(app_context_cb, &array);
869 if (APP_MANAGER_ERROR_NONE != ret) {
871 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
872 ("app_manager_foreach_app_context error: %d (%s)", ret, get_error_message(ret)));
874 ReportSuccess(result, response_obj);
878 auto get_apps_context_response =
879 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
880 picojson::object& obj = response->get<picojson::object>();
881 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
882 Instance::PostMessage(&this->instance_, response->serialize().c_str());
885 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
887 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_context, get_apps_context_response,
891 void ApplicationManager::GetAppContext(const picojson::value& args, picojson::object* out) {
895 const auto& context_id = args.get("contextId");
896 if (context_id.is<std::string>()) {
898 pid = std::stoi(context_id.get<std::string>());
900 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert context id."),
905 pid = CurrentApplication::GetInstance().GetProcessId();
908 char* app_id = nullptr;
910 int ret = app_manager_get_app_id(pid, &app_id);
911 // automatically release the memory
912 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
914 if (APP_MANAGER_ERROR_NONE != ret || nullptr == app_id) {
916 case APP_MANAGER_ERROR_NO_SUCH_APP:
917 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "No such application exist."), out,
918 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_NO_SUCH_APP"));
921 case APP_MANAGER_ERROR_INVALID_PARAMETER:
922 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Application not found."), out,
923 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_INVALID_PARAMETER"));
928 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), out,
929 ("app_manager_get_app_id returned: %d (%s)", ret, get_error_message(ret)));
934 picojson::value result = picojson::value(picojson::object());
935 utils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
937 ReportSuccess(result, *out);
940 void ApplicationManager::GetAppsInfo(const picojson::value& args) {
943 int callback_id = -1;
944 const auto& callback = args.get(kCallbackId);
945 if (callback.is<double>()) {
946 callback_id = static_cast<int>(callback.get<double>());
949 auto get_apps_info = [](const std::shared_ptr<picojson::value>& response) -> void {
950 ScopeLogger("Entered into asynchronous function, get_apps_info");
951 picojson::object& response_obj = response->get<picojson::object>();
952 picojson::value result = picojson::value(picojson::object());
953 picojson::object& result_obj = result.get<picojson::object>();
954 picojson::array& array =
955 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())))
956 .first->second.get<picojson::array>();
958 auto app_info_cb = [](pkgmgrinfo_appinfo_h handle, void* user_data) -> int {
959 ScopeLogger("Entered into asynchronous function, app_info_cb");
960 if (nullptr == user_data) {
964 picojson::array* array = static_cast<picojson::array*>(user_data);
965 array->push_back(picojson::value(picojson::object()));
967 utils::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 =
983 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
984 ScopeLogger("Entered into asynchronous function, get_apps_info_response");
985 picojson::object& obj = response->get<picojson::object>();
986 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
987 Instance::PostMessage(&this->instance_, response->serialize().c_str());
990 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
992 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_info, get_apps_info_response, data);
995 void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object* out) {
998 pkgmgrinfo_appinfo_h handle = nullptr;
1000 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1001 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out);
1005 picojson::value result = picojson::value(picojson::object());
1006 utils::CreateApplicationInformation(handle, &result.get<picojson::object>());
1007 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1009 ReportSuccess(result, *out);
1012 char* ApplicationManager::GetPackageId(const std::string& app_id) {
1015 char* pkg_id = nullptr;
1017 int ret = app_manager_get_app_info(app_id.c_str(), &handle);
1018 if (APP_MANAGER_ERROR_NONE != ret) {
1019 LoggerE("Failed to get app info: %d (%s)", ret, get_error_message(ret));
1023 ret = app_info_get_package(handle, &pkg_id);
1024 if (APP_MANAGER_ERROR_NONE != ret) {
1025 LoggerE("Failed to get package id: %d (%s)", ret, get_error_message(ret));
1029 ret = app_info_destroy(handle);
1030 if (APP_MANAGER_ERROR_NONE != ret) {
1031 LoggerE("Failed to destroy app info: %d (%s)", ret, get_error_message(ret));
1037 void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object* out) {
1040 char* package_id = nullptr;
1042 package_id = GetPackageId(app_id);
1043 // automatically release the memory
1044 std::unique_ptr<char, void (*)(void*)> package_id_ptr(package_id, &std::free);
1047 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1051 package_info_h pkg_info = nullptr;
1052 int ret = package_info_create(package_id, &pkg_info);
1054 std::unique_ptr<std::remove_pointer<package_info_h>::type, int (*)(package_info_h)> pkg_info_ptr(
1055 pkg_info, &package_info_destroy); // automatically release the memory
1057 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1058 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1059 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1063 auto cert_info_cb = [](package_info_h handle, package_cert_type_e cert_type,
1064 const char* cert_value, void* user_data) -> bool {
1065 const char* cert_name = nullptr;
1067 switch (cert_type) {
1068 case PACKAGE_INFO_AUTHOR_ROOT_CERT:
1069 cert_name = "AUTHOR_ROOT";
1071 case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT:
1072 cert_name = "AUTHOR_INTERMEDIATE";
1074 case PACKAGE_INFO_AUTHOR_SIGNER_CERT:
1075 cert_name = "AUTHOR_SIGNER";
1077 case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT:
1078 cert_name = "DISTRIBUTOR_ROOT";
1080 case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT:
1081 cert_name = "DISTRIBUTOR_INTERMEDIATE";
1083 case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT:
1084 cert_name = "DISTRIBUTOR_SIGNER";
1086 case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT:
1087 cert_name = "DISTRIBUTOR2_ROOT";
1089 case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT:
1090 cert_name = "DISTRIBUTOR2_INTERMEDIATE";
1092 case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT:
1093 cert_name = "DISTRIBUTOR2_SIGNER";
1096 LoggerD("Unknown certificate type: %d", cert_type);
1100 picojson::array* array = static_cast<picojson::array*>(user_data);
1101 array->push_back(picojson::value(picojson::object()));
1103 utils::CreateApplicationCertificate(cert_name, cert_value,
1104 &array->back().get<picojson::object>());
1109 picojson::value result = picojson::value(picojson::array());
1111 ret = package_info_foreach_cert_info(pkg_info, cert_info_cb, &result.get<picojson::array>());
1113 if ((PACKAGE_MANAGER_ERROR_NONE != ret) && (PACKAGE_MANAGER_ERROR_IO_ERROR != ret)) {
1114 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get certificates info."),
1116 ("Failed to get certificates info: %d (%s)", ret, get_error_message(ret)));
1120 ReportSuccess(result, *out);
1123 void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::object* out) {
1125 // this implementation assumes that shared/trusted path is the obligatory member of application
1126 // and it is used to extract the parent directory 'shared'
1127 char* path = nullptr;
1128 int ret = app_manager_get_shared_trusted_path(app_id.c_str(), &path);
1129 if (APP_MANAGER_ERROR_NONE != ret) {
1130 // if the application does not exist, there is no need to check "res" directory
1131 if (APP_MANAGER_ERROR_NO_SUCH_APP == ret) {
1132 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get shared URI."), out);
1136 // if the shared_trusted directory is not properly returned, gathering the shared/res path,
1137 // which is the obligatory member. The global path could be different then:
1138 // e.g. instead of path: /opt/usr/home/owner/apps_rw/org.example.basic/shared/
1139 // returned path is: /opt/usr/globalapps/org.example.basic/shared/
1141 "app_manager_get_shared_trusted_path failed(), trying "
1142 "app_manager_get_shared_resource_path() to gather path");
1143 int ret = app_manager_get_shared_resource_path(app_id.c_str(), &path);
1144 if (APP_MANAGER_ERROR_NONE != ret) {
1145 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get shared URI."), out);
1150 std::string path_str = path;
1153 std::string shared_path = path_str.substr(0, path_str.rfind("/", path_str.length() - 2));
1155 // checking if path is valid
1156 struct stat stat_res;
1157 if (0 != stat(shared_path.c_str(), &stat_res)) {
1158 LoggerW("Path %s does not exist", shared_path.c_str());
1159 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get shared URI."), out);
1163 picojson::value result = picojson::value(kTizenApisFileScheme + shared_path);
1164 ReportSuccess(result, *out);
1167 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1168 PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args,
1169 const context_history_filter_h filter,
1170 context_history_data_e* data_type_out) {
1172 int ret = CONTEXT_HISTORY_ERROR_NONE;
1173 int limit = kMaximumBatteryRetrievedObjects;
1174 if (args.contains("limit")) {
1175 limit = static_cast<int>(args.get("limit").get<double>());
1178 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1180 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1181 return LogAndCreateResult(
1182 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1183 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1186 context_history_data_e data_type_in = CONTEXT_HISTORY_RECENT_BATTERY_USAGE;
1188 if (args.contains("days")) {
1189 const int days = static_cast<int>(args.get("days").get<double>());
1190 data_type_in = CONTEXT_HISTORY_BATTERY_USAGE;
1191 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, days);
1193 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1194 return LogAndCreateResult(
1195 ErrorCode::INVALID_VALUES_ERR, "days given with invalid value.",
1196 ("days given with invalid value: %d (%s)", ret, get_error_message(ret)));
1200 *data_type_out = data_type_in;
1202 return PlatformResult(ErrorCode::NO_ERROR);
1205 PlatformResult ApplicationManager::BatteryUsageAttributes(const context_history_record_h record,
1206 picojson::object* object) {
1209 int ret = CONTEXT_HISTORY_ERROR_NONE;
1210 double amount = 0.0;
1211 char* app_id = nullptr;
1216 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1217 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1218 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1219 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1222 ret = context_history_record_get_double(record, CONTEXT_HISTORY_TOTAL_AMOUNT, &amount);
1223 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1224 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get amount.",
1225 ("Failed to get amount: %d (%s)", ret, get_error_message(ret)));
1228 object->insert(std::make_pair("appId", picojson::value(app_id)));
1229 object->insert(std::make_pair("batteryUsage", picojson::value(amount)));
1231 return PlatformResult(ErrorCode::NO_ERROR);
1234 PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
1235 const context_history_filter_h filter,
1236 context_history_data_e* data_type_out) {
1238 int ret = CONTEXT_HISTORY_ERROR_NONE;
1239 int limit = kMaximumAppsRetrievedObjects;
1240 if (args.contains("limit")) {
1241 limit = static_cast<int>(args.get("limit").get<double>());
1244 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1245 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1246 return LogAndCreateResult(
1247 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1248 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1251 context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
1252 if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
1253 data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
1256 int time_span = kDefaultPeriodOfTime;
1257 const picojson::object& JS_filter = args.get("filter").get<picojson::object>();
1258 auto time_span_iter = JS_filter.find("timeSpan");
1259 if (JS_filter.end() != time_span_iter || (JS_filter.end() == JS_filter.find("startTime") &&
1260 JS_filter.end() == JS_filter.find("endTime"))) {
1261 // In the second case, we treat the filter object just like an empty object.
1262 // The default value of filter will be used instead.
1263 if (JS_filter.end() != time_span_iter) {
1264 time_span = static_cast<int>(time_span_iter->second.get<double>());
1266 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
1267 // context_history_filter_set_int may return only success or
1268 // CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
1269 // Although this should never happen, it's better to check ret's value
1270 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1271 return LogAndCreateResult(ErrorCode::ABORT_ERR,
1272 "Error while setting the default TIME_SPAN value.",
1273 ("Error while setting the default TIME_SPAN value: %d (%s)", ret,
1274 get_error_message(ret)));
1277 auto start_time_iter = JS_filter.find("startTime");
1278 auto end_time_iter = JS_filter.find("endTime");
1279 if (start_time_iter != JS_filter.end()) {
1280 int start_time = static_cast<int>(start_time_iter->second.get<double>());
1281 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
1282 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1283 return LogAndCreateResult(
1284 ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
1285 ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1288 if (end_time_iter != JS_filter.end()) {
1289 int end_time = static_cast<int>(end_time_iter->second.get<double>());
1290 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
1291 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1292 return LogAndCreateResult(
1293 ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
1294 ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1299 *data_type_out = data_type_in;
1301 return PlatformResult(ErrorCode::NO_ERROR);
1304 PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
1305 picojson::object* object) {
1308 int ret = CONTEXT_HISTORY_ERROR_NONE;
1309 int total_count = 0;
1310 int total_duration = 0;
1312 char* app_id = nullptr;
1317 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1318 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1319 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1320 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1323 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
1324 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1325 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
1326 ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
1329 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
1330 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1331 return LogAndCreateResult(
1332 ErrorCode::ABORT_ERR, "Failed to get total duration.",
1333 ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
1336 ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
1337 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1338 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
1339 ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
1342 object->insert(std::make_pair("appId", picojson::value(app_id)));
1343 object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
1345 std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
1346 object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
1348 return PlatformResult(ErrorCode::NO_ERROR);
1352 void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
1355 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1356 int callback_id = -1;
1357 const auto& callback = args.get(kCallbackId);
1358 if (callback.is<double>()) {
1359 callback_id = static_cast<int>(callback.get<double>());
1362 auto get_battery_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1364 PlatformResult result = ApplicationManager::GetContextHistory(
1365 args, &response.get()->get<picojson::object>(), &ApplicationManager::BatteryUsageFilter,
1366 &ApplicationManager::BatteryUsageAttributes);
1368 LogAndReportError(result, &response.get()->get<picojson::object>());
1372 auto get_battery_usage_response =
1373 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1375 picojson::object& obj = response->get<picojson::object>();
1376 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1377 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1380 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1382 TaskQueue::GetInstance().Queue<picojson::value>(get_battery_usage, get_battery_usage_response,
1385 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1386 "This feature is not supported on this profile."),
1387 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1391 void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
1394 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1395 int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
1397 auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1399 PlatformResult result = ApplicationManager::GetContextHistory(
1400 args, &response.get()->get<picojson::object>(), &ApplicationManager::AppsUsageFilter,
1401 &ApplicationManager::AppsUsageAttributes);
1403 LogAndReportError(result, &response.get()->get<picojson::object>());
1407 auto get_apps_usage_response =
1408 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1410 picojson::object& obj = response->get<picojson::object>();
1411 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1412 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1415 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1417 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_usage, get_apps_usage_response, data);
1419 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1420 "This feature is not supported on this profile."),
1421 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1425 void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
1428 pkgmgrinfo_appinfo_h handle = nullptr;
1430 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
1431 std::unique_ptr<std::remove_pointer<pkgmgrinfo_appinfo_h>::type, int (*)(pkgmgrinfo_appinfo_h)>
1432 pkg_info_ptr(handle,
1433 &pkgmgrinfo_appinfo_destroy_appinfo); // automatically release the memory
1435 if (PMINFO_R_OK != ret) {
1436 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out,
1437 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
1441 auto meta_data_cb = [](const char* meta_key, const char* meta_value, void* user_data) -> int {
1442 if (nullptr == meta_key || nullptr == meta_value) {
1443 LoggerE("meta_key or meta_value is null");
1447 picojson::array* array = static_cast<picojson::array*>(user_data);
1448 array->push_back(picojson::value(picojson::object()));
1450 utils::CreateApplicationMetaData(meta_key, meta_value, &array->back().get<picojson::object>());
1454 picojson::value result = picojson::value(picojson::array());
1455 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, meta_data_cb, &result.get<picojson::array>());
1457 if (PMINFO_R_OK != ret) {
1458 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get metadata."), out,
1459 ("Failed to get metadata: %d (%s)", ret, get_error_message(ret)));
1463 ReportSuccess(result, *out);
1466 class ApplicationListChangedBroker {
1468 ApplicationListChangedBroker() : event_type_() {
1476 static int ClientStatusListener(unsigned int target_uid, int id, const char* type,
1477 const char* package, const char* key, const char* val,
1478 const void* msg, void* data) {
1480 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1482 if (0 == strcasecmp(key, kStartKey)) {
1483 that->HandleStart(val, package);
1484 } else if (0 == strcasecmp(key, kEndKey) && 0 == strcasecmp(val, kOkValue)) {
1485 that->HandleEnd(package);
1487 LoggerD("Ignored key: %s", key);
1493 static int AppUninstallListener(uid_t target_uid, int id, const char* type, const char* package,
1494 const char* key, const char* val, const void* msg, void* data) {
1497 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1499 if (0 == strcasecmp(key, kStartKey)) {
1500 that->HandleUninstallStart();
1501 } else if (0 == strcasecmp(key, kAppidKey)) {
1502 that->AddUninstalledAppId(val);
1503 } else if (0 == strcasecmp(key, kEndKey)) {
1504 that->HandleUninstallEnd();
1506 LoggerD("Ignored key: %s", key);
1512 void AddApplicationInstance(ApplicationInstance* app_instance) {
1514 app_instance_list_.push_back(app_instance);
1517 void RemoveApplicationInstance(ApplicationInstance* app_instance) {
1519 for (auto it = app_instance_list_.begin(); it != app_instance_list_.end(); it++) {
1520 if (*it == app_instance) {
1521 app_instance_list_.erase(it);
1528 void HandleStart(const char* event_type, const char* package) {
1531 set_event_type(event_type);
1534 void HandleEnd(const char* package) {
1537 if (Event::kUninstalled == event_type_) {
1541 GetApplicationIdsFromPackage(package);
1543 for (auto& app_id : app_list_) {
1544 picojson::value value = picojson::value(picojson::object());
1545 picojson::object& data_obj = value.get<picojson::object>();
1547 switch (event_type_) {
1548 case Event::kInstalled:
1549 data_obj.insert(std::make_pair(kAction, picojson::value(kOnInstalled)));
1552 case Event::kUpdated:
1553 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUpdated)));
1555 case Event::kUninstalled:
1556 LoggerD("Uninstalled called");
1560 switch (event_type_) {
1561 case Event::kInstalled:
1562 case Event::kUpdated: {
1563 pkgmgrinfo_appinfo_h handle = nullptr;
1565 pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1566 LoggerE("Failed to get application information handle.");
1569 auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object())));
1570 utils::CreateApplicationInformation(handle, &info.first->second.get<picojson::object>());
1571 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1573 case Event::kUninstalled:
1574 LoggerD("Uninstalled called");
1578 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1580 for (auto instance : app_instance_list_) {
1581 Instance::PostMessage(instance, value.serialize().c_str());
1586 void GetApplicationIdsFromPackage(const char* package) {
1588 package_info_h package_info = nullptr;
1590 int ret = package_info_create(package, &package_info);
1591 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1592 LoggerE("Failed to create package info: %d (%s)", ret, get_error_message(ret));
1596 ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_APP_COMPONENT_TYPE_ALL,
1597 ApplicationIdCallback, this);
1598 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1599 LoggerE("Failed to get application IDs: %d (%s)", ret, get_error_message(ret));
1602 ret = package_info_destroy(package_info);
1603 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1604 LoggerE("Failed to destroy package info: %d (%s)", ret, get_error_message(ret));
1608 void set_event_type(const char* type) {
1610 if (0 == strcasecmp(type, kInstallEvent)) {
1611 event_type_ = Event::kInstalled;
1612 } else if (0 == strcasecmp(type, kUpdateEvent)) {
1613 event_type_ = Event::kUpdated;
1614 } else if (0 == strcasecmp(type, kUninstallEvent)) {
1615 event_type_ = Event::kUninstalled;
1619 static bool ApplicationIdCallback(package_info_app_component_type_e comp_type, const char* app_id,
1622 if (nullptr != app_id) {
1623 static_cast<ApplicationListChangedBroker*>(user_data)->app_list_.push_back(app_id);
1628 void HandleUninstallStart() {
1631 set_event_type(kUninstallEvent);
1634 void AddUninstalledAppId(const char* app_id) {
1636 if (nullptr != app_id) {
1637 app_list_.push_back(app_id);
1641 void HandleUninstallEnd() {
1643 for (auto& app_id : app_list_) {
1644 picojson::value value = picojson::value(picojson::object());
1645 picojson::object& data_obj = value.get<picojson::object>();
1647 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUninstalled)));
1648 data_obj.insert(std::make_pair(kData, picojson::value(app_id)));
1650 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1652 for (auto instance : app_instance_list_) {
1653 Instance::PostMessage(instance, value.serialize().c_str());
1659 std::vector<std::string> app_list_;
1660 std::vector<ApplicationInstance*> app_instance_list_;
1663 static ApplicationListChangedBroker g_application_list_changed_broker;
1665 void ApplicationManager::StartAppInfoEventListener(picojson::object* out) {
1668 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1669 if (nullptr == pkgmgr_client_handle_) {
1670 pkgmgr_client_handle_ = pkgmgr_client_new(PC_LISTENING);
1672 if (nullptr == pkgmgr_client_uninstall_handle_) {
1673 pkgmgr_client_uninstall_handle_ = pkgmgr_client_new(PC_LISTENING);
1676 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1677 if (nullptr != pkgmgr_client_handle_) {
1678 pkgmgr_client_free(pkgmgr_client_handle_);
1679 pkgmgr_client_handle_ = nullptr;
1681 if (nullptr != pkgmgr_client_uninstall_handle_) {
1682 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1683 pkgmgr_client_uninstall_handle_ = nullptr;
1685 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."),
1690 #define CHECK_APPLICATION_EVENT_ERROR(result, function_name) \
1691 if (PKGMGR_R_OK > result) { \
1692 StopAppInfoEventListener(); \
1693 LogAndReportError( \
1694 PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."), out, \
1695 ("Function %s failed: %s (%d)", function_name, get_error_message(result), result)); \
1699 g_application_list_changed_broker.AddApplicationInstance(&instance_);
1701 int result = pkgmgr_client_set_status_type(
1702 pkgmgr_client_handle_,
1703 PACKAGE_MANAGER_STATUS_TYPE_INSTALL | PACKAGE_MANAGER_STATUS_TYPE_UPGRADE);
1704 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1706 result = pkgmgr_client_set_status_type(pkgmgr_client_uninstall_handle_,
1707 PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL);
1708 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1710 result = pkgmgr_client_listen_status(pkgmgr_client_handle_,
1711 ApplicationListChangedBroker::ClientStatusListener,
1712 &g_application_list_changed_broker);
1713 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1715 result = pkgmgr_client_listen_status(pkgmgr_client_uninstall_handle_,
1716 ApplicationListChangedBroker::AppUninstallListener,
1717 &g_application_list_changed_broker);
1718 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1720 #undef CHECK_APPLICATION_EVENT_ERROR
1722 LoggerD("Broker callback is already registered.");
1725 ReportSuccess(*out);
1728 void ApplicationManager::StopAppInfoEventListener() {
1731 if (nullptr != pkgmgr_client_handle_ || nullptr != pkgmgr_client_uninstall_handle_) {
1732 if (nullptr != pkgmgr_client_handle_) {
1733 pkgmgr_client_free(pkgmgr_client_handle_);
1734 pkgmgr_client_handle_ = nullptr;
1736 if (nullptr != pkgmgr_client_uninstall_handle_) {
1737 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1738 pkgmgr_client_uninstall_handle_ = nullptr;
1740 g_application_list_changed_broker.RemoveApplicationInstance(&instance_);
1742 LoggerD("Broker callback is already unregistered.");
1746 void ApplicationManager::GetApplicationInformationSize(const picojson::value& args,
1747 picojson::object* out) {
1750 const auto& package_id = args.get("packageId");
1751 if (!package_id.is<std::string>()) {
1752 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
1757 const std::string& package_id_str = package_id.get<std::string>();
1759 // get installed size from package server (to solve smack issue)
1760 pkgmgr_client* pc = pkgmgr_client_new(PC_REQUEST);
1763 if (nullptr == pc) {
1764 LoggerE("Failed to create pkgmgr client");
1766 size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL,
1767 package_id_str.c_str(), NULL, NULL, NULL);
1770 LoggerE("Failed to get installed size: %d (%s)", size, get_error_message(size));
1773 pkgmgr_client_free(pc);
1776 picojson::value result = picojson::value(picojson::object());
1777 picojson::object& result_obj = result.get<picojson::object>();
1778 result_obj.insert(std::make_pair("size", picojson::value(static_cast<double>(size))));
1780 ReportSuccess(result, *out);
1783 void ApplicationManager::BroadcastEventHelper(const picojson::value& args, picojson::object& out,
1788 std::string event_str = args.get("name").get<std::string>();
1789 const char* event_name = event_str.c_str();
1791 bundle* data = bundle_create();
1796 ret = bundle_add(data, "data", args.get("data").serialize().c_str());
1798 if (ret != EVENT_ERROR_NONE) {
1799 LoggerE("bundle_add failed, error: %d (%s)", ret, get_error_message(ret));
1805 ret = event_publish_trusted_app_event(event_name, data);
1807 ret = event_publish_app_event(event_name, data);
1810 if (ret == EVENT_ERROR_NONE) {
1813 LoggerE("event_publish_app_event failed, error: %d (%s)", ret, get_error_message(ret));
1818 void ApplicationManager::OnEvent(const char* event_name, bundle* event_data, void* user_data) {
1819 ScopeLogger("Event name is: '%s'", event_name);
1821 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1823 if (!manager->event_callback_) {
1824 LoggerD("No event listener registered, skipping.");
1828 picojson::value event = picojson::value(picojson::object());
1829 picojson::object& event_o = event.get<picojson::object>();
1832 char* val = nullptr;
1834 if (event_map_.count(event_name)) { // system event
1835 const std::string& key = event_map_.at(event_name);
1836 std::string state = "true";
1838 ret = bundle_get_str(event_data, key.c_str(), &val);
1839 if (EVENT_ERROR_NONE != ret) {
1840 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1844 state = std::string(val);
1847 LoggerD("State is %s", state.c_str());
1848 event_o["value"] = picojson::value(state);
1850 } else { // user event
1851 ret = bundle_get_str(event_data, "data", &val);
1852 if (EVENT_ERROR_NONE != ret) {
1853 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1857 picojson::value data;
1859 picojson::parse(data, val, val + strlen(val), &err);
1861 LoggerE("Failed to parse bundle data: %s", err.c_str());
1865 event_o["data"] = data;
1868 LoggerD("event_name is: %s", event_name);
1869 event_o["name"] = picojson::value(event_name);
1871 manager->event_callback_(&event);
1874 PlatformResult ApplicationManager::StartEventListener(const std::string& event_name,
1875 const JsonCallback& callback) {
1879 event_handler_h event_handler;
1881 ret = event_add_event_handler(event_name.c_str(), OnEvent, this, &event_handler);
1882 LoggerD("event_add_event_handler() result: %d (%s)", ret, get_error_message(ret));
1883 if (EVENT_ERROR_PERMISSION_DENIED == ret) {
1884 return LogAndCreateResult(ErrorCode::SECURITY_ERR, "The privilege is required",
1885 ("event_add_event_handler failed, error: %d", ret));
1886 } else if (EVENT_ERROR_NONE != ret) {
1887 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error setting event listener",
1888 ("event_add_event_handler failed, error: %d", ret));
1891 event_handler_map_[event_name] = event_handler;
1893 event_callback_ = callback;
1894 LoggerD("event_add_event_handler success");
1895 return PlatformResult(ErrorCode::NO_ERROR);
1898 void ApplicationManager::StopEventListener(const std::string& event_name) {
1902 event_handler_h event_handler;
1904 if (event_handler_map_.find(event_name) != event_handler_map_.end()) {
1905 event_handler = event_handler_map_[event_name];
1907 ret = event_remove_event_handler(event_handler);
1908 if (EVENT_ERROR_NONE != ret) {
1909 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
1913 event_handler_map_.erase(event_name);
1917 void ApplicationManager::OnStatusEvent(const char* type, const char* app_id,
1918 app_manager_event_type_e event_type,
1919 app_manager_event_state_e event_state,
1920 app_manager_event_h handle, void* user_data) {
1923 if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
1924 LoggerD("State different from completed");
1928 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1930 if (!manager || !manager->status_callback_) {
1931 LoggerD("No event listener registered, skipping.");
1936 switch (event_type) {
1937 case APP_MANAGER_EVENT_ENABLE_APP:
1940 case APP_MANAGER_EVENT_DISABLE_APP:
1941 status_type = false;
1944 LoggerD("Uknown status type skipping.");
1948 picojson::value event = picojson::value(picojson::object());
1949 picojson::object& event_o = event.get<picojson::object>();
1951 event_o[kStatusType] = picojson::value(status_type);
1952 event_o[kAppId] = picojson::value(app_id);
1953 event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
1955 manager->status_callback_(&event);
1958 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1959 PlatformResult ApplicationManager::GetContextHistory(
1960 const picojson::value& args, picojson::object* out,
1961 common::PlatformResult (*modify_filter_cb)(const picojson::value&,
1962 const context_history_filter_h,
1963 context_history_data_e* data_type),
1964 common::PlatformResult (*add_attributes_to_object)(const context_history_record_h,
1965 picojson::object*)) {
1967 context_history_list_h list = nullptr;
1968 context_history_h handle = nullptr;
1969 context_history_filter_h filter = nullptr;
1972 context_history_list_destroy(list);
1973 context_history_destroy(handle);
1974 context_history_filter_destroy(filter);
1977 int ret = context_history_create(&handle);
1978 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1979 return LogAndCreateResult(
1980 ErrorCode::ABORT_ERR, "Failed to create context handle.",
1981 ("Failed to create context handle: %d (%s)", ret, get_error_message(ret)));
1984 ret = context_history_filter_create(&filter);
1985 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1986 return LogAndCreateResult(
1987 ErrorCode::ABORT_ERR, "Failed to create filter handle.",
1988 ("Failed to create filter handle: %d (%s)", ret, get_error_message(ret)));
1991 context_history_data_e data_type;
1993 PlatformResult result = modify_filter_cb(args, filter, &data_type);
1998 picojson::value result_array = picojson::value(picojson::array());
1999 picojson::array& array_obj = result_array.get<picojson::array>();
2001 ret = context_history_get_list(handle, data_type, filter, &list);
2002 if (CONTEXT_HISTORY_ERROR_NO_DATA == ret) {
2003 ReportSuccess(result_array, *out);
2004 return PlatformResult(ErrorCode::NO_ERROR);
2005 } else if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2006 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list.",
2007 ("Failed to get list: %d (%s)", ret, get_error_message(ret)));
2011 ret = context_history_list_get_count(list, &size);
2012 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2013 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list size.",
2014 ("Failed to get list size: %d (%s)", ret, get_error_message(ret)));
2017 array_obj.resize(size, picojson::value(picojson::object()));
2019 for (int i = 0; i < size; ++i) {
2020 context_history_record_h record = nullptr;
2022 context_history_record_destroy(record);
2025 ret = context_history_list_get_current(list, &record);
2026 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2027 return LogAndCreateResult(
2028 ErrorCode::ABORT_ERR, "Failed to get current record.",
2029 ("Failed to get current record: %d (%s)", ret, get_error_message(ret)));
2032 result = add_attributes_to_object(record, &array_obj[i].get<picojson::object>());
2037 ret = context_history_list_move_next(list);
2038 if (CONTEXT_HISTORY_ERROR_NONE != ret && CONTEXT_HISTORY_ERROR_NO_DATA != ret) {
2039 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to move iterator.",
2040 ("Failed to move iterator: %d (%s)", ret, get_error_message(ret)));
2044 ReportSuccess(result_array, *out);
2045 return PlatformResult(ErrorCode::NO_ERROR);
2049 PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
2052 int ret = APP_MANAGER_ERROR_NONE;
2054 if (!app_status_handle_) {
2055 ret = app_manager_event_create(&app_status_handle_);
2056 if (APP_MANAGER_ERROR_NONE != ret) {
2057 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
2058 ("app_manager_event_create failed, error: %d", ret));
2061 ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
2062 if (APP_MANAGER_ERROR_NONE != ret) {
2063 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
2064 ("app_manager_event_set_status failed, error: %d", ret));
2068 status_callback_ = callback;
2069 ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
2070 if (APP_MANAGER_ERROR_NONE != ret) {
2071 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
2072 ("app_manager_set_event_cb failed, error: %d", ret));
2075 return PlatformResult(ErrorCode::NO_ERROR);
2078 PlatformResult ApplicationManager::StopStatusChangeListener() {
2081 if (app_status_handle_) {
2082 int ret = app_manager_unset_event_cb(app_status_handle_);
2083 if (APP_MANAGER_ERROR_NONE != ret) {
2084 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
2085 ("app_manager_unset_event_cb failed, error: %d", ret));
2089 return PlatformResult(ErrorCode::NO_ERROR);
2092 } // namespace application
2093 } // namespace extension