[Common] Changed configuration for common profile build
[platform/core/api/webapi-plugins.git] / src / application / application_manager.cc
index 69e2a55..c8c7c25 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <sys/stat.h>
 #include <unistd.h>
+#include <thread>
 #include <type_traits>
 
 #include <app_control_internal.h>
@@ -98,13 +99,16 @@ const std::map<std::string, std::string> event_map_ = {
     {SYSTEM_EVENT_DATA_ROAMING_STATE, EVENT_KEY_DATA_ROAMING_STATE},
     {SYSTEM_EVENT_FONT_SET, EVENT_KEY_FONT_SET}};
 
-#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
+#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE) || defined(TIZEN_COMMON)
 const int kMaximumBatteryRetrievedObjects = 30;
 const int kMaximumAppsRetrievedObjects = 10;
 const int kDefaultPeriodOfTime = 30;
 #endif
 }
 
+std::set<LaunchAppControlCallbackData*> ApplicationManager::launch_app_control_set_global_{};
+std::mutex ApplicationManager::launch_app_control_set_mutex_{};
+
 ApplicationManager::ApplicationManager(ApplicationInstance& instance)
     : pkgmgr_client_handle_(nullptr),
       pkgmgr_client_uninstall_handle_(nullptr),
@@ -132,6 +136,18 @@ ApplicationManager::~ApplicationManager() {
       LoggerE("app_manager_event_destroy failed, error: %d", ret);
     }
   }
+
+  // Calling order of reply_callback and result_callback of launchAppControl
+  // cannot be determined, reply_callback depends on application scenario, which
+  // cannot be predicted. Moreover reply_callback is optional and can be called or not,
+  // thus callback_data is relesed here at the end of application lifetime.
+  std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+  std::for_each(launch_app_control_set_.begin(), launch_app_control_set_.end(),
+                [](LaunchAppControlCallbackData* const& data) {
+                  LoggerD("Releasing callback data: %p", data);
+                  delete data;
+                  launch_app_control_set_global_.erase(data);
+                });
 }
 
 void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
@@ -149,7 +165,7 @@ void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojs
   picojson::value app_info = picojson::value(picojson::object());
   picojson::object& app_info_obj = app_info.get<picojson::object>();
 
-  ApplicationUtils::CreateApplicationInformation(handle, &app_info_obj);
+  utils::CreateApplicationInformation(handle, &app_info_obj);
   pkgmgrinfo_appinfo_destroy_appinfo(handle);
 
   picojson::value result = picojson::value(picojson::object());
@@ -213,7 +229,7 @@ class TerminateHandler {
     return;                                                        \
   }
 
