[Common] Changed configuration for common profile build
[platform/core/api/webapi-plugins.git] / src / application / application_manager.cc
index a4b3057..c8c7c25 100644 (file)
@@ -16,9 +16,9 @@
 
 #include "application_manager.h"
 
-#include <glib.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <thread>
 #include <type_traits>
 
 #include <app_control_internal.h>
@@ -99,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),
@@ -133,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) {
@@ -150,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());
@@ -389,7 +404,7 @@ PlatformResult PrepareAppControlForLaunchAppControl(const picojson::value& args,
   const picojson::object& app_control_obj = control.get<picojson::object>();
 
   app_control_h tmp_app_control = nullptr;
-  auto result = ApplicationUtils::ApplicationControlToService(app_control_obj, &tmp_app_control);
+  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);
 
@@ -452,11 +467,7 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
     reply_callback_id = reply.get<std::string>();
   }
 
-  struct LaunchAppControlCallbackData {
-    ApplicationInstance* instance;
-    std::shared_ptr<picojson::value> response;
-    std::string reply_callback_id;
-  }* launch_app_user_data = new (std::nothrow)
+  LaunchAppControlCallbackData* launch_app_user_data = new (std::nothrow)
       LaunchAppControlCallbackData{&this->instance_, response, reply_callback_id};
 
   if (!launch_app_user_data) {
@@ -475,8 +486,10 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
 
       LaunchAppControlCallbackData* callback_data =
           static_cast<LaunchAppControlCallbackData*>(user_data);
-      if (!callback_data) {
-        LoggerD("reply_callback failed: user_data is nullptr");
+
+      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;
       }
 
@@ -488,7 +501,7 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
       if (APP_CONTROL_RESULT_SUCCEEDED == result) {
         LoggerD("App started");
         return_value_obj.insert(std::make_pair("data", picojson::value(picojson::array())));
-        if (!ApplicationUtils::ServiceToApplicationControlDataArray(
+        if (!utils::ServiceToApplicationControlDataArray(
                 reply, &return_value_obj.find("data")->second.get<picojson::array>())) {
           return_value_obj.erase("data");
         }
@@ -498,7 +511,9 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
       }
 
       Instance::PostMessage(callback_data->instance, return_value.serialize().c_str());
-      delete callback_data;
+      // 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
     };
   }
 
@@ -509,7 +524,13 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
     LaunchAppControlCallbackData* callback_data =
         static_cast<LaunchAppControlCallbackData*>(user_data);
 
-    auto result = ApplicationUtils::TranslateAppControlError(launch_result);
+    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;
+    }
+
+    auto result = utils::TranslateAppControlError(launch_result);
 
     if (result.IsError()) {
       LogAndReportError(result, &(callback_data->response->get<picojson::object>()));
@@ -519,9 +540,9 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
 
     Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str());
 
-    if (result.IsError() || (callback_data->reply_callback_id).empty()) {
-      delete callback_data;
-    }
+    // 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
   };
 
   /*
@@ -531,7 +552,7 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
    * 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 = ApplicationUtils::TranslateAppControlError(
+  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)));
 
@@ -539,16 +560,26 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) {
     delete launch_app_user_data;
     AsyncResponse(launch_result, &response);
   } else {
-    LoggerD("App launched");
+    // 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 {
 
 PlatformResult TranslateLaunchError(app_control_error_e return_code) {
   ScopeLogger();
 
-  auto result = ApplicationUtils::TranslateAppControlError(return_code);
+  auto result = utils::TranslateAppControlError(return_code);
   if (ErrorCode::SECURITY_ERR == result.error_code()) {
     result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
   }
@@ -641,15 +672,14 @@ void ApplicationManager::Launch(const picojson::value& args) {
   };
 
   /*
-   * TODO: Observe how often app_control_send_launch_request_async tries to launch the application.
+   * 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_launch_request_async makes only one attempt.
+   * 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_launch_request_async(
-          app_control_ptr.get(), result_callback, nullptr, launch_user_data)));
+  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;
@@ -753,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
 
@@ -781,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);
       }
 
@@ -858,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;
       }
@@ -935,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);
 }
@@ -967,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;
     };
@@ -1007,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);
@@ -1104,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;
   };
@@ -1168,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) {
@@ -1356,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>()) {
@@ -1395,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 {
@@ -1451,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;
   };
 
@@ -1572,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:
@@ -1599,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));
@@ -1961,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&,