Refactor PluginExecutor
authorChanggyu Choi <changyu.choi@samsung.com>
Tue, 11 Mar 2025 05:04:11 +0000 (14:04 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Tue, 11 Mar 2025 05:04:11 +0000 (14:04 +0900)
To comply with OCP, we implemented PluginExecutor as an abstraction of AbstractActionExecutor.

Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
13 files changed:
src/action/action_executor_factory.cc [new file with mode: 0644]
src/action/action_executor_factory.hh [new file with mode: 0644]
src/action/action_request_handler.cc
src/action/action_request_handler.hh
src/action/app_control_executor.cc
src/action/app_control_executor.hh
src/action/plugin_executor.cc [new file with mode: 0644]
src/action/plugin_executor.hh [new file with mode: 0644]
src/action/result_handler.hh [deleted file]
src/common/action_executor.hh
src/common/result_handler.hh [new file with mode: 0644]
src/plugin-daemon/main.cc
tidl/plugin_manager.tidl

diff --git a/src/action/action_executor_factory.cc b/src/action/action_executor_factory.cc
new file mode 100644 (file)
index 0000000..f641bd7
--- /dev/null
@@ -0,0 +1,6 @@
+#include "action_executor_factory.hh"
+
+std::unique_ptr<common::AbstractActionExecutor>
+action::ActionExecutorFactory::CreateExecutor(common::ActionType type) {
+  return std::unique_ptr<common::AbstractActionExecutor>();
+}
diff --git a/src/action/action_executor_factory.hh b/src/action/action_executor_factory.hh
new file mode 100644 (file)
index 0000000..85b40da
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ACTION_ACTION_EXECUTOR_FACTORY_HH_
+#define ACTION_ACTION_EXECUTOR_FACTORY_HH_
+
+#include <memory>
+#include "common/action_executor.hh"
+
+namespace action {
+
+class ActionExecutorFactory {
+ public:
+  static std::unique_ptr<common::AbstractActionExecutor> CreateExecutor(
+      common::ActionType type);
+};
+
+}  // namespace action
+
+#endif  // ACTION_ACTION_EXECUTOR_FACTORY_HH_
index 09296bd133b5d7f3e97a4698737c7f307d0dba9b..db1b5b9ffe8a763f3da1c98f55538942e76fba1e 100644 (file)
 
 #include <string>
 
+#include "action/action_executor_factory.hh"
 #include "action/action_request_handler.hh"
-#include "action/app_control_executor.hh"
 #include "action/service.hh"
 #include "action/sqlite_db.hh"
 #include "action_request_handler.hh"
-#include "common/action_executor.hh"
 #include "common/utils/logging.hh"
 #include "utils/action_model_converter.hh"
 
 namespace action {
 
-ActionRequestHandler::ActionRequestHandler()
-    : plugin_manager_(
-          this,
-          "d::org.tizen.appfw.service.tizen_action_plugin_manager") {}
+ActionRequestHandler::ActionRequestHandler() {}
 
 ActionRequestHandler::~ActionRequestHandler() {}
 
 void ActionRequestHandler::Init() {
   service_.Listen(std::make_shared<action::Service::Factory>(*this));
-  plugin_manager_.Connect();
 }
 
 void ActionRequestHandler::OnListActions() {
@@ -59,20 +54,14 @@ void ActionRequestHandler::OnExecute(const std::string& requester,
   LOG(DEBUG) << "OnExecute action : " << model.GetActionId()
              << ", appid : " << model.GetAppId();
 
-  if (model.GetType() == common::ActionType::AppControl) {
-    LOG(DEBUG) << "execute appcontrol";
-
-    auto executor = std::make_unique<AppControlExecutor>(requester, model);
-    executor->SetResultHandler(this);
-    executor->Execute(model);
-    executors_.emplace_back(std::move(executor));
-  } else if (model.GetType() == common::ActionType::Plugin) {
-    LOG(DEBUG) << "execute plugin";
-
-    auto action = ActionModelConverter().ConvertToAction(model);
-    auto response = plugin_manager_.Execute(std::move(action));
-    LOG(DEBUG) << "plugin execute done";
-  }
+  LOG(DEBUG) << "execute action type: "
+             << (model.GetType() == common::ActionType::AppControl
+                     ? "AppControl"
+                     : "Plugin");
+  auto executor = ActionExecutorFactory::CreateExecutor(model.GetType());
+  executor->SetResultHandler(this);
+  executor->Execute(model);
+  executors_.emplace_back(std::move(executor));
 }
 
 void ActionRequestHandler::OnResult(const std::string& requester,
@@ -80,16 +69,4 @@ void ActionRequestHandler::OnResult(const std::string& requester,
   LOG(DEBUG) << "OnResult : " << result << ", from : " << requester;
 }
 
-void ActionRequestHandler::OnConnected() {
-  LOG(INFO) << "PluginManager connected";
-}
-
-void ActionRequestHandler::OnDisconnected() {
-  LOG(INFO) << "PluginManager disconnected";
-}
-
-void ActionRequestHandler::OnRejected() {
-  LOG(INFO) << "PluginManager rejected";
-}
-
 }  // namespace action
index 4634b8e67f5173b7a2012001c0823000a02e0215..65003d7ff4f055e1075c32656b3372e5974af32a 100644 (file)
 #include <memory>
 #include <vector>
 
-#include "action/plugin_manager_proxy.h"
 #include "action/request_handler.hh"
-#include "action/result_handler.hh"
 #include "action/tizen_action_service_stub.h"
 #include "common/action_executor.hh"
 #include "common/action_model.h"
+#include "common/result_handler.hh"
 
 namespace action {
 
-class ActionRequestHandler : public IRequestHandler,
-                             public IResultHandler,
-                             public rpc_port::plugin_manager_proxy::proxy::
-                                 PluginManager::IEventListener {
+class ActionRequestHandler : public IRequestHandler, common::IResultHandler {
  public:
   ActionRequestHandler();
   ~ActionRequestHandler();
@@ -49,14 +45,9 @@ class ActionRequestHandler : public IRequestHandler,
   void OnResult(const std::string& requester,
                 const std::string& result) override;
 
-  void OnConnected() override;
-  void OnDisconnected() override;
-  void OnRejected() override;
-
  private:
   rpc_port::tizen_action_service_stub::stub::ActionService service_;
   std::vector<std::unique_ptr<common::AbstractActionExecutor>> executors_;
-  rpc_port::plugin_manager_proxy::proxy::PluginManager plugin_manager_;
 };
 
 }  // namespace action
index 1d17ebaed6151775a0c542367d1cbac2f17246f4..5e277b424988d75d556dfcbd905f2b328e0c9892 100644 (file)
@@ -119,7 +119,7 @@ bool AppControlExecutor::SendAppControl() {
   return true;
 }
 
-void AppControlExecutor::SetResultHandler(IResultHandler* handler) {
+void AppControlExecutor::SetResultHandler(common::IResultHandler* handler) {
   result_handler_ = handler;
 }
 
index 5e54197ef45156d4326910c581693d278086c66f..aa35822f77827d2b17309233c6224f9496aaa171 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <app_control.h>
 
-#include "action/result_handler.hh"
 #include "common/action_executor.hh"
 #include "common/action_model.h"
 
@@ -32,7 +31,7 @@ class AppControlExecutor : public common::AbstractActionExecutor {
   int Execute(const common::ActionModel& model) override;
 
   void OnAppControlReply(const std::string& reply);
-  void SetResultHandler(IResultHandler* handler);
+  void SetResultHandler(common::IResultHandler* handler) override;
 
  private:
   void AddExtraData(const common::ActionModel& model);
@@ -40,7 +39,7 @@ class AppControlExecutor : public common::AbstractActionExecutor {
 
   common::ActionModel model_;
   app_control_h app_control_;
-  IResultHandler* result_handler_;
+  common::IResultHandler* result_handler_ = nullptr;
 };
 
 }  // namespace action
diff --git a/src/action/plugin_executor.cc b/src/action/plugin_executor.cc
new file mode 100644 (file)
index 0000000..57a9e04
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "action/plugin_executor.hh"
+
+#include <memory>
+
+#include "common/action_model.h"
+#include "common/utils/logging.hh"
+#include "utils/action_model_converter.hh"
+#include "plugin_executor.hh"
+
+namespace action {
+
+class ResultHandler : public rpc_port::plugin_manager_proxy::proxy::
+                          PluginManager::ResultHandler {
+ public:
+  ResultHandler(PluginExecutor* executor)
+      : rpc_port::plugin_manager_proxy::proxy::PluginManager::ResultHandler(
+            true),
+        executor_(executor) {
+  }
+
+  ~ResultHandler() = default;
+
+  void OnReceived(std::string result) override {
+    if (executor_)
+      executor_->OnResultReceived(result);
+  }
+
+ private:
+  PluginExecutor* executor_ = nullptr;
+};
+
+PluginExecutor::PluginExecutor(std::string id, const common::ActionModel& model)
+    : AbstractActionExecutor(std::move(id)),
+      plugin_manager_(
+          this,
+          "d::org.tizen.appfw.service.tizen_action_plugin_manager") {
+  model_ = model;
+}
+
+PluginExecutor::~PluginExecutor() {
+  if (connected_)
+    plugin_manager_.Disconnect();
+}
+
+int PluginExecutor::Execute(const common::ActionModel& model) {
+  LOG(ERROR) << "Plugin Execute : " << model.GetUri();
+
+  if (!Connect())
+    return -1;
+
+  auto action = ActionModelConverter().ConvertToAction(model);
+  auto result_cb = std::make_unique<ResultHandler>(this);
+  try {
+    plugin_manager_.Execute(std::move(action), std::move(result_cb));
+  } catch (const rpc_port::plugin_manager_proxy::proxy::Exception& e) {
+    LOG(ERROR) << "Failed to execute action";
+    return -1;
+  }
+
+  return 0;
+}
+
+void PluginExecutor::OnResultReceived(const std::string& result) {
+  // TODO: Handle result
+  LOG(DEBUG) << "result from instance: " << GetId() << ", result: " << result;
+  result_handler_->OnResult(GetId(), result);
+}
+
+void PluginExecutor::SetResultHandler(common::IResultHandler* handler) {
+  result_handler_ = handler;
+}
+
+bool PluginExecutor::Connect() {
+  if (connected_)
+    return true;
+
+  try {
+    plugin_manager_.Connect(true);
+  } catch (...) {
+    LOG(ERROR) << "Failed to connect to plugin manager";
+    return false;
+  }
+
+  connected_ = true;
+  return true;
+}
+
+void PluginExecutor::OnConnected() {
+  connected_ = true;
+  LOG(INFO) << "PluginManager connected";
+}
+
+void PluginExecutor::OnDisconnected() {
+  connected_ = false;
+  LOG(INFO) << "PluginManager disconnected";
+}
+
+void PluginExecutor::OnRejected() {
+  connected_ = false;
+  LOG(INFO) << "PluginManager rejected";
+}
+
+}  // namespace action
diff --git a/src/action/plugin_executor.hh b/src/action/plugin_executor.hh
new file mode 100644 (file)
index 0000000..089505e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ACTION_PLUGIN_EXECUTOR_HH_
+#define ACTION_PLUGIN_EXECUTOR_HH_
+
+#include <app_control.h>
+
+#include "common/action_executor.hh"
+#include "common/action_model.h"
+#include "plugin_manager_proxy.h"
+
+namespace action {
+
+class PluginExecutor : public common::AbstractActionExecutor,
+                       public rpc_port::plugin_manager_proxy::proxy::
+                           PluginManager::IEventListener {
+ public:
+  explicit PluginExecutor(std::string id, const common::ActionModel& model);
+  ~PluginExecutor();
+  int Execute(const common::ActionModel& model) override;
+  void SetResultHandler(common::IResultHandler* handler) override;
+  void OnResultReceived(const std::string& result);
+
+ private:
+  bool Connect();
+
+  void OnConnected() override;
+  void OnDisconnected() override;
+  void OnRejected() override;
+
+ private:
+  common::ActionModel model_;
+  rpc_port::plugin_manager_proxy::proxy::PluginManager plugin_manager_;
+  common::IResultHandler* result_handler_ = nullptr;
+  bool connected_ = false;
+};
+
+}  // namespace action
+
+#endif  // ACTION_PLUGIN_EXECUTOR_HH_
diff --git a/src/action/result_handler.hh b/src/action/result_handler.hh
deleted file mode 100644 (file)
index 9f9763a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ACTION_RESULT_HANDLER_HH_
-#define ACTION_RESULT_HANDLER_HH_
-
-#include <string>
-
-namespace action {
-
-class IResultHandler {
- public:
-  virtual ~IResultHandler() = default;
-  virtual void OnResult(const std::string& executor_id,
-      const std::string& result) = 0;
-};
-
-}  // namespace action
-
-#endif  // ACTION_RESULT_HANDLER_HH_
index e810ff628308978fce54d5a58c5e9a7ca1c477a8..08878d98e1fc871caffdba234c75ee2f4265a05a 100644 (file)
@@ -21,6 +21,7 @@
 #include <utility>
 
 #include "common/action_model.h"
+#include "common/result_handler.hh"
 
 namespace common {
 
@@ -30,6 +31,7 @@ class AbstractActionExecutor {
   virtual ~AbstractActionExecutor() = default;
   virtual int Execute(const ActionModel& model) = 0;
   virtual std::string GetId() { return id_; }
+  virtual void SetResultHandler(IResultHandler* handler) = 0;
 
  private:
   std::string id_;
diff --git a/src/common/result_handler.hh b/src/common/result_handler.hh
new file mode 100644 (file)
index 0000000..4fecce7
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COMMON_RESULT_HANDLER_HH_
+#define COMMON_RESULT_HANDLER_HH_
+
+#include <string>
+
+namespace common {
+
+class IResultHandler {
+ public:
+  virtual ~IResultHandler() = default;
+  virtual void OnResult(const std::string& executor_id,
+      const std::string& result) = 0;
+};
+
+}  // namespace common
+
+#endif  // COMMON_RESULT_HANDLER_HH_
index d05edd2192d3eaffb0712ac0cc37e9df7ecf459d..19549dba25ae62fee91f12f187d96d2c81bd5a25 100644 (file)
@@ -1,42 +1,82 @@
-#include <cstdio>
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #include <rpc-port-internal.h>
+#include <algorithm>
+#include <cstdio>
 #include <utility>
 
 #include "common/utils/logging.hh"
 #include "plugin_manager_stub.h"
 
-class PluginService : public rpc_port::plugin_manager_stub::stub::PluginManager::ServiceBase {
+class PluginService
+    : public rpc_port::plugin_manager_stub::stub::PluginManager::ServiceBase {
  public:
-  class Factory : public rpc_port::plugin_manager_stub::stub::PluginManager::ServiceBase::Factory {
+  class Factory : public rpc_port::plugin_manager_stub::stub::PluginManager::
+                      ServiceBase::Factory {
    public:
-    std::unique_ptr<rpc_port::plugin_manager_stub::stub::PluginManager::ServiceBase> CreateService(
-        std::string sender, std::string instance) override {
-      return std::make_unique<PluginService>(std::move(sender), std::move(instance));
+    std::unique_ptr<
+        rpc_port::plugin_manager_stub::stub::PluginManager::ServiceBase>
+    CreateService(std::string sender, std::string instance) override {
+      return std::make_unique<PluginService>(std::move(sender),
+                                             std::move(instance));
     }
   };
 
-  PluginService(std::string sender, std::string instance) : ServiceBase(sender, instance) {
-
-  }
+  PluginService(std::string sender, std::string instance)
+      : ServiceBase(sender, instance) {}
 
   void OnCreate() override {
     std::string sender = GetSender();
     std::string instance = GetInstance();
-    LOG(INFO) << "PluginService created. sender: " << sender << ", instance: " << instance;
+    LOG(INFO) << "PluginService created. sender: " << sender
+              << ", instance: " << instance;
   }
 
   void OnTerminate() override {
     std::string sender = GetSender();
     std::string instance = GetInstance();
-    LOG(INFO) << "PluginService terminated. sender: " << sender << ", instance: " << instance;
+    LOG(INFO) << "PluginService terminated. sender: " << sender
+              << ", instance: " << instance;
   }
 
-  rpc_port::plugin_manager_stub::Bundle Execute(rpc_port::plugin_manager_stub::Action action) {
+  void Execute(
+      rpc_port::plugin_manager_stub::Action action,
+      std::unique_ptr<
+          rpc_port::plugin_manager_stub::stub::PluginManager::ResultHandler>
+          result_cb) override {
     std::string sender = GetSender();
     std::string instance = GetInstance();
-    LOG(INFO) << "PluginService execute. sender: " << sender << ", instance: " << instance;
+    LOG(INFO) << "PluginService execute. sender: " << sender
+              << ", instance: " << instance;
     PrintAction(action);
-    return rpc_port::plugin_manager_stub::Bundle();
+    auto parameters = action.Getparameters();
+    auto it = std::find_if(parameters.begin(), parameters.end(),
+                           [](const auto& parameter) {
+                             return parameter.Getkey() == "Executable";
+                           });
+
+    if (it == parameters.end()) {
+      LOG(ERROR) << "Executable parameter not found";
+      result_cb->Invoke("Fail");
+    }
+
+    // TODO: implement action execution
+
+    result_cb->Invoke("Success");
   }
 
  private:
@@ -62,8 +102,8 @@ class PluginService : public rpc_port::plugin_manager_stub::stub::PluginManager:
 };
 
 int main() {
-  int ret =
-      rpc_port_register_proc_info("d::org.tizen.appfw.service.tizen_action_plugin_manager", nullptr);
+  int ret = rpc_port_register_proc_info(
+      "d::org.tizen.appfw.service.tizen_action_plugin_manager", nullptr);
   if (ret != 0) {
     perror("Failed to register proc info");
     return -1;
index 58cb3a616aa35e92fe7ede91a7e43f8191e858dc..2ce3e83dcec87b8c885b43a78ff51ae831713fec 100644 (file)
@@ -2,5 +2,6 @@ protocol 2
 import <tizen_action_datatype.tidl>
 
 interface PluginManager {
-    bundle Execute(Action action);
+    void ResultHandler(string result) delegate;
+    void Execute(Action action, ResultHandler result_cb) async;
 }