-void ApplicationManager::AsyncResponse(PlatformResult& result,
+void ApplicationManager::AsyncResponse(const PlatformResult& result,
                                        std::shared_ptr<picojson::value>* response) {
   ScopeLogger();
   LogAndReportError(result, &(*response)->get<picojson::object>());
@@ -375,82 +391,52 @@ void ApplicationManager::Kill(const picojson::value& args) {
   kill();
 }
 
-void ApplicationManager::Launch(const picojson::value& args) {
+namespace {
+
+PlatformResult PrepareAppControlForLaunchAppControl(const picojson::value& args,
+                                                    app_control_h* app_control) {
   ScopeLogger();
 
-  int callback_id = -1;
-  const auto& callback = args.get(kCallbackId);
-  if (callback.is<double>()) {
-    callback_id = static_cast<int>(callback.get<double>());
+  const auto& control = args.get("appControl");
+  if (!control.is<picojson::object>()) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
   }
+  const picojson::object& app_control_obj = control.get<picojson::object>();
 
-  std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
-  picojson::object& obj = response->get<picojson::object>();
-  obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+  app_control_h tmp_app_control = nullptr;
+  auto result = utils::ApplicationControlToService(app_control_obj, &tmp_app_control);
+  std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+      app_control_ptr(tmp_app_control, &app_control_destroy);
 
-  const auto& app_id = args.get("id");
-  if (!app_id.is<std::string>()) {
-    PlatformResult ret =
-        LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
-    AsyncResponse(ret, &response);
-    return;
+  if (result.IsError()) {
+    LoggerE("Application control to service failed.");
+    return result;
   }
-  const std::string& id = app_id.get<std::string>();
-
-  auto launch = [id](const std::shared_ptr<picojson::value>& response) -> void {
-    ScopeLogger("launch");
-    PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
-    const char* app_id = id.c_str();
-    const int retry_count = 3;
 
-    int retry = 0;
-    int ret = 0;
-
-    while (retry < retry_count) {
-      ret = aul_open_app(app_id);
+  std::string app_id;
+  const auto& id = args.get("id");
+  if (id.is<std::string>()) {
+    app_id = id.get<std::string>();
+  }
 
-      if (ret >= 0) {
-        break;
-      }
+  if (!app_id.empty()) {
+    LoggerD("app_id: %s", app_id.c_str());
 
-      // delay 300ms for each retry
-      struct timespec sleep_time = {0, 300L * 1000L * 1000L};
-      nanosleep(&sleep_time, nullptr);
-      ++retry;
+    int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
 
-      LoggerD("Retry launch request: %d", retry);
+    if (APP_CONTROL_ERROR_NONE != ret) {
+      LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
+      return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
     }
+  }
 
-    if (ret < 0) {
-      result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error has occurred.");
-
-      LoggerD("Aul open return: %d (%s)", ret, get_error_message(ret));
-      switch (ret) {
-        case AUL_R_EINVAL:
-        case AUL_R_ERROR:
-        case AUL_R_ENOAPP:
-          result =
-              LogAndCreateResult(ErrorCode::NOT_FOUND_ERR, "Launchpad returns not found error.",
-                                 ("aul_open_app returns Not Found error"));
-          break;
-
-        case AUL_R_ECOMM:
-          result = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Internal IPC error has occurred.",
-                                      ("aul_open_app returns internal IPC error"));
-          break;
-      }
-
-      LogAndReportError(result, &response->get<picojson::object>());
-    } else {
-      LoggerD("Launch request success");
-      ReportSuccess(response->get<picojson::object>());
-    }
-  };
+  *app_control = app_control_ptr.release();
 
-  launch(response);
-  Instance::PostMessage(&this->instance_, response->serialize().c_str());
+  return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+}  // namespace
+
 void ApplicationManager::LaunchAppControl(const picojson::value& args) {
   ScopeLogger();
 
@@ -465,180 +451,242 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
   response_obj.insert(
       std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
 
-  PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
-  const auto& control = args.get("appControl");
-  if (!control.is<picojson::object>()) {
-    result = LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
-    AsyncResponse(result, &response);
-    return;
-  }
-  const picojson::object& app_control_obj = control.get<picojson::object>();
-
-  std::string launch_mode_str;
-  const auto& launch_mode = control.get("launchMode");
-  if (launch_mode.is<std::string>()) {
-    launch_mode_str = launch_mode.get<std::string>();
-  }
-
   app_control_h app_control = nullptr;
-  result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
-  std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
-      app_control, &app_control_destroy);  // automatically release the memory
-
-  if (result.IsError()) {
-    LoggerE("Application control to service failed.");
-    AsyncResponse(result, &response);
+  auto prepare_app_control_result = PrepareAppControlForLaunchAppControl(args, &app_control);
+  if (prepare_app_control_result.IsError()) {
+    AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
     return;
   }
 
-  std::string app_id;
-  const auto& id = args.get("id");
-  if (id.is<std::string>()) {
-    app_id = id.get<std::string>();
-  }
+  std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+      app_control_ptr(app_control, &app_control_destroy);
 
-  std::string reply_callback;
+  std::string reply_callback_id;
   const auto& reply = args.get("replyCallback");
   if (reply.is<std::string>()) {
-    reply_callback = reply.get<std::string>();
+    reply_callback_id = reply.get<std::string>();
   }
 
-  auto launch = [this, app_control_ptr, app_id, launch_mode_str,
-                 reply_callback](const std::shared_ptr<picojson::value>& response) -> void {
-    ScopeLogger("Entered into asynchronous function, launch");
+  LaunchAppControlCallbackData* launch_app_user_data = new (std::nothrow)
+      LaunchAppControlCallbackData{&this->instance_, response, reply_callback_id};
 
-    if (!app_id.empty()) {
-      LoggerD("app_id: %s", app_id.c_str());
+  if (!launch_app_user_data) {
+    LoggerE("Memory allocation fail!");
+    AsyncResponse(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response);
+    return;
+  }
 
-      int ret = app_control_set_app_id(app_control_ptr.get(), app_id.c_str());
+  app_control_reply_cb reply_callback = nullptr;
+  if (!reply_callback_id.empty()) {
+    launch_app_user_data->reply_callback_id = reply_callback_id;
 
-      if (APP_CONTROL_ERROR_NONE != ret) {
-        LogAndReportError(
-            PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
-            &response->get<picojson::object>(),
-            ("Failed to set app id: %d (%s)", ret, get_error_message(ret)));
-        return;
-      }
-    }
+    reply_callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
+                        void* user_data) {
+      ScopeLogger("reply_callback");
 
-    if (!launch_mode_str.empty()) {
-      app_control_launch_mode_e launch_mode;
+      LaunchAppControlCallbackData* callback_data =
+          static_cast<LaunchAppControlCallbackData*>(user_data);
 
-      if ("SINGLE" == launch_mode_str) {
-        launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
-      } else if ("GROUP" == launch_mode_str) {
-        launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP;
-      } else {
-        ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."),
-                    &response->get<picojson::object>());
+      std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+      if (!launch_app_control_set_global_.count(callback_data)) {
+        LoggerE("Invalid callback_data: %p", callback_data);
         return;
       }
 
-      int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode);
-      if (APP_CONTROL_ERROR_NONE != ret) {
-        LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."),
-                          &response->get<picojson::object>(),
-                          ("Setting launch mode failed: %d (%s)", ret, get_error_message(ret)));
-        return;
+      picojson::value return_value = picojson::value(picojson::object());
+      picojson::object& return_value_obj = return_value.get<picojson::object>();
+      return_value_obj.insert(
+          std::make_pair(kListenerId, picojson::value(callback_data->reply_callback_id)));
+
+      if (APP_CONTROL_RESULT_SUCCEEDED == result) {
+        LoggerD("App started");
+        return_value_obj.insert(std::make_pair("data", picojson::value(picojson::array())));
+        if (!utils::ServiceToApplicationControlDataArray(
+                reply, &return_value_obj.find("data")->second.get<picojson::array>())) {
+          return_value_obj.erase("data");
+        }
+        ReportSuccess(return_value_obj);
+      } else {
+        ReportError(return_value_obj);
       }
-    }
 
-    app_control_reply_cb callback = nullptr;
-    struct ReplayCallbackData {
-      ApplicationInstance* app_instance;
-      std::string reply_callback;
+      Instance::PostMessage(callback_data->instance, return_value.serialize().c_str());
+      // Calling order of reply_callback and result_callback cannot be determined,
+      // thus callback_data is not released here, but stored for release in destructor of
+      // ApplicationManager
     };
+  }
 
-    ReplayCallbackData* user_data = nullptr;
-
-    if (!reply_callback.empty()) {
-      user_data = new ReplayCallbackData();
-      user_data->app_instance = &this->instance_;
-      user_data->reply_callback = reply_callback;
+  app_control_result_cb result_callback = [](app_control_h launch_request,
+                                             app_control_error_e launch_result, void* user_data) {
+    ScopeLogger("LaunchAppControl result_callback");
 
-      callback = [](app_control_h request, app_control_h reply, app_control_result_e result,
-                    void* user_data) {
-        LoggerD("send_launch_request callback");
+    LaunchAppControlCallbackData* callback_data =
+        static_cast<LaunchAppControlCallbackData*>(user_data);
 
-        picojson::value return_value = picojson::value(picojson::object());
-        picojson::object& return_value_obj = return_value.get<picojson::object>();
-        ReplayCallbackData* reply_callback = static_cast<ReplayCallbackData*>(user_data);
+    std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+    if (!launch_app_control_set_global_.count(callback_data)) {
+      LoggerE("Invalid callback_data: %p", callback_data);
+      return;
+    }
 
-        if (APP_CONTROL_RESULT_SUCCEEDED == result) {
-          const std::string data = "data";
-          return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array())));
-          if (!ApplicationUtils::ServiceToApplicationControlDataArray(
-                  reply, &return_value_obj.find(data)->second.get<picojson::array>())) {
-            return_value_obj.erase(data);
-          }
-          ReportSuccess(return_value_obj);
-        } else {
-          ReportError(return_value_obj);
-        }
+    auto result = utils::TranslateAppControlError(launch_result);
 
-        return_value_obj.insert(
-            std::make_pair("listenerId", picojson::value(reply_callback->reply_callback)));
-        Instance::PostMessage(reply_callback->app_instance, return_value.serialize().c_str());
-        delete reply_callback;
-      };
+    if (result.IsError()) {
+      LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
+    } else {
+      ReportSuccess(callback_data->response->get<picojson::object>());
     }
 
-    const int retry_count = 3;
+    Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
 
-    int retry = 0;
-    int ret = 0;
+    // Calling order of reply_callback and result_callback cannot be determined,
+    // thus callback_data is not released here, but stored for release in destructor of
+    // ApplicationManager
+  };
 
-    while (retry < retry_count) {
-      LoggerD("Calling launch request. Attempt number: %d", retry);
+  /*
+   * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
+   * Previous implementation, using synchronous app_control_send_launch_request,
+   * tries to launch the application 3 times, before reporting an error.
+   * New implementation, using app_control_send_launch_request_async makes only one attempt.
+   * If problems, such as failed application start occur, multiple attempts may solve the problem.
+   */
+  auto launch_result = utils::TranslateAppControlError(
+      static_cast<app_control_error_e>(app_control_send_launch_request_async(
+          app_control_ptr.get(), result_callback, reply_callback, launch_app_user_data)));
+
+  if (launch_result.IsError()) {
+    delete launch_app_user_data;
+    AsyncResponse(launch_result, &response);
+  } else {
+    // Calling order of reply_callback and result_callback cannot be determined,
+    // reply_callback depends on application scenario, which cannot be predicted.
+    // Moreover reply_callback is optional and can be called or not,
+    // thus callback_data is stored for releasing in destructor of ApplicationManager
+    // at the end of application lifetime.
+    // We can not be sure whether callbach will not fire after instance destruction,
+    // we store all user_data pointers in static launch_app_control_set_global_ to check
+    // if they are still valid.
+    std::lock_guard<std::mutex> lock(launch_app_control_set_mutex_);
+    launch_app_control_set_.insert(launch_app_user_data);
+    launch_app_control_set_global_.insert(launch_app_user_data);
+    LoggerD("App launched, data %p stored for later release", launch_app_user_data);
+  }
+}
+namespace {
 
-      ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data);
-      LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret));
-      if (APP_CONTROL_ERROR_NONE == ret) {
-        break;
-      }
+PlatformResult TranslateLaunchError(app_control_error_e return_code) {
+  ScopeLogger();
 
-      // delay 300ms for each retry
-      struct timespec sleep_time = {0, 300L * 1000L * 1000L};
-      nanosleep(&sleep_time, nullptr);
-      ++retry;
-    }
+  auto result = utils::TranslateAppControlError(return_code);
+  if (ErrorCode::SECURITY_ERR == result.error_code()) {
+    result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
+  }
+
+  return result;
+}
+
+PlatformResult PrepareAppControlForLaunch(const picojson::value& args, app_control_h* app_control) {
+  ScopeLogger();
+
+  const auto& app_id = args.get("id");
+  if (!app_id.is<std::string>()) {
+    return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
+  }
+  const auto app_id_str = app_id.get<std::string>();
+
+  app_control_h tmp_app_control = nullptr;
+  int result = app_control_create(&tmp_app_control);
+  if (APP_CONTROL_ERROR_NONE != result) {
+    LoggerD("app_control_create() failed: %d (%s)", result, get_error_message(result));
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred.");
+  }
+
+  std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+      app_control_ptr(tmp_app_control, &app_control_destroy);
+
+  if (!app_id_str.empty()) {
+    LoggerD("app_id: %s", app_id_str.c_str());
+
+    int ret = app_control_set_app_id(app_control_ptr.get(), app_id_str.c_str());
 
     if (APP_CONTROL_ERROR_NONE != ret) {
-      delete user_data;
-
-      switch (ret) {
-        case APP_CONTROL_ERROR_INVALID_PARAMETER:
-          LogAndReportError(
-              PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."),
-              &response->get<picojson::object>(),
-              ("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER"));
-          return;
-        case APP_CONTROL_ERROR_OUT_OF_MEMORY:
-          LogAndReportError(
-              PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."),
-              &response->get<picojson::object>(),
-              ("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY"));
-          return;
-        case APP_CONTROL_ERROR_LAUNCH_REJECTED:
-        case APP_CONTROL_ERROR_APP_NOT_FOUND:
-          LogAndReportError(
-              PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."),
-              &response->get<picojson::object>(),
-              ("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND"));
-          return;
-        default:
-          LogAndReportError(
-              PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."),
-              &response->get<picojson::object>(),
-              ("app_control_send_launch_request returns: %d (%s)", ret, get_error_message(ret)));
-          return;
-      }
+      LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret));
+      return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
     }
-    ReportSuccess(response->get<picojson::object>());
+  }
+
+  *app_control = app_control_ptr.release();
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+}  // namespace
+void ApplicationManager::Launch(const picojson::value& args) {
+  ScopeLogger();
+
+  int callback_id = -1;
+  const auto& callback = args.get(kCallbackId);
+  if (callback.is<double>()) {
+    callback_id = static_cast<int>(callback.get<double>());
+  }
+
+  std::shared_ptr<picojson::value> response(new picojson::value(picojson::object()));
+  picojson::object& response_obj = response->get<picojson::object>();
+  response_obj.insert(
+      std::make_pair(kCallbackId, picojson::value(static_cast<double>(callback_id))));
+
+  app_control_h app_control = nullptr;
+  auto prepare_app_control_result = PrepareAppControlForLaunch(args, &app_control);
+  if (prepare_app_control_result.IsError()) {
+    AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response);
+    return;
+  }
+
+  std::unique_ptr<std::remove_pointer<app_control_h>::type, decltype(&app_control_destroy)>
+      app_control_ptr(app_control, &app_control_destroy);
+
+  struct LaunchCallbackData {
+    ApplicationInstance* instance;
+    std::shared_ptr<picojson::value> response;
+  }* launch_user_data = new (std::nothrow) LaunchCallbackData{&this->instance_, response};
+
+  app_control_result_cb result_callback = [](app_control_h launch_request,
+                                             app_control_error_e launch_result, void* user_data) {
+    ScopeLogger("Launch result_callback");
+
+    LaunchCallbackData* callback_data = static_cast<LaunchCallbackData*>(user_data);
+
+    auto result = TranslateLaunchError(launch_result);
+
+    if (result.IsError()) {
+      LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
+    } else {
+      ReportSuccess(callback_data->response->get<picojson::object>());
+    }
+
+    Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
+
+    delete callback_data;
   };
 
