Change the interface to separate schema and model
authorChanggyu Choi <changyu.choi@samsung.com>
Mon, 21 Apr 2025 04:03:51 +0000 (13:03 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Mon, 28 Apr 2025 02:14:33 +0000 (11:14 +0900)
ActionSchema and ActionModel have different values.
So these two have to be separated.

Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
28 files changed:
src/action/action_request_handler.cc
src/action/action_request_handler.hh
src/action/app_control_executor.cc
src/action/plugin_executor.cc
src/action/plugin_executor.hh
src/action/request_handler.hh
src/action/service.cc
src/action/service.hh
src/action/utils/action_model_converter.cc
src/action/utils/action_model_converter.hh
src/action/utils/action_model_validator.cc [new file with mode: 0644]
src/action/utils/action_model_validator.hh [new file with mode: 0644]
src/common/action_model.cc
src/common/action_model.h
src/common/action_parameter.h
src/common/action_schema.cc [new file with mode: 0644]
src/common/action_schema.h [new file with mode: 0644]
src/common/action_type.h [new file with mode: 0644]
src/plugin-daemon/main.cc
test/unit_tests/action_model_converter_test.cc
test/unit_tests/action_model_test.cc
test/unit_tests/action_schema_test.cc [new file with mode: 0644]
tidl/plugin_manager.tidl
tidl/tizen_action_datatype.tidl
tidl/tizen_actions.tidl
tool/action_tool/tools/execute.cc
tool/action_tool/tools/get_action.cc
tool/action_tool/tools/list_actions.cc

index bde8cfae58392d7fd479c66ecd7204d165974b9b..bdcab2431a61240589ad37abe7676e219b322295 100755 (executable)
@@ -28,6 +28,7 @@
 #include "action_request_handler.hh"
 #include "common/utils/logging.hh"
 #include "utils/action_model_converter.hh"
+#include "utils/action_model_validator.hh"
 
 namespace {
 
@@ -84,20 +85,20 @@ bool CheckPrivileges(pid_t pid, uid_t uid,
   return privs.empty() ? true : false;
 }
 
-common::ParameterType GetParameterTypeFromString(const std::string& type) {
-  LOG(DEBUG) << "GetParmameterType : " << type;
+// common::ParameterType GetParameterTypeFromString(const std::string& type) {
+//   LOG(DEBUG) << "GetParmameterType : " << type;
 
-  if (type.compare("integer") == 0)
-    return common::ParameterType::IntType;
-  else if (type.compare("string") == 0)
-    return common::ParameterType::StringType;
-  else if (type.compare("double") == 0)
-    return common::ParameterType::DoubleType;
-  else if (type.compare("bool") == 0)
-    return common::ParameterType::BoolType;
+//   if (type.compare("integer") == 0)
+//     return common::ParameterType::IntType;
+//   else if (type.compare("string") == 0)
+//     return common::ParameterType::StringType;
+//   else if (type.compare("double") == 0)
+//     return common::ParameterType::DoubleType;
+//   else if (type.compare("bool") == 0)
+//     return common::ParameterType::BoolType;
 
-  return common::ParameterType::InvalidType;
-}
+//   return common::ParameterType::InvalidType;
+// }
 
 std::string GetStringFromParameterType(common::ParameterType type) {
   LOG(DEBUG) << "GetParmameterTypeString : " << static_cast<int>(type);
@@ -126,18 +127,18 @@ void ActionRequestHandler::Init() {
   service_.Listen(std::make_shared<action::Service::Factory>(*this));
 }
 
-std::vector<rpc::Action> ActionRequestHandler::OnListActions() {
+std::vector<rpc::ActionSchema> ActionRequestHandler::OnListActions() {
   // TODO: db as member variable?
   auto db = std::make_unique<action::SqliteDb>();
   std::vector<std::string> list = db->ListActions();
-  std::vector<rpc::Action> actions;
+  std::vector<rpc::ActionSchema> actions;
   for (const auto& item : list) {
-    common::ActionModel model(item);
-    rpc::Action action;
-    action.Setaction_id(model.GetActionId());
-    action.Setapp_id(model.GetAppId());
-    action.Setcategory(model.GetCategory());
-    action.Setdescription(model.GetDescription());
+    common::ActionSchema schema(item);
+    rpc::ActionSchema action;
+    action.Setaction_id(schema.GetActionId());
+    action.Setpackage_id(schema.GetPackageId());
+    action.Setcategory(schema.GetCategory());
+    action.Setdescription(schema.GetDescription());
     action.Settype("app_control");  // TODO
     // action.Setparameters();
     // action.Setprivileges();
@@ -146,20 +147,20 @@ std::vector<rpc::Action> ActionRequestHandler::OnListActions() {
   return actions;
 }
 
-rpc::Action ActionRequestHandler::OnGetAction(const std::string& id) {
+rpc::ActionSchema ActionRequestHandler::OnGetAction(const std::string& id) {
   auto db = std::make_unique<action::SqliteDb>();
   std::string json_str = db->GetAction(id);
-  common::ActionModel model(json_str);
+  common::ActionSchema schema(json_str);
 
-  rpc::Action action;
-  action.Setaction_id(model.GetActionId());
-  action.Setapp_id(model.GetAppId());
-  action.Setcategory(model.GetCategory());
-  action.Setdescription(model.GetDescription());
+  rpc::ActionSchema action;
+  action.Setaction_id(schema.GetActionId());
+  action.Setpackage_id(schema.GetPackageId());
+  action.Setcategory(schema.GetCategory());
+  action.Setdescription(schema.GetDescription());
   action.Settype("app_control");  // TODO
 
   std::vector<rpc::Parameter> actionparams;
-  auto params = model.GetParameters();
+  auto params = schema.GetParameters();
 
   for (auto const& iter : params) {
     auto param = rpc::Parameter(iter.GetName(), GetStringFromParameterType(iter.GetType()),
@@ -168,7 +169,7 @@ rpc::Action ActionRequestHandler::OnGetAction(const std::string& id) {
     actionparams.push_back(param);
   }
   action.Setparameters(actionparams);
-  action.Setprivileges(model.GetPrivileges());
+  action.Setprivileges(schema.GetPrivileges());
 
   return action;
 }
@@ -178,26 +179,19 @@ void ActionRequestHandler::OnGetActionId(const std::string& user_description,
                                          float search_threshold) {}
 
 void ActionRequestHandler::OnExecute(const std::string& instance, pid_t pid,
-                                     uid_t uid, rpc::Action& action) {
+                                     uid_t uid, rpc::ActionModel& action) {
   auto db = std::make_unique<action::SqliteDb>();
-  std::string json_str = db->GetAction(action.Getaction_id());
-  common::ActionModel model(json_str);
-  LOG(DEBUG) << "OnExecute action : " << model.GetActionId() << " appid: " << model.GetAppId();
-
-  std::vector<common::ActionParameter> params;
-  for (auto const& iter : action.Getparameters()) {
-    common::ParameterType param_type = GetParameterTypeFromString(iter.Gettype());
-    LOG(DEBUG) << "param key : " << iter.Getkey() << ", val : "
-        << iter.Getvalue() << ", type : " << iter.Gettype();
+  std::string schema_json = db->GetAction(action.Getaction_id());
+  common::ActionSchema schema(schema_json);
+  LOG(DEBUG) << "OnExecute action : " << schema.GetActionId() << " appid: " << schema.GetPackageId();
 
-    auto param = common::ActionParameter(iter.Getkey(), param_type,
-        iter.Getvalue(), iter.Getdescription(), iter.Getis_requied());
-
-    params.push_back(param);
+  common::ActionModel model(action.Getjson());
+  if (!ActionModelValidator().CheckValid(schema, model)) {
+    LOG(ERROR) << "Invalid model : " << action.Getjson();
+    return;
   }
-  model.SetParameters(params);
 
-  auto required_privileges = db->GetRequiredPrivileges(model.GetActionId());
+  auto required_privileges = db->GetRequiredPrivileges(model.GetId());
   if (!CheckPrivileges(pid, uid, required_privileges)) {
     LOG(ERROR) << "Not allowed to execute action due to missing privileges";
     return;
index 3b19fcf4031b03e4f3829db9c0b8b5faf6e78975..8a2899989f7d528cc8481ee0028b9636e6198140 100644 (file)
@@ -25,7 +25,7 @@
 #include "action/request_handler.hh"
 #include "action/tizen_action_service_stub.h"
 #include "common/action_executor.hh"
-#include "common/action_model.h"
+#include "common/action_schema.h"
 #include "common/action_result_handler.hh"
 
 namespace action {
@@ -36,13 +36,13 @@ class ActionRequestHandler : public IRequestHandler, common::IActionResultHandle
   ~ActionRequestHandler();
   void Init();
 
-  std::vector<rpc::Action> OnListActions() override;
-  rpc::Action OnGetAction(const std::string& id) override;
+  std::vector<rpc::ActionSchema> OnListActions() override;
+  rpc::ActionSchema OnGetAction(const std::string& id) override;
   void OnGetActionId(const std::string& user_description,
                      int top_k,
                      float search_threshold) override;
   void OnExecute(const std::string& instance, pid_t pid, uid_t uid,
-                 rpc::Action& model) override;
+                 rpc::ActionModel& model) override;
   void RegisterRequestReplyHandler(const std::string& requester,
                                    IRequestReplyHandler* handler) override;
   void UnregisterRequestReplyHandler(const std::string& requester) override;
index f54723608943ad58f1c1d4b9358bbf356f3ac9cd..5929b2067bc91c124301fc88859a541403a9c067 100644 (file)
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 #include "action/app_control_executor.hh"
 
 #include <app_control.h>
@@ -36,24 +35,28 @@ app_control_h ConvertToAppControl(const common::ActionModel& action_model) {
   }
 
   // TODO: Convert to app_control handle from action model
-  app_control_set_app_id(handle, action_model.GetAppId().c_str());
+  app_control_set_app_id(handle, action_model.GetPackageId().c_str());
 
   auto params = action_model.GetParameters();
 
-  for (auto const& iter : params)
-    LOG(DEBUG) << "param name : " << iter.GetName() << ", val : "
-        << iter.GetValue() << ", type : " << static_cast<int>(iter.GetType());
+  for (auto const& [key, value] : params) {
+    LOG(DEBUG) << "param name : " << key << ", val : " << value;
+    app_control_add_extra_data(handle, key.c_str(), value.c_str());
+  }
 
   return handle;
 }
 
-void ResultCb(app_control_h request, app_control_error_e result,
-    void* user_data) {
+void ResultCb(app_control_h request,
+              app_control_error_e result,
+              void* user_data) {
   LOG(DEBUG) << "ResultCb: " << result;
 }
 
-void ReplyCb(app_control_h request, app_control_h reply,
-    app_control_result_e result, void* user_data) {
+void ReplyCb(app_control_h request,
+             app_control_h reply,
+             app_control_result_e result,
+             void* user_data) {
   // TODO: return reply to caller
   auto on_reply = static_cast<action::AppControlExecutor*>(user_data);
 
@@ -68,7 +71,7 @@ namespace action {
 
 AppControlExecutor::AppControlExecutor(std::string id,
     const common::ActionModel& model)
-    : AbstractActionExecutor(std::move(id)) {
+    : common::AbstractActionExecutor(std::move(id)) {
   model_ = model;
   app_control_ = ConvertToAppControl(model);
 }
@@ -80,7 +83,7 @@ AppControlExecutor::~AppControlExecutor() {
 }
 
 int AppControlExecutor::Execute(const common::ActionModel& model) {
-  LOG(ERROR) << "AppControl Execute : " << model.GetAppId();
+  LOG(ERROR) << "AppControl Execute : " << model.GetId();
 
   AddExtraData(model);
 
@@ -99,19 +102,17 @@ void AppControlExecutor::OnAppControlReply(const std::string& reply) {
 }
 
 void AppControlExecutor::AddExtraData(const common::ActionModel& model) {
-  for (auto const& iter : model.GetParameters()) {
-    auto key = iter.GetName();
-    auto val = iter.GetValue();
-    int ret = app_control_add_extra_data(app_control_, key.c_str(),
-        val.c_str());
+  for (auto const& [key, val] : model.GetParameters()) {
+    int ret =
+        app_control_add_extra_data(app_control_, key.c_str(), val.c_str());
     if (ret != APP_CONTROL_ERROR_NONE)
       LOG(ERROR) << "Failed to add extra data: " << ret;
   }
 }
 
 bool AppControlExecutor::SendAppControl() {
-  int ret = app_control_send_launch_request_async(app_control_, ResultCb,
-      ReplyCb, static_cast<void*>(this));
+  int ret = app_control_send_launch_request_async(
+      app_control_, ResultCb, ReplyCb, static_cast<void*>(this));
   if (ret != APP_CONTROL_ERROR_NONE) {
     LOG(ERROR) << "Failed to send launch request: " << ret;
     return false;
index cc98c2a5b1d4331497c305548903be0a8c3e2695..6a02c0e6de461ee62aff9d4281d24830014147f9 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <memory>
 
-#include "common/action_model.h"
+#include "common/action_schema.h"
 #include "common/utils/logging.hh"
 #include "plugin_executor.hh"
 #include "utils/action_model_converter.hh"
@@ -56,12 +56,12 @@ PluginExecutor::~PluginExecutor() {
 }
 
 int PluginExecutor::Execute(const common::ActionModel& model) {
-  if (model.GetType() != common::ActionType::Plugin) {
-    LOG(ERROR) << "Invalid action type";
-    return -1;
-  }
+  // if (model.GetType() != common::ActionType::Plugin) {
+  //   LOG(ERROR) << "Invalid action type";
+  //   return -1;
+  // }
 
-  LOG(ERROR) << "Plugin Execute : " << model.GetActionId();
+  LOG(ERROR) << "Plugin Execute : " << model.GetId();
 
   if (!Connect())
     return -1;
index 312d0a5e8d3e33d172840ab0f9416d56edefc06b..84cdb246ddf7fa2f0b656394721206ba5f6da30b 100644 (file)
@@ -20,7 +20,6 @@
 #include <app_control.h>
 
 #include "common/action_executor.hh"
-#include "common/action_model.h"
 #include "plugin_manager_proxy.h"
 
 namespace action {
index ae4a3b6cef389b20c7d5d1fd6e1a9bca50845151..fdf632d7414f70f389bacc4e45e29636947a8c0b 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <string>
 
-#include "common/action_model.h"
+#include "common/action_schema.h"
 
 #include "action/request_reply_handler.hh"
 #include "action/tizen_action_service_stub.h"
@@ -33,11 +33,11 @@ namespace action {
 class IRequestHandler {
  public:
   virtual ~IRequestHandler() = default;
-  virtual std::vector<rpc::Action> OnListActions() = 0;
-  virtual rpc::Action OnGetAction(const std::string& id) = 0;
+  virtual std::vector<rpc::ActionSchema> OnListActions() = 0;
+  virtual rpc::ActionSchema OnGetAction(const std::string& id) = 0;
   virtual void OnGetActionId(const std::string& user_description, int top_k,
       float search_threshold) = 0;
-  virtual void OnExecute(const std::string& requester, pid_t pid, uid_t uid, rpc::Action& model) = 0;
+  virtual void OnExecute(const std::string& requester, pid_t pid, uid_t uid, rpc::ActionModel& model) = 0;
   virtual void RegisterRequestReplyHandler(const std::string& requester,
       IRequestReplyHandler* handler) = 0;
   virtual void UnregisterRequestReplyHandler(const std::string& requester) = 0;
index fed303552243fb5f3f17a2c83a525dd31d45dc9f..c23a5f01e12b407e434849f8f2232b61b52b2356 100644 (file)
@@ -21,7 +21,7 @@
 #include "action/request_handler.hh"
 #include "action/sqlite_db.hh"
 #include "common/utils/logging.hh"
-#include "common/action_model.h"
+#include "common/action_schema.h"
 
 namespace action {
 
@@ -44,11 +44,11 @@ void Service::OnTerminate() {
   handler_.UnregisterRequestReplyHandler(GetInstance());
 }
 
-std::vector<rpc::Action> Service::ListActions() {
+std::vector<rpc::ActionSchema> Service::ListActions() {
   return handler_.OnListActions();
 }
 
-rpc::Action Service::GetAction(std::string action_id) {
+rpc::ActionSchema Service::GetAction(std::string action_id) {
   return handler_.OnGetAction(action_id);
 }
 
@@ -59,9 +59,8 @@ std::vector<rpc::VectorDbResult> Service::GetActionId(
   return {};
 }
 
-int Service::Execute(rpc::Action action) {
-  LOG(DEBUG) << "Execute : " << action.Getaction_id()
-      << ", type : " << action.Gettype();
+int Service::Execute(rpc::ActionModel action) {
+  LOG(DEBUG) << "Execute : " << action.Getaction_id();
   handler_.OnExecute(GetInstance(), GetPid(), GetUid(), action);
   return 0;
 }
index deafb02128ea728f3676261ef06835aae8267074..4ce8234db34e71615f6c1c92c7e9563429c3fda1 100644 (file)
@@ -53,11 +53,11 @@ class Service : public rpc::stub::ActionService::ServiceBase,
 
   void OnCreate() override;
   void OnTerminate() override;
-  std::vector<rpc::Action> ListActions() override;
-  rpc::Action GetAction(std::string action_id) override;
+  std::vector<rpc::ActionSchema> ListActions() override;
+  rpc::ActionSchema GetAction(std::string action_id) override;
   std::vector<rpc::VectorDbResult> GetActionId(std::string user_description,
       int top_k, float search_threshold) override;
-  int Execute(rpc::Action action) override;
+  int Execute(rpc::ActionModel action) override;
   int RegisterActionReplyCb(std::unique_ptr<ActionReplyCb> cb) override;
   bool UnregisterActionReplyCb(int id) override;
   void SendRequestReply(const std::string& reply) override;
index c7791fc3cc1ad2f76b7eb54dd507c45d06acc7ed..8b0d1ae358cd381b1fb8a3e53e853408f8fcc89c 100644 (file)
@@ -5,28 +5,14 @@
 
 namespace plugin_proxy =  rpc_port::plugin_manager_proxy;
 
-plugin_proxy::Action ActionModelConverter::ConvertToAction(
+plugin_proxy::ActionModel ActionModelConverter::ConvertToAction(
     const common::ActionModel& model) {
-  plugin_proxy::Action action;
-  action.Setaction_id(model.GetActionId());
-  action.Setapp_id(model.GetAppId());
-  action.Setcategory(model.GetCategory());
-  action.Setdescription(model.GetDescription());
-  auto parameters = std::vector<plugin_proxy::Parameter>();
-  for (auto const& param : model.GetParameters()) {
-    plugin_proxy::Parameter parameter;
-    parameter.Setkey(param.GetName());
-    parameter.Settype(ActionParameterTypeToString(param.GetType()));
-    parameter.Setvalue(param.GetValue());
-    parameter.Setdescription(param.GetDescription());
-    parameter.Setis_requied(param.GetIsRequired());
-    parameters.push_back(std::move(parameter));
-  }
+  plugin_proxy::ActionModel action;
+  action.Setaction_id(model.GetId());
+  action.Setpackage_id(model.GetPackageId());
+  action.Setjson(model.GetJson());
 
-  action.Setparameters(std::move(parameters));
-  action.Setprivileges(model.GetPrivileges());
   // action.Setresults();
-  action.Settype(ActionTypeToString(model.GetType()));
   return action;
 }
 
index 1fd1de13a0f603e154ec0762b611e70487ea3841..789549cfd45318719d3073bd78822dccfa0c1cd9 100644 (file)
@@ -1,10 +1,33 @@
-#include "common/action_model.h"
+/*
+ * 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_MODEL_CONVERTER_HH_
+#define ACTION_ACTION_MODEL_CONVERTER_HH_
+
 #include "../plugin_manager_proxy.h"
+#include "common/action_model.h"
+#include "common/action_schema.h"
 
 class ActionModelConverter {
  public:
   ActionModelConverter() = default;
-  rpc_port::plugin_manager_proxy::Action ConvertToAction(const common::ActionModel& model);
+  rpc_port::plugin_manager_proxy::ActionModel ConvertToAction(
+      const common::ActionModel& model);
   std::string ActionTypeToString(common::ActionType type);
   std::string ActionParameterTypeToString(common::ParameterType type);
 };
+
+#endif  // ACTION_ACTION_MODEL_CONVERTER_HH_
diff --git a/src/action/utils/action_model_validator.cc b/src/action/utils/action_model_validator.cc
new file mode 100644 (file)
index 0000000..5a02381
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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_model_validator.hh"
+
+namespace action {
+
+bool ActionModelValidator::CheckValid(
+    const common::ActionSchema& schema,
+    const common::ActionModel& model) const {
+  // TODO: Implement this.
+  return false;
+}
+
+}  // namespace action
diff --git a/src/action/utils/action_model_validator.hh b/src/action/utils/action_model_validator.hh
new file mode 100644 (file)
index 0000000..e72332b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_MODEL_VALIDATOR_HH_
+#define ACTION_ACTION_MODEL_VALIDATOR_HH_
+
+#include "common/action_model.h"
+#include "common/action_schema.h"
+
+namespace action {
+
+class ActionModelValidator {
+ public:
+  ActionModelValidator() = default;
+
+  bool CheckValid(const common::ActionSchema& schema,
+                  const common::ActionModel& model) const;
+};
+
+}  // namespace action
+
+#endif  // ACTION_ACTION_MODEL_VALIDATOR_HH_
index 01aace51029ddd7ba4ef37277c2b321e7642f3ff..2582052845855fab4b813d5fa40943a4e52de788 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
  * limitations under the License.
  */
 
-#include "common/action_model.h"
+#include "action_model.h"
 
-#include <json/json.h>
+#include <jsoncpp/json/json.h>
 
-#include <string>
-#include <map>
+#include <utility>
 
 #include "common/utils/logging.hh"
 
+namespace common {
 namespace {
 
 Json::Value ParseJsonFromString(const std::string& json_str) {
@@ -31,112 +31,33 @@ Json::Value ParseJsonFromString(const std::string& json_str) {
   JSONCPP_STRING err;
   const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
   if (!reader->parse(json_str.c_str(), json_str.c_str() + json_str.length(),
-      &root, &err)) {
+                     &root, &err)) {
     LOG(ERROR) << "Failed to parse json string: " << err;
     return {};
   }
   return root;
 }
 
-std::map<std::string, common::ParameterType> kTypeMap = {
-  {"integer", common::ParameterType::IntType},
-  {"string", common::ParameterType::StringType},
-  {"double", common::ParameterType::DoubleType},
-  {"bool", common::ParameterType::BoolType},
-};
-
-common::ParameterType ConvertStringToParameterType(const std::string& type) {
-  auto it = kTypeMap.find(type);
-  if (it == kTypeMap.end()) {
-    LOG(ERROR) << "Unknown parameter type: " << type;
-    return common::ParameterType::InvalidType;
-  }
-  return it->second;
-}
-
-common::ActionType GetActionTypeFromString(const std::string& type) {
-  if (type.compare("app_control") == 0)
-    return common::ActionType::AppControl;
-  else if (type.compare("plugin") == 0)
-    return common::ActionType::Plugin;
-  return common::ActionType::InvalidType;
-}
-
 }  // namespace
 
-namespace common {
-
-ActionModel::ActionModel() {}
-
-ActionModel::ActionModel(const std::string& json_str) {
-  try {
-    Json::Value root = ParseJsonFromString(json_str);
-
-    action_id_ = root["name"].asString();
-    app_id_ = root["appId"].asString();
-    category_ = root["category"].asString();
-    description_ = root["desc"].asString();
-    type_ = GetActionTypeFromString(root["type"].asString());
-
-    // params
-    for (auto const& it : root["params"].getMemberNames()) {
-      std::string name = it;
-      common::ParameterType type =
-          ConvertStringToParameterType(root["params"][it]["type"].asString());
-      std::string description = root["params"][it]["desc"].asString();
-      bool is_required = root["params"][it]["isRequired"].asBool();
-      parameters_.emplace_back(name, type, "", description, is_required);
-    }
-
-    // returns
-    for (auto const& it : root["returns"].getMemberNames()) {
-      std::string name = it;
-      common::ParameterType type =
-          ConvertStringToParameterType(root["returns"][it]["type"].asString());
-      std::string description = root["returns"][it]["desc"].asString();
-      // ActionParameterType -> another class???
-      returns_.emplace_back(name, type, "", description, false);
-    }
-
-    for (auto const& it : root["required-privileges"])
-      privileges_.push_back(it.asString());
-  } catch (const Json::Exception& e) {
-    // TODO: how to handle invalid json case?
-    LOG(ERROR) << "Failed to parse json string: " << e.what();
+ActionModel::ActionModel(std::string json_str)
+    : json_str_(std::move(json_str)) {
+  Json::Value root = ParseJsonFromString(json_str_);
+  action_id_ = root["name"].asString();
+  package_id_ = root["packageId"].asString();
+  for (auto const& it : root["params"].getMemberNames()) {
+    std::string key = it;
+    std::string value = root["params"][key].asString();
+    parameters_.emplace_back(std::move(key), std::move(value));
   }
 }
 
-ActionModel::ActionModel(std::string action_id, std::string app_id,
-    std::string category, std::string description,
-    std::vector<ActionParameter> parameters,
-    std::vector<std::string> privileges)
-    : action_id_(std::move(action_id)), app_id_(std::move(app_id)),
-      category_(std::move(category)), description_(std::move(description)),
-      parameters_(std::move(parameters)), privileges_(std::move(privileges)) {
-}
-
-const std::string& ActionModel::GetActionId() const {
+const std::string& ActionModel::GetId() const {
   return action_id_;
 }
 
-void ActionModel::SetActionId(std::string action_id) {
-  action_id_ = std::move(action_id);
-}
-
-const std::string& ActionModel::GetAppId() const {
-  return app_id_;
-}
-
-void ActionModel::SetAppId(std::string app_id) {
-  app_id_ = std::move(app_id);
-}
-
-const std::string& ActionModel::GetCategory() const {
-  return category_;
-}
-
-void ActionModel::SetCategory(std::string category) {
-  category_ = std::move(category);
+const std::string& ActionModel::GetPackageId() const {
+  return package_id_;
 }
 
 const ActionType ActionModel::GetType() const {
@@ -147,36 +68,13 @@ void ActionModel::SetType(ActionType type) {
   type_ = type;
 }
 
-const std::string& ActionModel::GetDescription() const {
-  return description_;
-}
-
-void ActionModel::SetDescription(std::string description) {
-  description_ = std::move(description);
-}
-
-const std::vector<ActionParameter>& ActionModel::GetParameters() const {
+const std::vector<std::pair<std::string, std::string>>&
+ActionModel::GetParameters() const {
   return parameters_;
 }
 
-void ActionModel::SetParameters(std::vector<ActionParameter> parameters) {
-  parameters_ = std::move(parameters);
-}
-
-const std::vector<ActionParameter>& ActionModel::GetReturns() const {
-  return returns_;
-}
-
-void ActionModel::SetReturns(std::vector<ActionParameter> returns) {
-  returns_ = std::move(returns);
-}
-
-const std::vector<std::string>& ActionModel::GetPrivileges() const {
-  return privileges_;
-}
-
-void ActionModel::SetPrivileges(std::vector<std::string> privileges) {
-  privileges_ = std::move(privileges);
+const std::string& ActionModel::GetJson() const {
+  return json_str_;
 }
 
 }  // namespace common
index 6d388fbb2187b1693e2f1c7e4a2224125dac897d..28c061cc36455c60bb9b22c0cf6203814fc1d2c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
 #ifndef COMMON_ACTION_MODEL_H_
 #define COMMON_ACTION_MODEL_H_
 
+#include <algorithm>
+#include <string>
 #include <vector>
-#include "common/action_parameter.h"
 
-namespace common {
+#include "common/action_type.h"
 
-enum class ActionType {
-  AppControl = 0,
-  Plugin = 1,
-  InvalidType = 100
-};
+namespace common {
 
 class ActionModel {
  public:
-  ActionModel();
-  explicit ActionModel(const std::string& json_str);
-  explicit ActionModel(std::string action_id, std::string app_id,
-      std::string category, std::string description,
-      std::vector<ActionParameter> parameters,
-      std::vector<std::string> privileges);
-
-  const std::string& GetActionId() const;
-  void SetActionId(std::string action_id);
-
-  const std::string& GetAppId() const;
-  void SetAppId(std::string app_id);
-
-  const std::string& GetCategory() const;
-  void SetCategory(std::string category);
-
+  ActionModel() = default;
+  explicit ActionModel(std::string json_str);
+  const std::string& GetId() const;
+  const std::string& GetPackageId() const;
   const ActionType GetType() const;
   void SetType(ActionType type);
-
-  const std::string& GetDescription() const;
-  void SetDescription(std::string description);
-
-  const std::vector<ActionParameter>& GetParameters() const;
-  void SetParameters(std::vector<ActionParameter> parameters);
-
-  const std::vector<ActionParameter>& GetReturns() const;
-  void SetReturns(std::vector<ActionParameter> returns);
-
-  const std::vector<std::string>& GetPrivileges() const;
-  void SetPrivileges(std::vector<std::string> privileges);
+  const std::vector<std::pair<std::string, std::string>>& GetParameters() const;
+  const std::string& GetJson() const;
 
  private:
   std::string action_id_;
-  std::string app_id_;
-  std::string category_;
+  std::string package_id_;
+  std::string json_str_;
   ActionType type_ = ActionType::InvalidType;
-  std::string description_;
-
-  //is std::map better?
-  std::vector<ActionParameter> parameters_;
-  std::vector<ActionParameter> returns_;
-
-  // std::vector<Result> results_;
-  std::vector<std::string> privileges_;
+  std::vector<std::pair<std::string, std::string>> parameters_;
 };
 
-}   // namespace common
+}  // namespace common
 
 #endif  // COMMON_ACTION_MODEL_H_
index 920c355739fb5d152aa7d5bec599e1c9744e9cdb..85b0f216e6d77c9b72bffbb385e79fb6d8641376 100644 (file)
@@ -26,6 +26,7 @@ enum class ParameterType {
   StringType = 1,
   DoubleType = 2,
   BoolType = 3,
+  JsonType = 4,
   InvalidType = 100
 };
 
diff --git a/src/common/action_schema.cc b/src/common/action_schema.cc
new file mode 100644 (file)
index 0000000..100f985
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2024 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 "common/action_schema.h"
+
+#include <json/json.h>
+
+#include <string>
+#include <map>
+
+#include "common/utils/logging.hh"
+
+namespace {
+
+Json::Value ParseJsonFromString(const std::string& json_str) {
+  Json::Value root;
+  Json::CharReaderBuilder builder;
+  JSONCPP_STRING err;
+  const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
+  if (!reader->parse(json_str.c_str(), json_str.c_str() + json_str.length(),
+      &root, &err)) {
+    LOG(ERROR) << "Failed to parse json string: " << err;
+    return {};
+  }
+  return root;
+}
+
+std::map<std::string, common::ParameterType> kTypeMap = {
+  {"integer", common::ParameterType::IntType},
+  {"string", common::ParameterType::StringType},
+  {"double", common::ParameterType::DoubleType},
+  {"bool", common::ParameterType::BoolType},
+  {"json", common::ParameterType::JsonType},
+};
+
+common::ParameterType ConvertStringToParameterType(const std::string& type) {
+  auto it = kTypeMap.find(type);
+  if (it == kTypeMap.end()) {
+    LOG(ERROR) << "Unknown parameter type: " << type;
+    return common::ParameterType::InvalidType;
+  }
+  return it->second;
+}
+
+common::ActionType GetActionTypeFromString(const std::string& type) {
+  if (type.compare("app_control") == 0)
+    return common::ActionType::AppControl;
+  else if (type.compare("plugin") == 0)
+    return common::ActionType::Plugin;
+  return common::ActionType::InvalidType;
+}
+
+}  // namespace
+
+namespace common {
+
+ActionSchema::ActionSchema() {}
+
+ActionSchema::ActionSchema(const std::string& json_str) {
+  try {
+    Json::Value root = ParseJsonFromString(json_str);
+
+    action_id_ = root["name"].asString();
+    package_id_ = root["appId"].asString();  // TODO: Change to packageId.
+    category_ = root["category"].asString();
+    description_ = root["desc"].asString();
+    type_ = GetActionTypeFromString(root["type"].asString());
+
+    // params
+    for (auto const& it : root["params"].getMemberNames()) {
+      std::string name = it;
+      common::ParameterType type =
+          ConvertStringToParameterType(root["params"][it]["type"].asString());
+      std::string description = root["params"][it]["desc"].asString();
+      bool is_required = root["params"][it]["isRequired"].asBool();
+      parameters_.emplace_back(name, type, "", description, is_required);
+    }
+
+    // returns
+    for (auto const& it : root["returns"].getMemberNames()) {
+      std::string name = it;
+      common::ParameterType type =
+          ConvertStringToParameterType(root["returns"][it]["type"].asString());
+      std::string description = root["returns"][it]["desc"].asString();
+      // ActionParameterType -> another class???
+      returns_.emplace_back(name, type, "", description, false);
+    }
+
+    for (auto const& it : root["required-privileges"])
+      privileges_.push_back(it.asString());
+  } catch (const Json::Exception& e) {
+    // TODO: how to handle invalid json case?
+    LOG(ERROR) << "Failed to parse json string: " << e.what();
+  }
+}
+
+ActionSchema::ActionSchema(std::string action_id, std::string package_id,
+    std::string category, std::string description,
+    std::vector<ActionParameter> parameters,
+    std::vector<std::string> privileges)
+    : action_id_(std::move(action_id)), package_id_(std::move(package_id)),
+      category_(std::move(category)), description_(std::move(description)),
+      parameters_(std::move(parameters)), privileges_(std::move(privileges)) {
+}
+
+const std::string& ActionSchema::GetActionId() const {
+  return action_id_;
+}
+
+void ActionSchema::SetActionId(std::string action_id) {
+  action_id_ = std::move(action_id);
+}
+
+const std::string& ActionSchema::GetPackageId() const {
+  return package_id_;
+}
+
+void ActionSchema::SetPackageId(std::string package_id) {
+  package_id_ = std::move(package_id);
+}
+
+const std::string& ActionSchema::GetCategory() const {
+  return category_;
+}
+
+void ActionSchema::SetCategory(std::string category) {
+  category_ = std::move(category);
+}
+
+const ActionType ActionSchema::GetType() const {
+  return type_;
+}
+
+void ActionSchema::SetType(ActionType type) {
+  type_ = type;
+}
+
+const std::string& ActionSchema::GetDescription() const {
+  return description_;
+}
+
+void ActionSchema::SetDescription(std::string description) {
+  description_ = std::move(description);
+}
+
+const std::vector<ActionParameter>& ActionSchema::GetParameters() const {
+  return parameters_;
+}
+
+void ActionSchema::SetParameters(std::vector<ActionParameter> parameters) {
+  parameters_ = std::move(parameters);
+}
+
+const std::vector<ActionParameter>& ActionSchema::GetReturns() const {
+  return returns_;
+}
+
+void ActionSchema::SetReturns(std::vector<ActionParameter> returns) {
+  returns_ = std::move(returns);
+}
+
+const std::vector<std::string>& ActionSchema::GetPrivileges() const {
+  return privileges_;
+}
+
+void ActionSchema::SetPrivileges(std::vector<std::string> privileges) {
+  privileges_ = std::move(privileges);
+}
+
+}  // namespace common
diff --git a/src/common/action_schema.h b/src/common/action_schema.h
new file mode 100644 (file)
index 0000000..dee77bf
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2024 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_ACTION_SCHEMA_H_
+#define COMMON_ACTION_SCHEMA_H_
+
+#include <string>
+#include <vector>
+
+#include "common/action_parameter.h"
+#include "common/action_type.h"
+
+namespace common {
+
+class ActionSchema {
+ public:
+  ActionSchema();
+  explicit ActionSchema(const std::string& json_str);
+  explicit ActionSchema(std::string action_id, std::string package_id,
+      std::string category, std::string description,
+      std::vector<ActionParameter> parameters,
+      std::vector<std::string> privileges);
+
+  const std::string& GetActionId() const;
+  void SetActionId(std::string action_id);
+
+  const std::string& GetPackageId() const;
+  void SetPackageId(std::string package_id);
+
+  const std::string& GetCategory() const;
+  void SetCategory(std::string category);
+
+  const ActionType GetType() const;
+  void SetType(ActionType type);
+
+  const std::string& GetDescription() const;
+  void SetDescription(std::string description);
+
+  const std::vector<ActionParameter>& GetParameters() const;
+  void SetParameters(std::vector<ActionParameter> parameters);
+
+  const std::vector<ActionParameter>& GetReturns() const;
+  void SetReturns(std::vector<ActionParameter> returns);
+
+  const std::vector<std::string>& GetPrivileges() const;
+  void SetPrivileges(std::vector<std::string> privileges);
+
+ private:
+  std::string action_id_;
+  std::string package_id_;
+  std::string category_;
+  ActionType type_ = ActionType::InvalidType;
+  std::string description_;
+
+  //is std::map better?
+  std::vector<ActionParameter> parameters_;
+  std::vector<ActionParameter> returns_;
+
+  // std::vector<Result> results_;
+  std::vector<std::string> privileges_;
+};
+
+}   // namespace common
+
+#endif  // COMMON_ACTION_SCHEMA_H_
diff --git a/src/common/action_type.h b/src/common/action_type.h
new file mode 100644 (file)
index 0000000..1898b64
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 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_ACTION_TYPE_H_
+#define COMMON_ACTION_TYPE_H_
+
+namespace common {
+
+enum class ActionType {
+  AppControl = 0,
+  Plugin = 1,
+  InvalidType = 100
+};
+
+}  // namespace common
+
+#endif  // COMMON_ACTION_TYPE_H_
index 7904548fd81ab4f098f35d16f763754d82123550..c93db819ed748e3323c92c37fe68201655a9c856 100644 (file)
@@ -54,7 +54,7 @@ class PluginService
   }
 
   void Execute(
-      rpc_port::plugin_manager_stub::Action action,
+      rpc_port::plugin_manager_stub::ActionModel action,
       std::unique_ptr<
           rpc_port::plugin_manager_stub::stub::PluginManager::ResultHandler>
           result_cb) override {
@@ -63,13 +63,9 @@ class PluginService
     LOG(INFO) << "PluginService execute. sender: " << sender
               << ", instance: " << instance;
     PrintAction(action);
-    auto parameters = action.Getparameters();
-    auto it = std::find_if(parameters.begin(), parameters.end(),
-                           [](const auto& parameter) {
-                             return parameter.Getkey() == "Executable";
-                           });
+    // TODO: find executable path;
 
-    if (it == parameters.end()) {
+    if (true) {
       LOG(ERROR) << "Executable parameter not found";
       result_cb->Invoke("Fail");
       return;
@@ -81,20 +77,10 @@ class PluginService
   }
 
  private:
-  void PrintAction(const rpc_port::plugin_manager_stub::Action& action) {
+  void PrintAction(const rpc_port::plugin_manager_stub::ActionModel& action) {
     LOG(INFO) << "Action id: " << action.Getaction_id();
-    LOG(INFO) << "App id: " << action.Getapp_id();
-    LOG(INFO) << "Description: " << action.Getdescription();
-    LOG(INFO) << "Type: " << action.Gettype();
-    LOG(INFO) << "Privileges: ";
-    for (const auto& privilege : action.Getprivileges()) {
-      LOG(INFO) << " " << privilege;
-    }
-    LOG(INFO) << "Parameters: ";
-    for (const auto& parameter : action.Getparameters()) {
-      LOG(INFO) << " Key: " << parameter.Getkey();
-      LOG(INFO) << " Type: " << parameter.Gettype();
-    }
+    LOG(INFO) << "Package id: " << action.Getpackage_id();
+    LOG(INFO) << "Json: " << action.Getjson();
   }
 };
 
index 87f8b10ab2ad2dc613265f7b03efb59caf1dd86d..1b525448febdedddfcac1155257f025f09d2bc85 100644 (file)
@@ -1,78 +1,53 @@
 #include <gtest/gtest.h>
 
-#include "action/plugin_manager_proxy.h"
+#include "action/tizen_action_service_stub.h"
 #include "action/utils/action_model_converter.hh"
 #include "common/action_model.h"
 
-class ActionModelConverterTest : public ::testing::Test {
-protected:
-    void SetUp() override {}
-};
-
-TEST_F(ActionModelConverterTest, ConvertToAction_ValidInput) {
-    common::ActionModel model;
-    model.SetActionId("test_action");
-    model.SetAppId("test_app");
-    model.SetDescription("test_desc");
-    model.SetPrivileges({"priv1", "priv2"});
-    model.SetType(common::ActionType::AppControl);
-
-    common::ActionParameter param1;
-    param1.SetName("param1");
-    param1.SetType(common::ParameterType::StringType);
-    param1.SetValue("value1");
-    param1.SetDescription("param_desc");
-    param1.SetIsRequired(true);
-    model.SetParameters({param1});
-
-    ActionModelConverter converter;
-
-    rpc_port::plugin_manager_proxy::Action action = converter.ConvertToAction(model);
-
-    EXPECT_EQ(action.Getaction_id(), "test_action");
-    EXPECT_EQ(action.Getapp_id(), "test_app");
-    EXPECT_EQ(action.Getdescription(), "test_desc");
-    EXPECT_EQ(action.Getprivileges().size(), 2);
-    EXPECT_EQ(action.Gettype(), "app_control");
-    EXPECT_EQ(action.Getparameters().size(), 1);
-
-    const auto& param = action.Getparameters()[0];
-    EXPECT_EQ(param.Getkey(), "param1");
-    EXPECT_EQ(param.Gettype(), "string");
-    EXPECT_EQ(param.Getvalue(), "value1");
-    EXPECT_EQ(param.Getdescription(), "param_desc");
-    EXPECT_TRUE(param.Getis_requied());
-}
-
-TEST_F(ActionModelConverterTest, ConvertToAction_EmptyParameters) {
-    common::ActionModel model;
-    model.SetActionId("test_action");
-    ActionModelConverter converter;
-    rpc_port::plugin_manager_proxy::Action action = converter.ConvertToAction(model);
-    EXPECT_EQ(action.Getparameters().size(), 0);
-}
-
-TEST_F(ActionModelConverterTest, ConvertToAction_RequiredParameter) {
-    common::ActionModel model;
-    common::ActionParameter param;
-    param.SetIsRequired(false);
-    model.SetParameters({param});
-    rpc_port::plugin_manager_proxy::Action action = ActionModelConverter().ConvertToAction(model);
-    EXPECT_FALSE(action.Getparameters()[0].Getis_requied());
+TEST(ActionModelConverterTest, ConvertToAction) {
+  std::string json = R"({
+    "name": "test_action",
+    "packageId": "com.example.test",
+    "params": {
+      "param": "value",
+    }
+  })";
+
+  common::ActionModel common_model(json);
+  auto action =
+      ActionModelConverter().ConvertToAction(common_model);
+
+  EXPECT_EQ(action.Getaction_id(), "test_action");
+  EXPECT_EQ(action.Getpackage_id(), "com.example.test");
+  EXPECT_EQ(action.Getjson(), json);
 }
 
-TEST_F(ActionModelConverterTest, ActionTypeToString_AllTypes) {
-    ActionModelConverter converter;
-    EXPECT_EQ(converter.ActionTypeToString(common::ActionType::AppControl), "app_control");
-    EXPECT_EQ(converter.ActionTypeToString(common::ActionType::Plugin), "plugin");
-    EXPECT_EQ(converter.ActionTypeToString(static_cast<common::ActionType>(-1)), "InvalidType");
+TEST(ActionModelConverterTest, ActionTypeToString) {
+  EXPECT_EQ(
+      ActionModelConverter().ActionTypeToString(common::ActionType::AppControl),
+      "app_control");
+  EXPECT_EQ(
+      ActionModelConverter().ActionTypeToString(common::ActionType::Plugin),
+      "plugin");
+  EXPECT_EQ(ActionModelConverter().ActionTypeToString(
+                static_cast<common::ActionType>(999)),
+            "InvalidType");
 }
 
-TEST_F(ActionModelConverterTest, ActionParameterTypeToString_AllTypes) {
-    ActionModelConverter converter;
-    EXPECT_EQ(converter.ActionParameterTypeToString(common::ParameterType::IntType), "integer");
-    EXPECT_EQ(converter.ActionParameterTypeToString(common::ParameterType::StringType), "string");
-    EXPECT_EQ(converter.ActionParameterTypeToString(common::ParameterType::DoubleType), "double");
-    EXPECT_EQ(converter.ActionParameterTypeToString(common::ParameterType::BoolType), "bool");
-    EXPECT_EQ(converter.ActionParameterTypeToString(static_cast<common::ParameterType>(-1)), "InvalidType");
+TEST(ActionModelConverterTest, ParameterTypeToString) {
+  EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
+                common::ParameterType::IntType),
+            "integer");
+  EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
+                common::ParameterType::StringType),
+            "string");
+  EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
+                common::ParameterType::DoubleType),
+            "double");
+  EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
+                common::ParameterType::BoolType),
+            "bool");
+  EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
+                static_cast<common::ParameterType>(999)),
+            "InvalidType");
 }
index 8770024d3565acb6031cb559fdbd15e26ba9b155..23f83dc00b65603cd467136d1eb4b6a1124ff0d7 100644 (file)
@@ -1,49 +1,36 @@
-#include <gtest/gtest.h>
 #include "common/action_model.h"
+#include <gtest/gtest.h>
 
 using namespace common;
 
-TEST(ActionModelTest, SettersAndGetters) {
-    ActionModel model;
+TEST(ActionModelTest, JsonInitialization) {
+  ActionModel model(R"({
+      "name": "new_action",
+      "packageId": "new_package",
+      "params": {
+        "param1": "hello1",
+        "param2": "hello2",
+      }
+    })");
 
-    model.SetActionId("new_action");
-    model.SetAppId("new_app");
-    model.SetDescription("New Desc");
-    model.SetParameters({ActionParameter("param1", ParameterType::StringType, "type1", "desc1", true)});
-    model.SetPrivileges({"privilege2"});
-    model.SetType(ActionType::AppControl);
+  model.SetType(ActionType::AppControl);
 
-    EXPECT_EQ("new_action", model.GetActionId());
-    EXPECT_EQ("new_app", model.GetAppId());
-    EXPECT_EQ("New Desc", model.GetDescription());
-    EXPECT_EQ(1, model.GetParameters().size());
-    EXPECT_EQ(1, model.GetPrivileges().size());
-    EXPECT_EQ(ActionType::AppControl, model.GetType());
+  EXPECT_EQ("new_action", model.GetId());
+  EXPECT_EQ("new_package", model.GetPackageId());
+  EXPECT_EQ(2, model.GetParameters().size());
+  const auto& parameters = model.GetParameters();
+  EXPECT_EQ(2, parameters.size());
+  EXPECT_EQ("param1", parameters.at(0).first);
+  EXPECT_EQ("hello1", parameters.at(0).second);
+  EXPECT_EQ("param2", parameters.at(1).first);
+  EXPECT_EQ("hello2", parameters.at(1).second);
+  EXPECT_EQ(ActionType::AppControl, model.GetType());
 }
 
 TEST(ActionModelTest, EmptyInitialization) {
-    ActionModel model;
-    EXPECT_EQ("", model.GetActionId());
-    EXPECT_EQ("", model.GetAppId());
-    EXPECT_EQ("", model.GetDescription());
-    EXPECT_EQ(0, model.GetParameters().size());
-    EXPECT_EQ(0, model.GetPrivileges().size());
-}
-
-TEST(ActionModelTest, ParameterVectorTest) {
-    ActionModel model;
-    std::vector<ActionParameter> params = {
-        ActionParameter("name1", ParameterType::StringType, "type1", "desc1", true),
-        ActionParameter("name2", ParameterType::StringType, "type2", "desc2", false)
-    };
-    model.SetParameters(params);
-    EXPECT_EQ(2, model.GetParameters().size());
-    EXPECT_EQ("name1", model.GetParameters()[0].GetName());
-}
-
-TEST(ActionModelTest, PrivilegeVectorTest) {
-    ActionModel model;
-    model.SetPrivileges({"priv1", "priv2"});
-    EXPECT_EQ(2, model.GetPrivileges().size());
-    EXPECT_EQ("priv1", model.GetPrivileges()[0]);
+  ActionModel model;
+  EXPECT_EQ("", model.GetId());
+  EXPECT_EQ("", model.GetPackageId());
+  EXPECT_EQ(0, model.GetParameters().size());
+  EXPECT_EQ(ActionType::InvalidType, model.GetType());
 }
diff --git a/test/unit_tests/action_schema_test.cc b/test/unit_tests/action_schema_test.cc
new file mode 100644 (file)
index 0000000..05afaf8
--- /dev/null
@@ -0,0 +1,111 @@
+#include <gtest/gtest.h>
+#include "common/action_schema.h"
+#include <sstream>
+
+using namespace common;
+
+class ActionSchemaTest : public ::testing::Test {
+protected:
+    void SetUp() override {
+        valid_json_ = R"(
+        {
+          "name": "test_action",
+          "appId": "com.example.app",
+          "category": "test_category",
+          "desc": "Test action description",
+          "type": "app_control",
+          "params": {
+            "param1": {
+              "type": "integer",
+              "desc": "Param 1"
+            },
+            "param2": {
+              "type": "string",
+              "desc": "Param 2"
+            }
+          },
+          "returns": {
+            "return1": {
+              "type": "double",
+              "desc": "Return 1"
+            }
+          },
+          "required-privileges": ["priv1", "priv2"]
+        })";
+        invalid_json_ = R"( { "invalid": "json" })";
+    }
+
+    std::string valid_json_;
+    std::string invalid_json_;
+};
+
+TEST_F(ActionSchemaTest, ValidJsonParsing) {
+    ActionSchema schema(valid_json_);
+    EXPECT_EQ(schema.GetActionId(), "test_action");
+    EXPECT_EQ(schema.GetPackageId(), "com.example.app");
+    EXPECT_EQ(schema.GetCategory(), "test_category");
+    EXPECT_EQ(schema.GetDescription(), "Test action description");
+    EXPECT_EQ(schema.GetType(), ActionType::AppControl);
+
+    const auto& params = schema.GetParameters();
+    EXPECT_EQ(params.size(), 2);
+    EXPECT_EQ(params[0].GetName(), "param1");
+    EXPECT_EQ(params[0].GetType(), ParameterType::IntType);
+    EXPECT_EQ(params[1].GetName(), "param2");
+    EXPECT_EQ(params[1].GetType(), ParameterType::StringType);
+
+    const auto& returns = schema.GetReturns();
+    EXPECT_EQ(returns.size(), 1);
+    EXPECT_EQ(returns[0].GetType(), ParameterType::DoubleType);
+
+    const auto& privileges = schema.GetPrivileges();
+    EXPECT_EQ(privileges.size(), 2);
+    EXPECT_EQ(privileges[0], "priv1");
+    EXPECT_EQ(privileges[1], "priv2");
+}
+
+TEST_F(ActionSchemaTest, InvalidJsonParsing) {
+    ActionSchema invalid_schema(invalid_json_);
+    EXPECT_EQ(invalid_schema.GetActionId().empty(), true);
+    EXPECT_EQ(invalid_schema.GetPackageId().empty(), true);
+    EXPECT_EQ(invalid_schema.GetCategory().empty(), true);
+    EXPECT_EQ(invalid_schema.GetDescription().empty(), true);
+    EXPECT_EQ(invalid_schema.GetType(), ActionType::InvalidType);
+}
+
+TEST_F(ActionSchemaTest, SettersAndGetters) {
+    ActionSchema schema;
+    schema.SetActionId("new_id");
+    schema.SetPackageId("new_package");
+    schema.SetCategory("new_category");
+    schema.SetDescription("new_desc");
+    schema.SetType(ActionType::Plugin);
+
+    EXPECT_EQ(schema.GetActionId(), "new_id");
+    EXPECT_EQ(schema.GetPackageId(), "new_package");
+    EXPECT_EQ(schema.GetCategory(), "new_category");
+    EXPECT_EQ(schema.GetDescription(), "new_desc");
+    EXPECT_EQ(schema.GetType(), ActionType::Plugin);
+}
+
+TEST_F(ActionSchemaTest, ParameterTypeConversion) {
+    ActionSchema schema(valid_json_);
+    const auto& params = schema.GetParameters();
+    EXPECT_EQ(params[0].GetType(), ParameterType::IntType);
+    EXPECT_EQ(params[1].GetType(), ParameterType::StringType);
+
+    const auto& returns = schema.GetReturns();
+    EXPECT_EQ(returns[0].GetType(), ParameterType::DoubleType);
+}
+
+TEST_F(ActionSchemaTest, DefaultConstructor) {
+    ActionSchema default_schema;
+    EXPECT_TRUE(default_schema.GetActionId().empty());
+    EXPECT_TRUE(default_schema.GetPackageId().empty());
+    EXPECT_TRUE(default_schema.GetCategory().empty());
+    EXPECT_TRUE(default_schema.GetDescription().empty());
+    EXPECT_EQ(default_schema.GetType(), ActionType::InvalidType);
+    EXPECT_TRUE(default_schema.GetParameters().empty());
+    EXPECT_TRUE(default_schema.GetReturns().empty());
+    EXPECT_TRUE(default_schema.GetPrivileges().empty());
+}
index 2ce3e83dcec87b8c885b43a78ff51ae831713fec..89b730ab260f8dcf67730c209235ccff25f0f2d7 100644 (file)
@@ -3,5 +3,5 @@ import <tizen_action_datatype.tidl>
 
 interface PluginManager {
     void ResultHandler(string result) delegate;
-    void Execute(Action action, ResultHandler result_cb) async;
+    void Execute(ActionModel action, ResultHandler result_cb) async;
 }
index 566e3053dbed02a33d49ad600605668453bb7fad..e3cbb7d904d41f0aabcca9f94b32c30e7efb7084 100644 (file)
@@ -13,15 +13,22 @@ struct Result {
     string type;
 }
 
-struct Action {
+struct ActionSchema {
     string action_id;
-    string app_id;
+    string package_id;
     string category;
     string description;
     string type;
     array<Parameter> parameters;
     array<Result> results;
     array<string> privileges;
+    string json;
+}
+
+struct ActionModel {
+    string action_id;
+    string package_id;
+    string json;
 }
 
 struct VectorDbResult {
index a1267c2ef15af05f1a7b54f3d06faf070f0de1ac..481c0a3ca0a772e97ba45d781a4a6c74028c29c3 100644 (file)
@@ -2,10 +2,10 @@ protocol 2
 import <tizen_action_datatype.tidl>
 
 interface ActionService {
-    array<Action> ListActions();
-    Action GetAction(string action_id);
+    array<ActionSchema> ListActions();
+    ActionSchema GetAction(string action_id);
     array<VectorDbResult> GetActionId(string user_description, int top_k, float search_threshold);
-    int Execute(Action action);
+    int Execute(ActionModel action);
     void ActionReplyCb(string result) delegate;
     int RegisterActionReplyCb(ActionReplyCb cb);
     bool UnregisterActionReplyCb(int id);
index 7ddd8f171b3f627ed14bf1fb73d54532a8b4516e..534ed63d360d08d4b1fe6d626bcb8dc1c92a1a71 100644 (file)
 #include "action_tool.hh"
 #include "log_private.hh"
 
+#include <jsoncpp/json/json.h>
+
 #include <memory>
 #include <utility>
 
 #include "action_tool/tizen_action_service_proxy.h"
+#include "log_private.hh"
+
 
 namespace action_tool {
+namespace {
 
 constexpr const char kStubAppId[] = "org.tizen.action-framework.service";
 
+// Json::Value ParseJsonFromString(const std::string& json_str) {
+//   Json::Value root;
+//   Json::CharReaderBuilder builder;
+//   JSONCPP_STRING err;
+//   const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
+//   if (!reader->parse(json_str.c_str(), json_str.c_str() + json_str.length(),
+//       &root, &err)) {
+//     _E("Failed to parse json string");
+//     return {};
+//   }
+//   return root;
+// }
+
+}  // namespace
+
 namespace rpc = rpc_port::tizen_action_service_proxy;
 using ActionReplyCb = rpc::proxy::ActionService::ActionReplyCb;
 class Reply : public ActionReplyCb {
@@ -40,7 +60,7 @@ class Execute : public ActionTool,
                       IEventListener {
  public:
   Execute()
-      : ActionTool("execute", "Execute", "execute <action id> <app_control/plugin> <parameter1:value> ..."),
+      : ActionTool("execute", "Execute", "execute <action id> <package_id> <json string>"),
         proxy_(this, kStubAppId) {}
 
   virtual ~Execute() {}
@@ -80,32 +100,17 @@ class Execute : public ActionTool,
       return -1;
     }
 
-    rpc_port::tizen_action_service_proxy::Action action;
+    rpc_port::tizen_action_service_proxy::ActionModel action;
     std::vector<rpc_port::tizen_action_service_proxy::Parameter> actionparams;
 
     std::string action_id = std::string(argv[2]);
-    std::string type = std::string(argv[3]);
+    std::string package_id = std::string(argv[3]);
+    std::string json = std::string(argv[4]);
 
     action.Setaction_id(action_id);
-    action.Settype(type);
-
-    _E("id : %s, type : %s", action_id.c_str(), type.c_str());
-
-    for (int i = 4; i < argc; i++) {
-      std::string args = std::string(argv[i]);
-      std::size_t delim = args.find(":");
-
-      std::string key_ = args.substr(0, delim);
-      std::string value_ = args.substr(delim + 1);
-
-      _E("key : %s, value : %s", key_.c_str(), value_.c_str());
-
-      auto param = rpc_port::tizen_action_service_proxy::Parameter(key_, "", value_, "", true);
-
-      actionparams.push_back(param);
-    }
-    action.Setparameters(actionparams);
-
+    action.Setpackage_id(package_id);
+    _E("id : %s, package_id : %s", action_id.c_str(), package_id.c_str());
+    action.Setjson(json);
     try {
       int ret = proxy_.Execute(action);
       return ret;
index 496ae5fa3854f0fd48b3b64f92eb38797ad39845..f8693093e51e4413428e276e92d51e87729ceb2f 100644 (file)
@@ -71,7 +71,7 @@ class GetAction : public ActionTool,
     try {
       auto action = proxy_.GetAction(std::move(action_id));
       _D("id: %s --------------------", action.Getaction_id().c_str());
-      _D("appid: %s", action.Getapp_id().c_str());
+      _D("package: %s", action.Getpackage_id().c_str());
       _D("category: %s", action.Getcategory().c_str());
       _D("description: %s", action.Getdescription().c_str());
 
index f42e9cac3e9e706a24f0f8e53d5b00f3266ee039..e7db487dcb61307b66fe10876deccee8d47336f6 100644 (file)
@@ -64,7 +64,7 @@ class ListActions : public ActionTool,
       _D("Actions cnt(%zu)", actions.size());
       for (auto action : actions) {
         _D("id: %s --------------------", action.Getaction_id().c_str());
-        _D("appid: %s", action.Getapp_id().c_str());
+        _D("package_id: %s", action.Getpackage_id().c_str());
         _D("category: %s", action.Getcategory().c_str());
         _D("description: %s", action.Getdescription().c_str());