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"
23 #include <type_traits>
25 #include <app_control_internal.h>
27 #include <app_manager_extension.h>
31 #include <bundle_internal.h>
32 #include <package_manager.h>
33 #include <pkgmgr-info.h>
34 #include <pkgmgr_installer.h>
36 #include "common/current_application.h"
37 #include "common/logger.h"
38 #include "common/platform_result.h"
39 #include "common/scope_exit.h"
40 #include "common/task-queue.h"
41 #include "common/tools.h"
43 #include "application/application_instance.h"
44 #include "application/application_utils.h"
46 using namespace common;
47 using namespace tools;
50 namespace application {
53 const std::string kTizenApisFileScheme = "file://";
54 const std::string kTizenApisAppSlash = "/";
55 const std::string kTizenApisAppShared = "shared";
57 const char* kStartKey = PKGMGR_INSTALLER_START_KEY_STR;
58 const char* kEndKey = PKGMGR_INSTALLER_END_KEY_STR;
59 const char* kOkValue = PKGMGR_INSTALLER_OK_EVENT_STR;
60 const char* kInstallEvent = PKGMGR_INSTALLER_INSTALL_EVENT_STR;
61 const char* kUpdateEvent = PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
62 const char* kUninstallEvent = PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
64 const char* kAppidKey = "appid";
66 const std::string kAction = "action";
67 const std::string kCallbackId = "callbackId";
68 const std::string kOnInstalled = "oninstalled";
69 const std::string kOnUpdated = "onupdated";
70 const std::string kOnUninstalled = "onuninstalled";
71 const std::string kData = "data";
72 const std::string kStatusType = "statusType";
73 const std::string kAppId = "appId";
74 const std::string kListenerId = "listenerId";
75 const std::string kAppStatusChangeListener = "AppStatusChangeListener";
76 const std::string kAppUsageModeFrequently = "FREQUENTLY";
77 const std::string kAppUsageModeRecently = "RECENTLY";
79 const std::map<std::string, std::string> event_map_ = {
80 {SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
81 {SYSTEM_EVENT_BATTERY_LEVEL_STATUS, EVENT_KEY_BATTERY_LEVEL_STATUS},
82 {SYSTEM_EVENT_USB_STATUS, EVENT_KEY_USB_STATUS},
83 {SYSTEM_EVENT_EARJACK_STATUS, EVENT_KEY_EARJACK_STATUS},
84 {SYSTEM_EVENT_DISPLAY_STATE, EVENT_KEY_DISPLAY_STATE},
85 {SYSTEM_EVENT_LOW_MEMORY, EVENT_KEY_LOW_MEMORY},
86 {SYSTEM_EVENT_WIFI_STATE, EVENT_KEY_WIFI_STATE},
87 {SYSTEM_EVENT_BT_STATE, EVENT_KEY_BT_STATE},
88 {SYSTEM_EVENT_LOCATION_ENABLE_STATE, EVENT_KEY_LOCATION_ENABLE_STATE},
89 {SYSTEM_EVENT_GPS_ENABLE_STATE, EVENT_KEY_GPS_ENABLE_STATE},
90 {SYSTEM_EVENT_NPS_ENABLE_STATE, EVENT_KEY_NPS_ENABLE_STATE},
91 {SYSTEM_EVENT_INCOMING_MSG, EVENT_KEY_MSG_TYPE},
92 {SYSTEM_EVENT_TIME_ZONE, EVENT_KEY_TIME_ZONE},
93 {SYSTEM_EVENT_HOUR_FORMAT, EVENT_KEY_HOUR_FORMAT},
94 {SYSTEM_EVENT_LANGUAGE_SET, EVENT_KEY_LANGUAGE_SET},
95 {SYSTEM_EVENT_REGION_FORMAT, EVENT_KEY_REGION_FORMAT},
96 {SYSTEM_EVENT_SILENT_MODE, EVENT_KEY_SILENT_MODE},
97 {SYSTEM_EVENT_VIBRATION_STATE, EVENT_KEY_VIBRATION_STATE},
98 {SYSTEM_EVENT_SCREEN_AUTOROTATE_STATE, EVENT_KEY_SCREEN_AUTOROTATE_STATE},
99 {SYSTEM_EVENT_MOBILE_DATA_STATE, EVENT_KEY_MOBILE_DATA_STATE},
100 {SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
101 {SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}};
103 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
104 const int kMaximumBatteryRetrievedObjects = 30;
105 const int kMaximumAppsRetrievedObjects = 10;
106 const int kDefaultPeriodOfTime = 30;
110 ApplicationManager::ApplicationManager(ApplicationInstance& instance)
111 : pkgmgr_client_handle_(nullptr),
112 pkgmgr_client_uninstall_handle_(nullptr),
114 app_status_handle_(nullptr) {
118 ApplicationManager::~ApplicationManager() {
120 StopAppInfoEventListener();
121 StopStatusChangeListener();
123 for (auto it = event_handler_map_.begin(); it != event_handler_map_.end();) {
124 int ret = event_remove_event_handler(it->second);
125 if (EVENT_ERROR_NONE != ret) {
126 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
128 it = event_handler_map_.erase(it);
131 if (app_status_handle_) {
132 int ret = app_manager_event_destroy(app_status_handle_);
133 if (APP_MANAGER_ERROR_NONE != ret) {
134 LoggerE("app_manager_event_destroy failed, error: %d", ret);
139 void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
142 // obtain handle to application info
143 pkgmgrinfo_appinfo_h handle;
144 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
145 if (PMINFO_R_OK != ret) {
146 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app info."), out,
147 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
151 picojson::value app_info = picojson::value(picojson::object());
152 picojson::object& app_info_obj = app_info.get<picojson::object>();
154 utils::CreateApplicationInformation(handle, &app_info_obj);
155 pkgmgrinfo_appinfo_destroy_appinfo(handle);
157 picojson::value result = picojson::value(picojson::object());
158 picojson::object& result_obj = result.get<picojson::object>();
160 result_obj.insert(std::make_pair(
162 picojson::value(std::to_string(CurrentApplication::GetInstance().GetProcessId()))));
163 result_obj.insert(std::make_pair("appInfo", app_info));
165 ReportSuccess(result, *out);
168 class TerminateHandler {
170 TerminateHandler(int callback_id, ApplicationInstance* app_instance)
171 : callback_handle_(callback_id), pid_(-1), timeout_id_(0), app_instance_(app_instance) {
174 void set_pid(pid_t pid) {
182 void Invoke(const std::shared_ptr<picojson::value>& response) {
185 if (timeout_id_ > 0) {
186 // cancel terminate callback
187 g_source_remove(timeout_id_);
191 ApplicationInstance* app_instance = this->app_instance_;
192 int callback_id = this->callback_handle_;
193 TaskQueue::GetInstance().Async<picojson::value>(
194 [callback_id, app_instance](const std::shared_ptr<picojson::value>& response) {
195 picojson::object& obj = response->get<picojson::object>();
197 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
198 Instance::PostMessage(app_instance, response->serialize().c_str());
204 int callback_handle_;
207 ApplicationInstance* app_instance_;
210 #define CHECK_RESULT(result, response, handler) \
211 if (result.IsError()) { \
212 LogAndReportError(result, &response->get<picojson::object>()); \
213 handler->Invoke(response); \
218 void ApplicationManager::AsyncResponse(const PlatformResult& result,
219 std::shared_ptr<picojson::value>* response) {
221 LogAndReportError(result, &(*response)->get<picojson::object>());
223 TaskQueue::GetInstance().Async<picojson::value>(
224 [this](const std::shared_ptr<picojson::value>& response) {
225 Instance::PostMessage(&this->instance_, response->serialize().c_str());
230 void ApplicationManager::Kill(const picojson::value& args) {
233 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
235 int callback_id = -1;
236 const auto& callback = args.get(kCallbackId);
237 if (callback.is<double>()) {
238 callback_id = static_cast<int>(callback.get<double>());
241 const auto& context = args.get("contextId");
242 if (!context.is<std::string>()) {
243 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
246 const std::string& context_id = context.get<std::string>();
248 if (context_id.empty() && result.IsSuccess()) {
249 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID is empty.");
252 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
253 picojson::object& obj = response->get<picojson::object>();
254 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
256 if (result.IsError()) {
257 LoggerE("Failed args.get");
258 AsyncResponse(result, &response);
262 auto kill = [this, callback_id, context_id]() -> void {
265 std::shared_ptr<picojson::value> response =
266 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
268 TerminateHandler* handler = new TerminateHandler(callback_id, &this->instance_);
269 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
273 pid = std::stoi(context_id);
275 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int.");
276 CHECK_RESULT(result, response, handler)
280 result = LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Context ID cannot be negative value.");
281 CHECK_RESULT(result, response, handler)
284 // if kill request comes for current context, throw InvalidValuesException
285 if (CurrentApplication::GetInstance().GetProcessId() == pid) {
287 LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Cannot kill current application.");
288 CHECK_RESULT(result, response, handler)
291 LoggerD("Kill, pid: %d", pid);
293 char* app_id = nullptr;
294 int ret = app_manager_get_app_id(pid, &app_id);
295 // automatically release the memory
296 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
298 if (APP_MANAGER_ERROR_NONE != ret) {
299 result = LogAndCreateResult(
300 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
301 ("Failed to get application ID, error: %d (%s)", ret, get_error_message(ret)));
302 CHECK_RESULT(result, response, handler)
305 LoggerD("Kill, app ID: %s", app_id);
307 // acquire application context
308 app_context_h app_context = nullptr;
310 ret = app_manager_get_app_context(app_id, &app_context);
311 std::unique_ptr<std::remove_pointer<app_context_h>::type, int (*)(app_context_h)>
312 app_context_ptr(app_context, &app_context_destroy); // automatically release the memory
314 if (APP_MANAGER_ERROR_NONE != ret) {
315 result = LogAndCreateResult(
316 ErrorCode::NOT_FOUND_ERR, "Failed to get application ID.",
317 ("Failed to get application context handle: %d (%s)", ret, get_error_message(ret)));
318 CHECK_RESULT(result, response, handler)
321 auto terminate_callback = [](app_context_h app_context, app_context_event_e event,
323 LoggerD("terminate_callback: %d", event);
325 if (APP_CONTEXT_EVENT_TERMINATED != event) {
326 LoggerD("ignoring event");
331 int ret = app_context_get_pid(app_context, &pid);
333 if (APP_MANAGER_ERROR_NONE != ret) {
334 LoggerE("Failed to get pid of terminated app: %d (%s)", ret, get_error_message(ret));
338 TerminateHandler* handler = static_cast<TerminateHandler*>(user_data);
340 LoggerD("Expected PID: %d, got: %d", handler->pid(), pid);
342 if (handler->pid() == pid) {
343 std::shared_ptr<picojson::value> response =
344 std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
345 ReportSuccess(response->get<picojson::object>());
346 handler->Invoke(response);
351 LoggerD("Kill, setting callback");
352 handler->set_pid(pid);
353 ret = app_manager_set_app_context_event_cb(terminate_callback, handler);
355 if (APP_MANAGER_ERROR_NONE != ret) {
356 result = LogAndCreateResult(
357 ErrorCode::UNKNOWN_ERR, "Failed to register termination callback.",
358 ("Error while registering app context event: %d (%s)", ret, get_error_message(ret)));
359 CHECK_RESULT(result, response, handler)
362 LoggerD("Kill, calling native function");
364 // terminate application
365 ret = app_manager_terminate_app(app_context);
367 if (APP_MANAGER_ERROR_NONE != ret) {
368 result = LogAndCreateResult(
369 ErrorCode::UNKNOWN_ERR, "Failed to terminate application.",
370 ("Failed to terminate application: %d (%s)", ret, get_error_message(ret)));
371 CHECK_RESULT(result, response, handler)
374 LoggerD("Kill, end, waiting for notification");
382 PlatformResult PrepareAppControlForLaunchAppControl(const picojson::value& args,
383 app_control_h* app_control) {
386 const auto& control = args.get("appControl");
387 if (!control.is<picojson::object>()) {
388 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
390 const picojson::object& app_control_obj = control.get<picojson::object>();
392 app_control_h tmp_app_control = nullptr;
393 auto result = utils::ApplicationControlToService(app_control_obj, &tmp_app_control);
394 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
395 app_control_ptr(tmp_app_control, &app_control_destroy);
397 if (result.IsError()) {
398 LoggerE("Application control to service failed.");
403 const auto& id = args.get("id");
404 if (id.is<std::string>()) {
405 app_id = id.get<std::string>();
408 if (!app_id.empty()) {
409 LoggerD("app_id: %s", app_id.c_str());
411 int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
413 if (APP_CONTROL_ERROR_NONE != ret) {
414 LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
415 return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
419 *app_control = app_control_ptr.release();
421 return PlatformResult(ErrorCode::NO_ERROR);
426 void ApplicationManager::LaunchAppControl(const picojson::value& args) {
429 int callback_id = -1;
430 const auto& callback = args.get(kCallbackId);
431 if (callback.is<double>()) {
432 callback_id = static_cast<int>(callback.get<double>());
435 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
436 picojson::object& response_obj = response->get<picojson::object>();
438 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
440 app_control_h app_control = nullptr;
441 auto prepare_app_control_result = PrepareAppControlForLaunchAppControl(args, &app_control);
442 if (prepare_app_control_result.IsError()) {
443 AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
447 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
448 app_control_ptr(app_control, &app_control_destroy);
450 std::string reply_callback_id;
451 const auto& reply = args.get("replyCallback");
452 if (reply.is<std::string>()) {
453 reply_callback_id = reply.get<std::string>();
456 struct LaunchAppControlCallbackData {
457 ApplicationInstance* instance;
458 std::shared_ptr<picojson::value> response;
459 std::string reply_callback_id;
460 }* launch_app_user_data = new (std::nothrow)
461 LaunchAppControlCallbackData{&this->instance_, response, reply_callback_id};
463 if (!launch_app_user_data) {
464 LoggerE("Memory allocation fail!");
465 AsyncResponse(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response);
469 app_control_reply_cb reply_callback = nullptr;
470 if (!reply_callback_id.empty()) {
471 launch_app_user_data->reply_callback_id = reply_callback_id;
473 reply_callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
475 ScopeLogger("reply_callback");
477 LaunchAppControlCallbackData* callback_data =
478 static_cast<LaunchAppControlCallbackData*>(user_data);
479 if (!callback_data) {
480 LoggerD("reply_callback failed: user_data is nullptr");
484 picojson::value return_value = picojson::value(picojson::object());
485 picojson::object& return_value_obj = return_value.get<picojson::object>();
486 return_value_obj.insert(
487 std::make_pair(kListenerId, picojson::value(callback_data->reply_callback_id)));
489 if (APP_CONTROL_RESULT_SUCCEEDED == result) {
490 LoggerD("App started");
491 return_value_obj.insert(std::make_pair("data", picojson::value(picojson::array())));
492 if (!utils::ServiceToApplicationControlDataArray(
493 reply, &return_value_obj.find("data")->second.get<picojson::array>())) {
494 return_value_obj.erase("data");
496 ReportSuccess(return_value_obj);
498 ReportError(return_value_obj);
501 Instance::PostMessage(callback_data->instance, return_value.serialize().c_str());
502 // Calling order of reply_callback and result_callback cannot be determined,
503 // thus callback_data is not released here - it is always
504 // released in result_callback with delay to prevent using a released memory.
508 app_control_result_cb result_callback = [](app_control_h launch_request,
509 app_control_error_e launch_result, void* user_data) {
510 ScopeLogger("LaunchAppControl result_callback");
512 LaunchAppControlCallbackData* callback_data =
513 static_cast<LaunchAppControlCallbackData*>(user_data);
515 auto result = utils::TranslateAppControlError(launch_result);
517 if (result.IsError()) {
518 LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
520 ReportSuccess(callback_data->response->get<picojson::object>());
523 Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
525 // Calling order of reply_callback and result_callback cannot be determined,
526 // thus callback_data is released here with delay to prevent using a released
527 // memory in reply_callback function.
529 std::thread([callback_data, timeout]() {
530 std::this_thread::sleep_for(std::chrono::seconds(timeout));
531 LoggerD("Deleting callback_data: %p", callback_data);
532 delete callback_data;
537 * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
538 * Previous implementation, using synchronous app_control_send_launch_request,
539 * tries to launch the application 3 times, before reporting an error.
540 * New implementation, using app_control_send_launch_request_async makes only one attempt.
541 * If problems, such as failed application start occur, multiple attempts may solve the problem.
543 auto launch_result = utils::TranslateAppControlError(
544 static_cast<app_control_error_e>(app_control_send_launch_request_async(
545 app_control_ptr.get(), result_callback, reply_callback, launch_app_user_data)));
547 if (launch_result.IsError()) {
548 delete launch_app_user_data;
549 AsyncResponse(launch_result, &response);
551 LoggerD("App launched");
557 PlatformResult TranslateLaunchError(app_control_error_e return_code) {
560 auto result = utils::TranslateAppControlError(return_code);
561 if (ErrorCode::SECURITY_ERR == result.error_code()) {
562 result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
568 PlatformResult PrepareAppControlForLaunch(const picojson::value& args, app_control_h* app_control) {
571 const auto& app_id = args.get("id");
572 if (!app_id.is<std::string>()) {
573 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
575 const auto app_id_str = app_id.get<std::string>();
577 app_control_h tmp_app_control = nullptr;
578 int result = app_control_create(&tmp_app_control);
579 if (APP_CONTROL_ERROR_NONE != result) {
580 LoggerD("app_control_create() failed: %d (%s)", result, get_error_message(result));
581 return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
584 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
585 app_control_ptr(tmp_app_control, &app_control_destroy);
587 if (!app_id_str.empty()) {
588 LoggerD("app_id: %s", app_id_str.c_str());
590 int ret = app_control_set_app_id(app_control_ptr.get(), app_id_str.c_str());
592 if (APP_CONTROL_ERROR_NONE != ret) {
593 LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
594 return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
598 *app_control = app_control_ptr.release();
600 return PlatformResult(ErrorCode::NO_ERROR);
604 void ApplicationManager::Launch(const picojson::value& args) {
607 int callback_id = -1;
608 const auto& callback = args.get(kCallbackId);
609 if (callback.is<double>()) {
610 callback_id = static_cast<int>(callback.get<double>());
613 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
614 picojson::object& response_obj = response->get<picojson::object>();
616 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
618 app_control_h app_control = nullptr;
619 auto prepare_app_control_result = PrepareAppControlForLaunch(args, &app_control);
620 if (prepare_app_control_result.IsError()) {
621 AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
625 std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
626 app_control_ptr(app_control, &app_control_destroy);
628 struct LaunchCallbackData {
629 ApplicationInstance* instance;
630 std::shared_ptr<picojson::value> response;
631 }* launch_user_data = new (std::nothrow) LaunchCallbackData{&this->instance_, response};
633 app_control_result_cb result_callback = [](app_control_h launch_request,
634 app_control_error_e launch_result, void* user_data) {
635 ScopeLogger("Launch result_callback");
637 LaunchCallbackData* callback_data = static_cast<LaunchCallbackData*>(user_data);
639 auto result = TranslateLaunchError(launch_result);
641 if (result.IsError()) {
642 LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
644 ReportSuccess(callback_data->response->get<picojson::object>());
647 Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
649 delete callback_data;
653 * TODO: Observe how often app_control_send_resume_request tries to launch the application.
654 * Previous implementation, using synchronous app_control_send_launch_request,
655 * tries to launch the application 3 times, before reporting an error.
656 * New implementation, using app_control_send_resume_request makes only one attempt.
657 * If problems, such as failed application start occur, multiple attempts may solve the problem.
659 auto launch_result = TranslateLaunchError(static_cast<app_control_error_e>(
660 app_control_send_resume_request(app_control_ptr.get(), result_callback, launch_user_data)));
662 if (launch_result.IsError()) {
663 delete launch_user_data;
664 AsyncResponse(launch_result, &response);
666 LoggerD("App launched");
670 // internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
671 // public CAPI did not handling APP_CONTROL_ERROR_APP_NOT_FOUND
672 int app_control_foreach_app_matched_internal(app_control_h app_control,
673 app_control_app_matched_cb callback, void* user_data) {
676 app_control_h app_control;
677 app_control_app_matched_cb callback;
680 } foreach_context_launchable_app_t_internal;
682 // internal impl of app_control_cb_broker_foreach_app_matched()
683 auto app_control_cb_broker_foreach_app_matched_internal = [](const char* package,
686 "Entered into asynchronous function, app_control_cb_broker_foreach_app_matched_internal's "
688 foreach_context_launchable_app_t_internal* foreach_context;
689 app_control_app_matched_cb app_matched_cb;
691 if (package == NULL || data == NULL) {
692 LoggerE("APP_CONTROL_ERROR_INVALID_PARAMETER");
696 foreach_context = (foreach_context_launchable_app_t_internal*)data;
697 if (foreach_context->foreach_break == true) return -1;
699 app_matched_cb = foreach_context->callback;
700 if (app_matched_cb != NULL) {
701 bool stop_foreach = false;
704 !app_matched_cb(foreach_context->app_control, package, foreach_context->user_data);
706 foreach_context->foreach_break = stop_foreach;
712 foreach_context_launchable_app_t_internal foreach_context = {.app_control = app_control,
713 .callback = callback,
714 .user_data = user_data,
715 .foreach_break = false};
717 bundle* bundle_data = NULL;
718 app_control_to_bundle(app_control, &bundle_data);
720 int ret = appsvc_usr_get_list(bundle_data, app_control_cb_broker_foreach_app_matched_internal,
721 &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;
739 void ApplicationManager::FindAppControl(const picojson::value& args) {
742 int callback_id = -1;
743 const auto& callback = args.get(kCallbackId);
744 if (callback.is<double>()) {
745 callback_id = static_cast<int>(callback.get<double>());
748 std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
749 picojson::object& response_obj = response->get<picojson::object>();
751 std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
753 PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
754 const auto& control = args.get("appControl");
755 if (!control.is<picojson::object>()) {
756 result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
757 AsyncResponse(result, &response);
761 const picojson::object& app_control_obj = control.get<picojson::object>();
763 app_control_h app_control = nullptr;
764 result = utils::ApplicationControlToService(app_control_obj, &app_control);
765 std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
766 app_control, &app_control_destroy); // automatically release the memory
768 if (result.IsError()) {
769 LoggerE("Application control to service failed.");
770 AsyncResponse(result, &response);
774 auto find = [app_control_ptr](const std::shared_ptr<picojson::value>& response) -> void {
775 ScopeLogger("Entered into asynchronous function, find");
776 auto app_control_matched = [](app_control_h app_control, const char* appid,
777 void* user_data) -> bool {
778 ScopeLogger("Entered into asynchronous function, app_control_matched");
779 if (nullptr == appid) {
780 LoggerD("appid is NULL");
784 pkgmgrinfo_appinfo_h handle;
785 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &handle);
786 if (PMINFO_R_OK != ret) {
787 LoggerE("Failed to get appInfo: %d (%s)", ret, get_error_message(ret));
789 picojson::array* array = static_cast<picojson::array*>(user_data);
790 array->push_back(picojson::value(picojson::object()));
792 utils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
793 pkgmgrinfo_appinfo_destroy_appinfo(handle);
799 picojson::object& response_obj = response->get<picojson::object>();
800 auto it_result = response_obj.find("result");
801 picojson::object& result_obj = it_result->second.get<picojson::object>();
803 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())));
805 int ret = app_control_foreach_app_matched_internal(app_control_ptr.get(), app_control_matched,
806 &array.first->second.get<picojson::array>());
808 if (APP_CONTROL_ERROR_NONE != ret) {
809 if (APP_CONTROL_ERROR_APP_NOT_FOUND == ret) {
810 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Matched Application not found"),
811 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
812 get_error_message(ret)));
813 } else if (APP_CONTROL_ERROR_LAUNCH_FAILED == ret) {
815 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error"), &response_obj,
816 ("app_control_foreach_app_matched error: %d (%s)", ret, get_error_message(ret)));
817 } else if (APP_CONTROL_ERROR_INVALID_PARAMETER == ret) {
818 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed"),
819 &response_obj, ("app_control_foreach_app_matched error: %d (%s)", ret,
820 get_error_message(ret)));
822 // remove copied ApplicationControl from result
823 response_obj.erase(it_result);
825 ReportSuccess(response_obj);
829 auto find_response = [this](const std::shared_ptr<picojson::value>& response) -> void {
830 ScopeLogger("Entered into asynchronous function, find_response");
831 Instance::PostMessage(&this->instance_, response->serialize().c_str());
834 // prepare result object, we need to do that here, as input parameter is passed to result callback
835 auto ret = response_obj.insert(std::make_pair("result", picojson::value(picojson::object())));
836 // reinsert application control
837 ret.first->second.get<picojson::object>().insert(
838 std::make_pair("appControl", args.get("appControl")));
840 TaskQueue::GetInstance().Queue<picojson::value>(find, find_response, response);
843 void ApplicationManager::GetAppsContext(const picojson::value& args) {
846 int callback_id = -1;
847 const auto& callback = args.get(kCallbackId);
848 if (callback.is<double>()) {
849 callback_id = static_cast<int>(callback.get<double>());
852 auto get_apps_context = [](const std::shared_ptr<picojson::value>& response) -> void {
853 picojson::object& response_obj = response->get<picojson::object>();
854 picojson::value result = picojson::value(picojson::object());
855 picojson::object& result_obj = result.get<picojson::object>();
856 picojson::array& array =
857 result_obj.insert(std::make_pair("contexts", picojson::value(picojson::array())))
858 .first->second.get<picojson::array>();
860 auto app_context_cb = [](app_context_h app_context, void* user_data) -> bool {
861 if (nullptr == user_data) {
865 picojson::array* array = static_cast<picojson::array*>(user_data);
866 array->push_back(picojson::value(picojson::object()));
868 if (!utils::CreateApplicationContext(app_context, &array->back().get<picojson::object>())) {
876 int ret = app_manager_foreach_app_context(app_context_cb, &array);
878 if (APP_MANAGER_ERROR_NONE != ret) {
880 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
881 ("app_manager_foreach_app_context error: %d (%s)", ret, get_error_message(ret)));
883 ReportSuccess(result, response_obj);
887 auto get_apps_context_response =
888 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
889 picojson::object& obj = response->get<picojson::object>();
890 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
891 Instance::PostMessage(&this->instance_, response->serialize().c_str());
894 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
896 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_context, get_apps_context_response,
900 void ApplicationManager::GetAppContext(const picojson::value& args, picojson::object* out) {
904 const auto& context_id = args.get("contextId");
905 if (context_id.is<std::string>()) {
907 pid = std::stoi(context_id.get<std::string>());
909 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert context id."),
914 pid = CurrentApplication::GetInstance().GetProcessId();
917 char* app_id = nullptr;
919 int ret = app_manager_get_app_id(pid, &app_id);
920 // automatically release the memory
921 std::unique_ptr<char, void (*)(void*)> app_id_ptr(app_id, &std::free);
923 if (APP_MANAGER_ERROR_NONE != ret || nullptr == app_id) {
925 case APP_MANAGER_ERROR_NO_SUCH_APP:
926 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "No such application exist."), out,
927 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_NO_SUCH_APP"));
930 case APP_MANAGER_ERROR_INVALID_PARAMETER:
931 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Application not found."), out,
932 ("app_manager_get_app_id returned: APP_MANAGER_ERROR_INVALID_PARAMETER"));
937 PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), out,
938 ("app_manager_get_app_id returned: %d (%s)", ret, get_error_message(ret)));
943 picojson::value result = picojson::value(picojson::object());
944 utils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
946 ReportSuccess(result, *out);
949 void ApplicationManager::GetAppsInfo(const picojson::value& args) {
952 int callback_id = -1;
953 const auto& callback = args.get(kCallbackId);
954 if (callback.is<double>()) {
955 callback_id = static_cast<int>(callback.get<double>());
958 auto get_apps_info = [](const std::shared_ptr<picojson::value>& response) -> void {
959 ScopeLogger("Entered into asynchronous function, get_apps_info");
960 picojson::object& response_obj = response->get<picojson::object>();
961 picojson::value result = picojson::value(picojson::object());
962 picojson::object& result_obj = result.get<picojson::object>();
963 picojson::array& array =
964 result_obj.insert(std::make_pair("informationArray", picojson::value(picojson::array())))
965 .first->second.get<picojson::array>();
967 auto app_info_cb = [](pkgmgrinfo_appinfo_h handle, void* user_data) -> int {
968 ScopeLogger("Entered into asynchronous function, app_info_cb");
969 if (nullptr == user_data) {
973 picojson::array* array = static_cast<picojson::array*>(user_data);
974 array->push_back(picojson::value(picojson::object()));
976 utils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
981 int ret = pkgmgrinfo_appinfo_get_usr_installed_list(app_info_cb, getuid(), &array);
983 if (APP_MANAGER_ERROR_NONE != ret) {
984 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj,
985 ("pkgmgrinfo_appinfo_get_usr_installed_list error"));
987 ReportSuccess(result, response_obj);
991 auto get_apps_info_response =
992 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
993 ScopeLogger("Entered into asynchronous function, get_apps_info_response");
994 picojson::object& obj = response->get<picojson::object>();
995 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
996 Instance::PostMessage(&this->instance_, response->serialize().c_str());
999 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1001 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_info, get_apps_info_response, data);
1004 void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object* out) {
1007 pkgmgrinfo_appinfo_h handle = nullptr;
1009 if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1010 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out);
1014 picojson::value result = picojson::value(picojson::object());
1015 utils::CreateApplicationInformation(handle, &result.get<picojson::object>());
1016 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1018 ReportSuccess(result, *out);
1021 char* ApplicationManager::GetPackageId(const std::string& app_id) {
1024 char* pkg_id = nullptr;
1026 int ret = app_manager_get_app_info(app_id.c_str(), &handle);
1027 if (APP_MANAGER_ERROR_NONE != ret) {
1028 LoggerE("Failed to get app info: %d (%s)", ret, get_error_message(ret));
1032 ret = app_info_get_package(handle, &pkg_id);
1033 if (APP_MANAGER_ERROR_NONE != ret) {
1034 LoggerE("Failed to get package id: %d (%s)", ret, get_error_message(ret));
1038 ret = app_info_destroy(handle);
1039 if (APP_MANAGER_ERROR_NONE != ret) {
1040 LoggerE("Failed to destroy app info: %d (%s)", ret, get_error_message(ret));
1046 void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object* out) {
1049 char* package_id = nullptr;
1051 package_id = GetPackageId(app_id);
1052 // automatically release the memory
1053 std::unique_ptr<char, void (*)(void*)> package_id_ptr(package_id, &std::free);
1056 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out);
1060 package_info_h pkg_info = nullptr;
1061 int ret = package_info_create(package_id, &pkg_info);
1063 std::unique_ptr<std::remove_pointer<package_info_h>::type, int (*)(package_info_h)> pkg_info_ptr(
1064 pkg_info, &package_info_destroy); // automatically release the memory
1066 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1067 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out,
1068 ("Failed to get package info: %d (%s)", ret, get_error_message(ret)));
1072 auto cert_info_cb = [](package_info_h handle, package_cert_type_e cert_type,
1073 const char* cert_value, void* user_data) -> bool {
1074 const char* cert_name = nullptr;
1076 switch (cert_type) {
1077 case PACKAGE_INFO_AUTHOR_ROOT_CERT:
1078 cert_name = "AUTHOR_ROOT";
1080 case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT:
1081 cert_name = "AUTHOR_INTERMEDIATE";
1083 case PACKAGE_INFO_AUTHOR_SIGNER_CERT:
1084 cert_name = "AUTHOR_SIGNER";
1086 case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT:
1087 cert_name = "DISTRIBUTOR_ROOT";
1089 case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT:
1090 cert_name = "DISTRIBUTOR_INTERMEDIATE";
1092 case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT:
1093 cert_name = "DISTRIBUTOR_SIGNER";
1095 case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT:
1096 cert_name = "DISTRIBUTOR2_ROOT";
1098 case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT:
1099 cert_name = "DISTRIBUTOR2_INTERMEDIATE";
1101 case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT:
1102 cert_name = "DISTRIBUTOR2_SIGNER";
1105 LoggerD("Unknown certificate type: %d", cert_type);
1109 picojson::array* array = static_cast<picojson::array*>(user_data);
1110 array->push_back(picojson::value(picojson::object()));
1112 utils::CreateApplicationCertificate(cert_name, cert_value,
1113 &array->back().get<picojson::object>());
1118 picojson::value result = picojson::value(picojson::array());
1120 ret = package_info_foreach_cert_info(pkg_info, cert_info_cb, &result.get<picojson::array>());
1122 if ((PACKAGE_MANAGER_ERROR_NONE != ret) && (PACKAGE_MANAGER_ERROR_IO_ERROR != ret)) {
1123 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get certificates info."),
1125 ("Failed to get certificates info: %d (%s)", ret, get_error_message(ret)));
1129 ReportSuccess(result, *out);
1132 void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::object* out) {
1134 // this implementation assumes that shared/trusted path is the obligatory member of application
1135 // and it is used to extract the parent directory 'shared'
1136 char* path = nullptr;
1137 int ret = app_manager_get_shared_trusted_path(app_id.c_str(), &path);
1138 if (APP_MANAGER_ERROR_NONE != ret) {
1139 // if the application does not exist, there is no need to check "res" directory
1140 if (APP_MANAGER_ERROR_NO_SUCH_APP == ret) {
1141 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get shared URI."), out);
1145 // if the shared_trusted directory is not properly returned, gathering the shared/res path,
1146 // which is the obligatory member. The global path could be different then:
1147 // e.g. instead of path: /opt/usr/home/owner/apps_rw/org.example.basic/shared/
1148 // returned path is: /opt/usr/globalapps/org.example.basic/shared/
1150 "app_manager_get_shared_trusted_path failed(), trying "
1151 "app_manager_get_shared_resource_path() to gather path");
1152 int ret = app_manager_get_shared_resource_path(app_id.c_str(), &path);
1153 if (APP_MANAGER_ERROR_NONE != ret) {
1154 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get shared URI."), out);
1159 std::string path_str = path;
1162 std::string shared_path = path_str.substr(0, path_str.rfind("/", path_str.length() - 2));
1164 // checking if path is valid
1165 struct stat stat_res;
1166 if (0 != stat(shared_path.c_str(), &stat_res)) {
1167 LoggerW("Path %s does not exist", shared_path.c_str());
1168 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get shared URI."), out);
1172 picojson::value result = picojson::value(kTizenApisFileScheme + shared_path);
1173 ReportSuccess(result, *out);
1176 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1177 PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args,
1178 const context_history_filter_h filter,
1179 context_history_data_e* data_type_out) {
1181 int ret = CONTEXT_HISTORY_ERROR_NONE;
1182 int limit = kMaximumBatteryRetrievedObjects;
1183 if (args.contains("limit")) {
1184 limit = static_cast<int>(args.get("limit").get<double>());
1187 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1189 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1190 return LogAndCreateResult(
1191 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1192 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1195 context_history_data_e data_type_in = CONTEXT_HISTORY_RECENT_BATTERY_USAGE;
1197 if (args.contains("days")) {
1198 const int days = static_cast<int>(args.get("days").get<double>());
1199 data_type_in = CONTEXT_HISTORY_BATTERY_USAGE;
1200 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, days);
1202 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1203 return LogAndCreateResult(
1204 ErrorCode::INVALID_VALUES_ERR, "days given with invalid value.",
1205 ("days given with invalid value: %d (%s)", ret, get_error_message(ret)));
1209 *data_type_out = data_type_in;
1211 return PlatformResult(ErrorCode::NO_ERROR);
1214 PlatformResult ApplicationManager::BatteryUsageAttributes(const context_history_record_h record,
1215 picojson::object* object) {
1218 int ret = CONTEXT_HISTORY_ERROR_NONE;
1219 double amount = 0.0;
1220 char* app_id = nullptr;
1225 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1226 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1227 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1228 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1231 ret = context_history_record_get_double(record, CONTEXT_HISTORY_TOTAL_AMOUNT, &amount);
1232 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1233 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get amount.",
1234 ("Failed to get amount: %d (%s)", ret, get_error_message(ret)));
1237 object->insert(std::make_pair("appId", picojson::value(app_id)));
1238 object->insert(std::make_pair("batteryUsage", picojson::value(amount)));
1240 return PlatformResult(ErrorCode::NO_ERROR);
1243 PlatformResult ApplicationManager::AppsUsageFilter(const picojson::value& args,
1244 const context_history_filter_h filter,
1245 context_history_data_e* data_type_out) {
1247 int ret = CONTEXT_HISTORY_ERROR_NONE;
1248 int limit = kMaximumAppsRetrievedObjects;
1249 if (args.contains("limit")) {
1250 limit = static_cast<int>(args.get("limit").get<double>());
1253 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_RESULT_SIZE, limit);
1254 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1255 return LogAndCreateResult(
1256 ErrorCode::INVALID_VALUES_ERR, "limit given with invalid value.",
1257 ("limit given with invalid value: %d (%s)", ret, get_error_message(ret)));
1260 context_history_data_e data_type_in = CONTEXT_HISTORY_FREQUENTLY_USED_APP;
1261 if (args.contains("mode") && kAppUsageModeRecently == args.get("mode").get<std::string>()) {
1262 data_type_in = CONTEXT_HISTORY_RECENTLY_USED_APP;
1265 int time_span = kDefaultPeriodOfTime;
1266 const picojson::object& JS_filter = args.get("filter").get<picojson::object>();
1267 auto time_span_iter = JS_filter.find("timeSpan");
1268 if (JS_filter.end() != time_span_iter || (JS_filter.end() == JS_filter.find("startTime") &&
1269 JS_filter.end() == JS_filter.find("endTime"))) {
1270 // In the second case, we treat the filter object just like an empty object.
1271 // The default value of filter will be used instead.
1272 if (JS_filter.end() != time_span_iter) {
1273 time_span = static_cast<int>(time_span_iter->second.get<double>());
1275 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_TIME_SPAN, time_span);
1276 // context_history_filter_set_int may return only success or
1277 // CONTEXT_HISTORY_ERROR_INVALID_PARAMETER
1278 // Although this should never happen, it's better to check ret's value
1279 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1280 return LogAndCreateResult(ErrorCode::ABORT_ERR,
1281 "Error while setting the default TIME_SPAN value.",
1282 ("Error while setting the default TIME_SPAN value: %d (%s)", ret,
1283 get_error_message(ret)));
1286 auto start_time_iter = JS_filter.find("startTime");
1287 auto end_time_iter = JS_filter.find("endTime");
1288 if (start_time_iter != JS_filter.end()) {
1289 int start_time = static_cast<int>(start_time_iter->second.get<double>());
1290 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_START_TIME, start_time);
1291 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1292 return LogAndCreateResult(
1293 ErrorCode::INVALID_VALUES_ERR, "startTime given with invalid value.",
1294 ("startTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1297 if (end_time_iter != JS_filter.end()) {
1298 int end_time = static_cast<int>(end_time_iter->second.get<double>());
1299 ret = context_history_filter_set_int(filter, CONTEXT_HISTORY_FILTER_END_TIME, end_time);
1300 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1301 return LogAndCreateResult(
1302 ErrorCode::INVALID_VALUES_ERR, "endTime given with invalid value.",
1303 ("endTime given with invalid value: %d (%s)", ret, get_error_message(ret)));
1308 *data_type_out = data_type_in;
1310 return PlatformResult(ErrorCode::NO_ERROR);
1313 PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_record_h record,
1314 picojson::object* object) {
1317 int ret = CONTEXT_HISTORY_ERROR_NONE;
1318 int total_count = 0;
1319 int total_duration = 0;
1321 char* app_id = nullptr;
1326 ret = context_history_record_get_string(record, CONTEXT_HISTORY_APP_ID, &app_id);
1327 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1328 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get string.",
1329 ("Failed to get string: %d (%s)", ret, get_error_message(ret)));
1332 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_COUNT, &total_count);
1333 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1334 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get total count.",
1335 ("Failed to get total count: %d (%s)", ret, get_error_message(ret)));
1338 ret = context_history_record_get_int(record, CONTEXT_HISTORY_TOTAL_DURATION, &total_duration);
1339 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1340 return LogAndCreateResult(
1341 ErrorCode::ABORT_ERR, "Failed to get total duration.",
1342 ("Failed to get total duration: %d (%s)", ret, get_error_message(ret)));
1345 ret = context_history_record_get_int(record, CONTEXT_HISTORY_LAST_TIME, &last_time);
1346 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1347 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get last time.",
1348 ("Failed to get last time: %d (%s)", ret, get_error_message(ret)));
1351 object->insert(std::make_pair("appId", picojson::value(app_id)));
1352 object->insert(std::make_pair("totalCount", picojson::value(static_cast<double>(total_count))));
1354 std::make_pair("totalDuration", picojson::value(static_cast<double>(total_duration))));
1355 object->insert(std::make_pair("lastTime", picojson::value(static_cast<double>(last_time))));
1357 return PlatformResult(ErrorCode::NO_ERROR);
1361 void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
1364 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1365 int callback_id = -1;
1366 const auto& callback = args.get(kCallbackId);
1367 if (callback.is<double>()) {
1368 callback_id = static_cast<int>(callback.get<double>());
1371 auto get_battery_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1373 PlatformResult result = ApplicationManager::GetContextHistory(
1374 args, &response.get()->get<picojson::object>(), &ApplicationManager::BatteryUsageFilter,
1375 &ApplicationManager::BatteryUsageAttributes);
1377 LogAndReportError(result, &response.get()->get<picojson::object>());
1381 auto get_battery_usage_response =
1382 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1384 picojson::object& obj = response->get<picojson::object>();
1385 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1386 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1389 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1391 TaskQueue::GetInstance().Queue<picojson::value>(get_battery_usage, get_battery_usage_response,
1394 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1395 "This feature is not supported on this profile."),
1396 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1400 void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
1403 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1404 int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
1406 auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
1408 PlatformResult result = ApplicationManager::GetContextHistory(
1409 args, &response.get()->get<picojson::object>(), &ApplicationManager::AppsUsageFilter,
1410 &ApplicationManager::AppsUsageAttributes);
1412 LogAndReportError(result, &response.get()->get<picojson::object>());
1416 auto get_apps_usage_response =
1417 [this, callback_id](const std::shared_ptr<picojson::value>& response) -> void {
1419 picojson::object& obj = response->get<picojson::object>();
1420 obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
1421 Instance::PostMessage(&this->instance_, response->serialize().c_str());
1424 auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
1426 TaskQueue::GetInstance().Queue<picojson::value>(get_apps_usage, get_apps_usage_response, data);
1428 LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1429 "This feature is not supported on this profile."),
1430 out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
1434 void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) {
1437 pkgmgrinfo_appinfo_h handle = nullptr;
1439 int ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle);
1440 std::unique_ptr<std::remove_pointer<pkgmgrinfo_appinfo_h>::type, int (*)(pkgmgrinfo_appinfo_h)>
1441 pkg_info_ptr(handle,
1442 &pkgmgrinfo_appinfo_destroy_appinfo); // automatically release the memory
1444 if (PMINFO_R_OK != ret) {
1445 LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out,
1446 ("Failed to get app info: %d (%s)", ret, get_error_message(ret)));
1450 auto meta_data_cb = [](const char* meta_key, const char* meta_value, void* user_data) -> int {
1451 if (nullptr == meta_key || nullptr == meta_value) {
1452 LoggerE("meta_key or meta_value is null");
1456 picojson::array* array = static_cast<picojson::array*>(user_data);
1457 array->push_back(picojson::value(picojson::object()));
1459 utils::CreateApplicationMetaData(meta_key, meta_value, &array->back().get<picojson::object>());
1463 picojson::value result = picojson::value(picojson::array());
1464 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, meta_data_cb, &result.get<picojson::array>());
1466 if (PMINFO_R_OK != ret) {
1467 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get metadata."), out,
1468 ("Failed to get metadata: %d (%s)", ret, get_error_message(ret)));
1472 ReportSuccess(result, *out);
1475 class ApplicationListChangedBroker {
1477 ApplicationListChangedBroker() : event_type_() {
1485 static int ClientStatusListener(unsigned int target_uid, int id, const char* type,
1486 const char* package, const char* key, const char* val,
1487 const void* msg, void* data) {
1489 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1491 if (0 == strcasecmp(key, kStartKey)) {
1492 that->HandleStart(val, package);
1493 } else if (0 == strcasecmp(key, kEndKey) && 0 == strcasecmp(val, kOkValue)) {
1494 that->HandleEnd(package);
1496 LoggerD("Ignored key: %s", key);
1502 static int AppUninstallListener(uid_t target_uid, int id, const char* type, const char* package,
1503 const char* key, const char* val, const void* msg, void* data) {
1506 ApplicationListChangedBroker* that = static_cast<ApplicationListChangedBroker*>(data);
1508 if (0 == strcasecmp(key, kStartKey)) {
1509 that->HandleUninstallStart();
1510 } else if (0 == strcasecmp(key, kAppidKey)) {
1511 that->AddUninstalledAppId(val);
1512 } else if (0 == strcasecmp(key, kEndKey)) {
1513 that->HandleUninstallEnd();
1515 LoggerD("Ignored key: %s", key);
1521 void AddApplicationInstance(ApplicationInstance* app_instance) {
1523 app_instance_list_.push_back(app_instance);
1526 void RemoveApplicationInstance(ApplicationInstance* app_instance) {
1528 for (auto it = app_instance_list_.begin(); it != app_instance_list_.end(); it++) {
1529 if (*it == app_instance) {
1530 app_instance_list_.erase(it);
1537 void HandleStart(const char* event_type, const char* package) {
1540 set_event_type(event_type);
1543 void HandleEnd(const char* package) {
1546 if (Event::kUninstalled == event_type_) {
1550 GetApplicationIdsFromPackage(package);
1552 for (auto& app_id : app_list_) {
1553 picojson::value value = picojson::value(picojson::object());
1554 picojson::object& data_obj = value.get<picojson::object>();
1556 switch (event_type_) {
1557 case Event::kInstalled:
1558 data_obj.insert(std::make_pair(kAction, picojson::value(kOnInstalled)));
1561 case Event::kUpdated:
1562 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUpdated)));
1564 case Event::kUninstalled:
1565 LoggerD("Uninstalled called");
1569 switch (event_type_) {
1570 case Event::kInstalled:
1571 case Event::kUpdated: {
1572 pkgmgrinfo_appinfo_h handle = nullptr;
1574 pkgmgrinfo_appinfo_get_usr_appinfo(app_id.c_str(), getuid(), &handle)) {
1575 LoggerE("Failed to get application information handle.");
1578 auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object())));
1579 utils::CreateApplicationInformation(handle, &info.first->second.get<picojson::object>());
1580 pkgmgrinfo_appinfo_destroy_appinfo(handle);
1582 case Event::kUninstalled:
1583 LoggerD("Uninstalled called");
1587 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1589 for (auto instance : app_instance_list_) {
1590 Instance::PostMessage(instance, value.serialize().c_str());
1595 void GetApplicationIdsFromPackage(const char* package) {
1597 package_info_h package_info = nullptr;
1599 int ret = package_info_create(package, &package_info);
1600 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1601 LoggerE("Failed to create package info: %d (%s)", ret, get_error_message(ret));
1605 ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_APP_COMPONENT_TYPE_ALL,
1606 ApplicationIdCallback, this);
1607 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1608 LoggerE("Failed to get application IDs: %d (%s)", ret, get_error_message(ret));
1611 ret = package_info_destroy(package_info);
1612 if (PACKAGE_MANAGER_ERROR_NONE != ret) {
1613 LoggerE("Failed to destroy package info: %d (%s)", ret, get_error_message(ret));
1617 void set_event_type(const char* type) {
1619 if (0 == strcasecmp(type, kInstallEvent)) {
1620 event_type_ = Event::kInstalled;
1621 } else if (0 == strcasecmp(type, kUpdateEvent)) {
1622 event_type_ = Event::kUpdated;
1623 } else if (0 == strcasecmp(type, kUninstallEvent)) {
1624 event_type_ = Event::kUninstalled;
1628 static bool ApplicationIdCallback(package_info_app_component_type_e comp_type, const char* app_id,
1631 if (nullptr != app_id) {
1632 static_cast<ApplicationListChangedBroker*>(user_data)->app_list_.push_back(app_id);
1637 void HandleUninstallStart() {
1640 set_event_type(kUninstallEvent);
1643 void AddUninstalledAppId(const char* app_id) {
1645 if (nullptr != app_id) {
1646 app_list_.push_back(app_id);
1650 void HandleUninstallEnd() {
1652 for (auto& app_id : app_list_) {
1653 picojson::value value = picojson::value(picojson::object());
1654 picojson::object& data_obj = value.get<picojson::object>();
1656 data_obj.insert(std::make_pair(kAction, picojson::value(kOnUninstalled)));
1657 data_obj.insert(std::make_pair(kData, picojson::value(app_id)));
1659 data_obj["listenerId"] = picojson::value("ApplicationEventListener");
1661 for (auto instance : app_instance_list_) {
1662 Instance::PostMessage(instance, value.serialize().c_str());
1668 std::vector<std::string> app_list_;
1669 std::vector<ApplicationInstance*> app_instance_list_;
1672 static ApplicationListChangedBroker g_application_list_changed_broker;
1674 void ApplicationManager::StartAppInfoEventListener(picojson::object* out) {
1677 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1678 if (nullptr == pkgmgr_client_handle_) {
1679 pkgmgr_client_handle_ = pkgmgr_client_new(PC_LISTENING);
1681 if (nullptr == pkgmgr_client_uninstall_handle_) {
1682 pkgmgr_client_uninstall_handle_ = pkgmgr_client_new(PC_LISTENING);
1685 if (nullptr == pkgmgr_client_handle_ || nullptr == pkgmgr_client_uninstall_handle_) {
1686 if (nullptr != pkgmgr_client_handle_) {
1687 pkgmgr_client_free(pkgmgr_client_handle_);
1688 pkgmgr_client_handle_ = nullptr;
1690 if (nullptr != pkgmgr_client_uninstall_handle_) {
1691 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1692 pkgmgr_client_uninstall_handle_ = nullptr;
1694 LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."),
1699 #define CHECK_APPLICATION_EVENT_ERROR(result, function_name) \
1700 if (PKGMGR_R_OK > result) { \
1701 StopAppInfoEventListener(); \
1702 LogAndReportError( \
1703 PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."), out, \
1704 ("Function %s failed: %s (%d)", function_name, get_error_message(result), result)); \
1708 g_application_list_changed_broker.AddApplicationInstance(&instance_);
1710 int result = pkgmgr_client_set_status_type(
1711 pkgmgr_client_handle_,
1712 PACKAGE_MANAGER_STATUS_TYPE_INSTALL | PACKAGE_MANAGER_STATUS_TYPE_UPGRADE);
1713 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1715 result = pkgmgr_client_set_status_type(pkgmgr_client_uninstall_handle_,
1716 PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL);
1717 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_set_status_type")
1719 result = pkgmgr_client_listen_status(pkgmgr_client_handle_,
1720 ApplicationListChangedBroker::ClientStatusListener,
1721 &g_application_list_changed_broker);
1722 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1724 result = pkgmgr_client_listen_status(pkgmgr_client_uninstall_handle_,
1725 ApplicationListChangedBroker::AppUninstallListener,
1726 &g_application_list_changed_broker);
1727 CHECK_APPLICATION_EVENT_ERROR(result, "pkgmgr_client_listen_status")
1729 #undef CHECK_APPLICATION_EVENT_ERROR
1731 LoggerD("Broker callback is already registered.");
1734 ReportSuccess(*out);
1737 void ApplicationManager::StopAppInfoEventListener() {
1740 if (nullptr != pkgmgr_client_handle_ || nullptr != pkgmgr_client_uninstall_handle_) {
1741 if (nullptr != pkgmgr_client_handle_) {
1742 pkgmgr_client_free(pkgmgr_client_handle_);
1743 pkgmgr_client_handle_ = nullptr;
1745 if (nullptr != pkgmgr_client_uninstall_handle_) {
1746 pkgmgr_client_free(pkgmgr_client_uninstall_handle_);
1747 pkgmgr_client_uninstall_handle_ = nullptr;
1749 g_application_list_changed_broker.RemoveApplicationInstance(&instance_);
1751 LoggerD("Broker callback is already unregistered.");
1755 void ApplicationManager::GetApplicationInformationSize(const picojson::value& args,
1756 picojson::object* out) {
1759 const auto& package_id = args.get("packageId");
1760 if (!package_id.is<std::string>()) {
1761 LogAndReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
1766 const std::string& package_id_str = package_id.get<std::string>();
1768 // get installed size from package server (to solve smack issue)
1769 pkgmgr_client* pc = pkgmgr_client_new(PC_REQUEST);
1772 if (nullptr == pc) {
1773 LoggerE("Failed to create pkgmgr client");
1775 size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL,
1776 package_id_str.c_str(), NULL, NULL, NULL);
1779 LoggerE("Failed to get installed size: %d (%s)", size, get_error_message(size));
1782 pkgmgr_client_free(pc);
1785 picojson::value result = picojson::value(picojson::object());
1786 picojson::object& result_obj = result.get<picojson::object>();
1787 result_obj.insert(std::make_pair("size", picojson::value(static_cast<double>(size))));
1789 ReportSuccess(result, *out);
1792 void ApplicationManager::BroadcastEventHelper(const picojson::value& args, picojson::object& out,
1797 std::string event_str = args.get("name").get<std::string>();
1798 const char* event_name = event_str.c_str();
1800 bundle* data = bundle_create();
1805 ret = bundle_add(data, "data", args.get("data").serialize().c_str());
1807 if (ret != EVENT_ERROR_NONE) {
1808 LoggerE("bundle_add failed, error: %d (%s)", ret, get_error_message(ret));
1814 ret = event_publish_trusted_app_event(event_name, data);
1816 ret = event_publish_app_event(event_name, data);
1819 if (ret == EVENT_ERROR_NONE) {
1822 LoggerE("event_publish_app_event failed, error: %d (%s)", ret, get_error_message(ret));
1827 void ApplicationManager::OnEvent(const char* event_name, bundle* event_data, void* user_data) {
1828 ScopeLogger("Event name is: '%s'", event_name);
1830 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1832 if (!manager->event_callback_) {
1833 LoggerD("No event listener registered, skipping.");
1837 picojson::value event = picojson::value(picojson::object());
1838 picojson::object& event_o = event.get<picojson::object>();
1841 char* val = nullptr;
1843 if (event_map_.count(event_name)) { // system event
1844 const std::string& key = event_map_.at(event_name);
1845 std::string state = "true";
1847 ret = bundle_get_str(event_data, key.c_str(), &val);
1848 if (EVENT_ERROR_NONE != ret) {
1849 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1853 state = std::string(val);
1856 LoggerD("State is %s", state.c_str());
1857 event_o["value"] = picojson::value(state);
1859 } else { // user event
1860 ret = bundle_get_str(event_data, "data", &val);
1861 if (EVENT_ERROR_NONE != ret) {
1862 LoggerE("failed to read bundle data, error: %d (%s)", ret, get_error_message(ret));
1866 picojson::value data;
1868 picojson::parse(data, val, val + strlen(val), &err);
1870 LoggerE("Failed to parse bundle data: %s", err.c_str());
1874 event_o["data"] = data;
1877 LoggerD("event_name is: %s", event_name);
1878 event_o["name"] = picojson::value(event_name);
1880 manager->event_callback_(&event);
1883 PlatformResult ApplicationManager::StartEventListener(const std::string& event_name,
1884 const JsonCallback& callback) {
1888 event_handler_h event_handler;
1890 ret = event_add_event_handler(event_name.c_str(), OnEvent, this, &event_handler);
1891 LoggerD("event_add_event_handler() result: %d (%s)", ret, get_error_message(ret));
1892 if (EVENT_ERROR_PERMISSION_DENIED == ret) {
1893 return LogAndCreateResult(ErrorCode::SECURITY_ERR, "The privilege is required",
1894 ("event_add_event_handler failed, error: %d", ret));
1895 } else if (EVENT_ERROR_NONE != ret) {
1896 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error setting event listener",
1897 ("event_add_event_handler failed, error: %d", ret));
1900 event_handler_map_[event_name] = event_handler;
1902 event_callback_ = callback;
1903 LoggerD("event_add_event_handler success");
1904 return PlatformResult(ErrorCode::NO_ERROR);
1907 void ApplicationManager::StopEventListener(const std::string& event_name) {
1911 event_handler_h event_handler;
1913 if (event_handler_map_.find(event_name) != event_handler_map_.end()) {
1914 event_handler = event_handler_map_[event_name];
1916 ret = event_remove_event_handler(event_handler);
1917 if (EVENT_ERROR_NONE != ret) {
1918 LoggerE("event_remove_event_handler failed, error: %d (%s)", ret, get_error_message(ret));
1922 event_handler_map_.erase(event_name);
1926 void ApplicationManager::OnStatusEvent(const char* type, const char* app_id,
1927 app_manager_event_type_e event_type,
1928 app_manager_event_state_e event_state,
1929 app_manager_event_h handle, void* user_data) {
1932 if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
1933 LoggerD("State different from completed");
1937 ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
1939 if (!manager || !manager->status_callback_) {
1940 LoggerD("No event listener registered, skipping.");
1945 switch (event_type) {
1946 case APP_MANAGER_EVENT_ENABLE_APP:
1949 case APP_MANAGER_EVENT_DISABLE_APP:
1950 status_type = false;
1953 LoggerD("Uknown status type skipping.");
1957 picojson::value event = picojson::value(picojson::object());
1958 picojson::object& event_o = event.get<picojson::object>();
1960 event_o[kStatusType] = picojson::value(status_type);
1961 event_o[kAppId] = picojson::value(app_id);
1962 event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
1964 manager->status_callback_(&event);
1967 #if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
1968 PlatformResult ApplicationManager::GetContextHistory(
1969 const picojson::value& args, picojson::object* out,
1970 common::PlatformResult (*modify_filter_cb)(const picojson::value&,
1971 const context_history_filter_h,
1972 context_history_data_e* data_type),
1973 common::PlatformResult (*add_attributes_to_object)(const context_history_record_h,
1974 picojson::object*)) {
1976 context_history_list_h list = nullptr;
1977 context_history_h handle = nullptr;
1978 context_history_filter_h filter = nullptr;
1981 context_history_list_destroy(list);
1982 context_history_destroy(handle);
1983 context_history_filter_destroy(filter);
1986 int ret = context_history_create(&handle);
1987 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1988 return LogAndCreateResult(
1989 ErrorCode::ABORT_ERR, "Failed to create context handle.",
1990 ("Failed to create context handle: %d (%s)", ret, get_error_message(ret)));
1993 ret = context_history_filter_create(&filter);
1994 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
1995 return LogAndCreateResult(
1996 ErrorCode::ABORT_ERR, "Failed to create filter handle.",
1997 ("Failed to create filter handle: %d (%s)", ret, get_error_message(ret)));
2000 context_history_data_e data_type;
2002 PlatformResult result = modify_filter_cb(args, filter, &data_type);
2007 picojson::value result_array = picojson::value(picojson::array());
2008 picojson::array& array_obj = result_array.get<picojson::array>();
2010 ret = context_history_get_list(handle, data_type, filter, &list);
2011 if (CONTEXT_HISTORY_ERROR_NO_DATA == ret) {
2012 ReportSuccess(result_array, *out);
2013 return PlatformResult(ErrorCode::NO_ERROR);
2014 } else if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2015 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list.",
2016 ("Failed to get list: %d (%s)", ret, get_error_message(ret)));
2020 ret = context_history_list_get_count(list, &size);
2021 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2022 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to get list size.",
2023 ("Failed to get list size: %d (%s)", ret, get_error_message(ret)));
2026 array_obj.resize(size, picojson::value(picojson::object()));
2028 for (int i = 0; i < size; ++i) {
2029 context_history_record_h record = nullptr;
2031 context_history_record_destroy(record);
2034 ret = context_history_list_get_current(list, &record);
2035 if (CONTEXT_HISTORY_ERROR_NONE != ret) {
2036 return LogAndCreateResult(
2037 ErrorCode::ABORT_ERR, "Failed to get current record.",
2038 ("Failed to get current record: %d (%s)", ret, get_error_message(ret)));
2041 result = add_attributes_to_object(record, &array_obj[i].get<picojson::object>());
2046 ret = context_history_list_move_next(list);
2047 if (CONTEXT_HISTORY_ERROR_NONE != ret && CONTEXT_HISTORY_ERROR_NO_DATA != ret) {
2048 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to move iterator.",
2049 ("Failed to move iterator: %d (%s)", ret, get_error_message(ret)));
2053 ReportSuccess(result_array, *out);
2054 return PlatformResult(ErrorCode::NO_ERROR);
2058 PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
2061 int ret = APP_MANAGER_ERROR_NONE;
2063 if (!app_status_handle_) {
2064 ret = app_manager_event_create(&app_status_handle_);
2065 if (APP_MANAGER_ERROR_NONE != ret) {
2066 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
2067 ("app_manager_event_create failed, error: %d", ret));
2070 ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
2071 if (APP_MANAGER_ERROR_NONE != ret) {
2072 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
2073 ("app_manager_event_set_status failed, error: %d", ret));
2077 status_callback_ = callback;
2078 ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
2079 if (APP_MANAGER_ERROR_NONE != ret) {
2080 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
2081 ("app_manager_set_event_cb failed, error: %d", ret));
2084 return PlatformResult(ErrorCode::NO_ERROR);
2087 PlatformResult ApplicationManager::StopStatusChangeListener() {
2090 if (app_status_handle_) {
2091 int ret = app_manager_unset_event_cb(app_status_handle_);
2092 if (APP_MANAGER_ERROR_NONE != ret) {
2093 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
2094 ("app_manager_unset_event_cb failed, error: %d", ret));
2098 return PlatformResult(ErrorCode::NO_ERROR);
2101 } // namespace application
2102 } // namespace extension