-  launch(response);
-  Instance::PostMessage(&this->instance_, response->serialize().c_str());
+  /*
+   * TODO: Observe how often app_control_send_resume_request tries to launch the application.
+   * Previous implementation, using synchronous app_control_send_launch_request,
+   * tries to launch the application 3 times, before reporting an error.
+   * New implementation, using app_control_send_resume_request makes only one attempt.
+   * If problems, such as failed application start occur, multiple attempts may solve the problem.
+   */
+  auto launch_result = TranslateLaunchError(static_cast<app_control_error_e>(
+      app_control_send_resume_request(app_control_ptr.get(), result_callback, launch_user_data)));
+
+  if (launch_result.IsError()) {
+    delete launch_user_data;
+    AsyncResponse(launch_result, &response);
+  } else {
+    LoggerD("App launched");
+  }
 }
 
 // internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND
@@ -735,7 +783,7 @@ void ApplicationManager::FindAppControl(const picojson::value& args) {
   const picojson::object& app_control_obj = control.get<picojson::object>();
 
   app_control_h app_control = nullptr;
-  result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control);
+  result = utils::ApplicationControlToService(app_control_obj, &app_control);
   std::shared_ptr<std::remove_pointer<app_control_h>::type> app_control_ptr(
       app_control, &app_control_destroy);  // automatically release the memory
 
