[Application] Fixed behaviour of clearing data for reply callbacks
[platform/core/api/webapi-plugins.git] / src / application / application_manager.cc
index 7b77545..4de3140 100644 (file)
@@ -19,6 +19,7 @@
 #include <glib.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <thread>
 #include <type_traits>
 
 #include <app_control_internal.h>
@@ -133,6 +134,16 @@ 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::for_each(launch_app_control_set.begin(), launch_app_control_set.end(),
+                [](LaunchAppControlCallbackData* const& data) {
+                  LoggerD("Releasing callback data: %p", data);
+                  delete data;
+                });
 }
 
 void ApplicationManager::GetCurrentApplication(const std::string& app_id, picojson::object* out) {
@@ -452,11 +463,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) {
@@ -498,7 +505,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
     };
   }
 
@@ -519,9 +528,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
   };
 
   /*
@@ -539,10 +548,15 @@ 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.
+    launch_app_control_set.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) {
@@ -641,15 +655,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;