@@ -763,8 +811,7 @@ void ApplicationManager::FindAppControl(const picojson::value& args) {
         picojson::array* array = static_cast<picojson::array*>(user_data);
         array->push_back(picojson::value(picojson::object()));
 
-        ApplicationUtils::CreateApplicationInformation(handle,
-                                                       &array->back().get<picojson::object>());
+        utils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
         pkgmgrinfo_appinfo_destroy_appinfo(handle);
       }
 
@@ -840,8 +887,7 @@ void ApplicationManager::GetAppsContext(const picojson::value& args) {
       picojson::array* array = static_cast<picojson::array*>(user_data);
       array->push_back(picojson::value(picojson::object()));
 
-      if (!ApplicationUtils::CreateApplicationContext(app_context,
-                                                      &array->back().get<picojson::object>())) {
+      if (!utils::CreateApplicationContext(app_context, &array->back().get<picojson::object>())) {
         array->pop_back();
         return false;
       }
@@ -917,7 +963,7 @@ void ApplicationManager::GetAppContext(const picojson::value& args, picojson::ob
   }
 
   picojson::value result = picojson::value(picojson::object());
-  ApplicationUtils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
+  utils::CreateApplicationContext(pid, app_id, &result.get<picojson::object>());
 
   ReportSuccess(result, *out);
 }
@@ -949,8 +995,7 @@ void ApplicationManager::GetAppsInfo(const picojson::value& args) {
       picojson::array* array = static_cast<picojson::array*>(user_data);
       array->push_back(picojson::value(picojson::object()));
 
-      ApplicationUtils::CreateApplicationInformation(handle,
-                                                     &array->back().get<picojson::object>());
+      utils::CreateApplicationInformation(handle, &array->back().get<picojson::object>());
 
       return 0;
     };
@@ -989,7 +1034,7 @@ void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object*
   }
 
   picojson::value result = picojson::value(picojson::object());
-  ApplicationUtils::CreateApplicationInformation(handle, &result.get<picojson::object>());
+  utils::CreateApplicationInformation(handle, &result.get<picojson::object>());
   pkgmgrinfo_appinfo_destroy_appinfo(handle);
 
   ReportSuccess(result, *out);
@@ -1086,8 +1131,8 @@ void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object
     picojson::array* array = static_cast<picojson::array*>(user_data);
     array->push_back(picojson::value(picojson::object()));
 
-    ApplicationUtils::CreateApplicationCertificate(cert_name, cert_value,
-                                                   &array->back().get<picojson::object>());
+    utils::CreateApplicationCertificate(cert_name, cert_value,
+                                        &array->back().get<picojson::object>());
 
     return true;
   };
@@ -1150,7 +1195,7 @@ void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::ob
   ReportSuccess(result, *out);
 }
 
-#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
+#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE) || defined(TIZEN_COMMON)
 PlatformResult ApplicationManager::BatteryUsageFilter(const picojson::value& args,
                                                       const context_history_filter_h filter,
                                                       context_history_data_e* data_type_out) {
@@ -1338,7 +1383,7 @@ PlatformResult ApplicationManager::AppsUsageAttributes(const context_history_rec
 void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojson::object* out) {
   ScopeLogger();
 
-#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
+#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE) || defined(TIZEN_COMMON)
   int callback_id = -1;
   const auto& callback = args.get(kCallbackId);
   if (callback.is<double>()) {
@@ -1368,8 +1413,6 @@ void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojs
   TaskQueue::GetInstance().Queue<picojson::value>(get_battery_usage, get_battery_usage_response,
                                                   data);
 #else
-  // 20170510 Context API is supported only for mobile profile, other ones would result with
-  // NotSupportedError
   LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
                                    "This feature is not supported on this profile."),
                     out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
@@ -1379,7 +1422,7 @@ void ApplicationManager::GetBatteryUsageInfo(const picojson::value& args, picojs
 void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson::object* out) {
   ScopeLogger();
 
-#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
+#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE) || defined(TIZEN_COMMON)
   int callback_id = static_cast<int>(args.get(kCallbackId).get<double>());
 
   auto get_apps_usage = [args](const std::shared_ptr<picojson::value>& response) -> void {
@@ -1404,8 +1447,6 @@ void ApplicationManager::GetAppsUsageInfo(const picojson::value& args, picojson:
 
   TaskQueue::GetInstance().Queue<picojson::value>(get_apps_usage, get_apps_usage_response, data);
 #else
-  // Context API is supported only for mobile profile, other ones would result with
-  // NotSupportedError
   LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
                                    "This feature is not supported on this profile."),
                     out, ("NOT_SUPPORTED_ERR: This feature is not supported on this profile"));
@@ -1437,8 +1478,7 @@ void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::obj
     picojson::array* array = static_cast<picojson::array*>(user_data);
     array->push_back(picojson::value(picojson::object()));
 
-    ApplicationUtils::CreateApplicationMetaData(meta_key, meta_value,
-                                                &array->back().get<picojson::object>());
+    utils::CreateApplicationMetaData(meta_key, meta_value, &array->back().get<picojson::object>());
     return 0;
   };
 
@@ -1558,8 +1598,7 @@ class ApplicationListChangedBroker {
             continue;
           }
           auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object())));
-          ApplicationUtils::CreateApplicationInformation(
-              handle, &info.first->second.get<picojson::object>());
+          utils::CreateApplicationInformation(handle, &info.first->second.get<picojson::object>());
           pkgmgrinfo_appinfo_destroy_appinfo(handle);
         } break;
         case Event::kUninstalled:
@@ -1585,7 +1624,7 @@ class ApplicationListChangedBroker {
       return;
     }
 
-    ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_ALLAPP,
+    ret = package_info_foreach_app_from_package(package_info, PACKAGE_INFO_APP_COMPONENT_TYPE_ALL,
                                                 ApplicationIdCallback, this);
     if (PACKAGE_MANAGER_ERROR_NONE != ret) {
       LoggerE("Failed to get application IDs: %d (%s)", ret, get_error_message(ret));
@@ -1947,7 +1986,7 @@ void ApplicationManager::OnStatusEvent(const char* type, const char* app_id,
   manager->status_callback_(&event);
 }
 
-#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE)
+#if defined(TIZEN_MOBILE) || defined(TIZEN_WEARABLE) || defined(TIZEN_COMMON)
 PlatformResult ApplicationManager::GetContextHistory(
     const picojson::value& args, picojson::object* out,
     common::PlatformResult (*modify_filter_cb)(const picojson::value&,