Implement app_core_base_control APIs 18/305218/7
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 30 Jan 2024 06:11:38 +0000 (15:11 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 30 Jan 2024 23:23:20 +0000 (08:23 +0900)
To remote appcore-common dependency from app-control,
the app_core_base_control APIs are added.

Adds:
 - app_core_base_control_add()
 - app_core_base_control_remove()

Change-Id: I49da74afe61ad19730cdce2de92091b4ca378165
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
12 files changed:
packaging/app-core.spec
tizen-cpp/app-core-cpp/CMakeLists.txt
tizen-cpp/app-core-cpp/api/app_core_base_control.cc [new file with mode: 0644]
tizen-cpp/app-core-cpp/api/app_core_base_control.h [new file with mode: 0644]
tizen-cpp/app-core-cpp/app-core-cpp.pc.in
tizen-cpp/app-core-cpp/app_control_action_private.cc [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_control_action_private.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_control_info_private.cc [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_control_info_private.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_control_manager_private.cc [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_control_manager_private.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_core_base.cc

index 6524eac..b574f51 100644 (file)
@@ -279,6 +279,7 @@ install -m 0644 %{name}.zip %{buildroot}%{_datadir}/gcov/
 %{_includedir}/appcore_cpp/interface_app_core_ui_event.hh
 %{_includedir}/appcore_cpp/interface_main_loop.hh
 %{_includedir}/appcore_cpp/interface_window.hh
+%{_includedir}/appcore_cpp/api/app_core_base_control.h
 %{_libdir}/libapp-core-cpp.so
 %{_libdir}/pkgconfig/app-core-cpp.pc
 
index 0534880..d3c3ce4 100644 (file)
@@ -1,12 +1,15 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/api API_SRCS)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_CORE_CPP_SRCS)
 SET(COMMON_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../common/glib_private.cc)
 
 ADD_LIBRARY(${TARGET_APP_CORE_CPP} SHARED
+  ${API_SRCS}
   ${APP_CORE_CPP_SRCS}
   ${COMMON_SRCS})
 
 TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_CPP} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/api
   ${CMAKE_CURRENT_SOURCE_DIR}/../)
 
 TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_CPP} PUBLIC "-ldl -L${LIB_INSTALL_DIR}/hal -Wl,-z,nodelete")
@@ -22,6 +25,10 @@ APPLY_PKG_CONFIG(${TARGET_APP_CORE_CPP} PUBLIC
   VCONF_DEPS
 )
 
+APPLY_PKG_CONFIG(${TARGET_APP_CORE_CPP} PRIVATE
+  PKGMGR_INFO_DEPS
+)
+
 CONFIGURE_FILE(${TARGET_APP_CORE_CPP}.pc.in ${TARGET_APP_CORE_CPP}.pc @ONLY)
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_APP_CORE_CPP}.pc
   DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
@@ -31,3 +38,8 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/appcore_cpp
   FILES_MATCHING
   PATTERN "*_private.hh" EXCLUDE
   PATTERN "*.hh")
+
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/api/
+  DESTINATION include/appcore_cpp/api
+  FILES_MATCHING
+  PATTERN "*.h")
diff --git a/tizen-cpp/app-core-cpp/api/app_core_base_control.cc b/tizen-cpp/app-core-cpp/api/app_core_base_control.cc
new file mode 100644 (file)
index 0000000..263be6d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 "app-core-cpp/api/app_core_base_control.h"
+
+#include "app-core-cpp/app_control_manager_private.hh"
+#include "common/log_private.hh"
+
+#undef API
+#define API extern "C" __attribute__ ((visibility("default")))
+
+API int app_core_base_control_add(const char* id, app_core_base_control_cb cb,
+                                  void* user_data, app_core_base_control_h* h) {
+  if (id == nullptr || cb == nullptr || h == nullptr) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  return tizen_cpp::AppControlManager::Add(
+      id, [=](bundle* b) { cb(b, user_data); },
+      reinterpret_cast<tizen_cpp::AppControlAction**>(h));
+}
+
+API int app_core_base_control_remove(app_core_base_control_h h) {
+  if (h == nullptr) {
+    _E("Invalid parameter");
+    return -EINVAL;
+  }
+
+  return tizen_cpp::AppControlManager::Remove(
+      reinterpret_cast<tizen_cpp::AppControlAction*>(h));
+}
diff --git a/tizen-cpp/app-core-cpp/api/app_core_base_control.h b/tizen-cpp/app-core-cpp/api/app_core_base_control.h
new file mode 100644 (file)
index 0000000..d8ce69a
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 __APP_CORE_BASE_CONTROL_H__
+#define __APP_CORE_BASE_CONTROL_H__
+
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *app_core_base_control_h;
+
+typedef void (*app_core_base_control_cb)(bundle *b, void *user_data);
+
+int app_core_base_control_add(const char *id, app_core_base_control_cb cb,
+                              void *user_data, app_core_base_control_h *h);
+
+int app_core_base_control_remove(app_core_base_control_h h);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APP_CORE_BASE_CONTROL_H__ */
index 9aec6dd..e9305fc 100644 (file)
@@ -10,5 +10,5 @@ Description: Tizen application core library
 Version: @VERSION@
 Requires.private: sensor vconf aul dlog
 Libs: -L${libdir} -lapp-core-cpp
-Cflags: -I${includedir} -I${includedir}/appcore_cpp
-cppflags: I${includedir} -I${includedir}/appcore_cpp
+Cflags: -I${includedir} -I${includedir}/appcore_cpp -I${includedir}/appcore_cpp/api
+cppflags: I${includedir} -I${includedir}/appcore_cpp -I${includedir}/appcore_cpp/api
diff --git a/tizen-cpp/app-core-cpp/app_control_action_private.cc b/tizen-cpp/app-core-cpp/app_control_action_private.cc
new file mode 100644 (file)
index 0000000..f897d2c
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * 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 "app-core-cpp/app_control_action_private.hh"
+
+#include <utility>
+
+namespace tizen_cpp {
+
+AppControlAction::AppControlAction(std::string action, ControlFunc func)
+    : action_(std::move(action)), func_(std::move(func)) {}
+
+const std::string& AppControlAction::GetAction() const { return action_; }
+
+void AppControlAction::Invoke(bundle* b) { func_(b); }
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-cpp/app_control_action_private.hh b/tizen-cpp/app-core-cpp/app_control_action_private.hh
new file mode 100644 (file)
index 0000000..7d7dd72
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * 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 TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_ACTION_HH_
+#define TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_ACTION_HH_
+
+#include <bundle.h>
+
+#include <functional>
+#include <string>
+
+namespace tizen_cpp {
+
+class AppControlAction {
+ public:
+  using ControlFunc = std::function<void(bundle*)>;
+
+  AppControlAction(std::string action, ControlFunc func);
+
+  const std::string& GetAction() const;
+
+  void Invoke(bundle* b);
+
+ private:
+  std::string action_;
+  ControlFunc func_;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_ACTION_HH_
diff --git a/tizen-cpp/app-core-cpp/app_control_info_private.cc b/tizen-cpp/app-core-cpp/app_control_info_private.cc
new file mode 100644 (file)
index 0000000..e0b986f
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * 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 "app-core-cpp/app_control_info_private.hh"
+
+#include <utility>
+
+namespace tizen_cpp {
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetOperation(
+    aul_svc_info_h info) {
+  char* operation;
+  if (aul_svc_info_get_operation(info, &operation) == AUL_SVC_RET_OK) {
+    operation_ = operation;
+    free(operation);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetUri(aul_svc_info_h info) {
+  char* uri;
+  if (aul_svc_info_get_uri(info, &uri) == AUL_SVC_RET_OK) {
+    uri_ = uri;
+    free(uri);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetUriScheme(
+    aul_svc_info_h info) {
+  char* uri_scheme;
+  if (aul_svc_info_get_uri_scheme(info, &uri_scheme) == AUL_SVC_RET_OK) {
+    uri_scheme_ = uri_scheme;
+    free(uri_scheme);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetUriHost(
+    aul_svc_info_h info) {
+  char* uri_host;
+  if (aul_svc_info_get_uri_host(info, &uri_host) == AUL_SVC_RET_OK) {
+    uri_host_ = uri_host;
+    free(uri_host);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetMime(aul_svc_info_h info) {
+  char* mime;
+  if (aul_svc_info_get_mime(info, &mime) == AUL_SVC_RET_OK) {
+    mime_ = mime;
+    free(mime);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetMimeType(
+    aul_svc_info_h info) {
+  char* mime_type;
+  if (aul_svc_info_get_mime_type(info, &mime_type) == AUL_SVC_RET_OK) {
+    mime_type_ = mime_type;
+    free(mime_type);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetMimeSubtype(
+    aul_svc_info_h info) {
+  char* mime_subtype;
+  if (aul_svc_info_get_mime_subtype(info, &mime_subtype) == AUL_SVC_RET_OK) {
+    mime_subtype_ = mime_subtype;
+    free(mime_subtype);
+  }
+
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetId(std::string id) {
+  id_ = std::move(id);
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetOperation(
+    std::string operation) {
+  operation_ = std::move(operation);
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetUri(std::string uri) {
+  uri_ = std::move(uri);
+  return *this;
+}
+
+AppControlInfo::Builder& AppControlInfo::Builder::SetMime(std::string mime) {
+  mime_ = std::move(mime);
+  return *this;
+}
+
+AppControlInfo* AppControlInfo::Builder::Build() {
+  return new AppControlInfo(std::move(id_), std::move(operation_),
+                            std::move(uri_), std::move(uri_scheme_),
+                            std::move(uri_host_), std::move(mime_),
+                            std::move(mime_type_), std::move(mime_subtype_));
+}
+
+AppControlInfo::AppControlInfo(std::string id, std::string operation,
+                               std::string uri, std::string uri_scheme,
+                               std::string uri_host, std::string mime,
+                               std::string mime_type, std::string mime_subtype)
+    : id_(std::move(id)),
+      operation_(std::move(operation)),
+      uri_(std::move(uri)),
+      uri_scheme_(std::move(uri_scheme)),
+      uri_host_(std::move(uri_host)),
+      mime_(std::move(mime)),
+      mime_type_(std::move(mime_type)),
+      mime_subtype_(std::move(mime_subtype)) {}
+
+const std::string& AppControlInfo::GetId() const { return id_; }
+
+const std::string& AppControlInfo::GetOperation() const { return operation_; }
+
+const std::string& AppControlInfo::GetUri() const { return uri_; }
+
+const std::string& AppControlInfo::GetUriScheme() const { return uri_scheme_; }
+
+const std::string& AppControlInfo::GetUriHost() const { return uri_host_; }
+
+const std::string& AppControlInfo::GetMime() const { return mime_; }
+
+const std::string& AppControlInfo::GetMimeType() const { return mime_type_; }
+
+const std::string& AppControlInfo::GetMimeSubtype() const {
+  return mime_subtype_;
+}
+
+void AppControlInfo::SetUri(std::string uri) { uri_ = std::move(uri); }
+
+bool AppControlInfo::Match(const AppControlInfo& info) const {
+  if (info.GetOperation() != GetOperation()) return false;
+
+  if (info.GetUri() == GetUri() && info.GetMime() == GetMime()) return true;
+
+  if (info.GetUri() == GetUri()) {
+    if (info.GetMime() == "NULL" && info.GetMimeSubtype() == "%") {
+      std::string mime = info.GetMimeType() + "/*";
+      if (GetMime() == mime) return true;
+    }
+
+    if (info.GetMime() == "NULL" && info.GetMimeType() == "%")
+      if (GetMime() == "*/*") return true;
+  }
+
+  return false;
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-cpp/app_control_info_private.hh b/tizen-cpp/app-core-cpp/app_control_info_private.hh
new file mode 100644 (file)
index 0000000..0b02fdd
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * 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 TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_INFO_PRIVATE_HH_
+#define TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_INFO_PRIVATE_HH_
+
+#include <aul_svc.h>
+#include <aul_svc_internal.h>
+
+#include <string>
+
+namespace tizen_cpp {
+
+class AppControlInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetOperation(aul_svc_info_h info);
+    Builder& SetUri(aul_svc_info_h info);
+    Builder& SetUriScheme(aul_svc_info_h info);
+    Builder& SetUriHost(aul_svc_info_h info);
+    Builder& SetMime(aul_svc_info_h info);
+    Builder& SetMimeType(aul_svc_info_h info);
+    Builder& SetMimeSubtype(aul_svc_info_h info);
+
+    Builder& SetId(std::string id);
+    Builder& SetOperation(std::string operation);
+    Builder& SetUri(std::string uri);
+    Builder& SetMime(std::string mime);
+
+    AppControlInfo* Build();
+
+   private:
+    std::string id_;
+    std::string operation_;
+    std::string uri_;
+    std::string uri_scheme_;
+    std::string uri_host_;
+    std::string mime_;
+    std::string mime_type_;
+    std::string mime_subtype_;
+  };
+
+ private:
+  friend class AppControlInfo::Builder;
+  AppControlInfo(std::string id, std::string operation, std::string uri,
+                 std::string uri_scheme, std::string uri_host, std::string mime,
+                 std::string mime_type, std::string mime_subtype);
+
+ public:
+  const std::string& GetId() const;
+  const std::string& GetOperation() const;
+  const std::string& GetUri() const;
+  const std::string& GetUriScheme() const;
+  const std::string& GetUriHost() const;
+  const std::string& GetMime() const;
+  const std::string& GetMimeType() const;
+  const std::string& GetMimeSubtype() const;
+
+  void SetUri(std::string uri);
+
+  bool Match(const AppControlInfo& info) const;
+
+ private:
+  std::string id_;
+  std::string operation_;
+  std::string uri_;
+  std::string uri_scheme_;
+  std::string uri_host_;
+  std::string mime_;
+  std::string mime_type_;
+  std::string mime_subtype_;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_INFO_PRIVATE_HH_
diff --git a/tizen-cpp/app-core-cpp/app_control_manager_private.cc b/tizen-cpp/app-core-cpp/app_control_manager_private.cc
new file mode 100644 (file)
index 0000000..190b7bf
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * 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 "app-core-cpp/app_control_manager_private.hh"
+
+#include <aul.h>
+#include <errno.h>
+#include <pkgmgr-info.h>
+
+#include <memory>
+#include <mutex>
+#include <utility>
+#include <vector>
+
+#include "app-core-cpp/app_control_action_private.hh"
+#include "app-core-cpp/app_control_info_private.hh"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+namespace {
+
+class Manager {
+ public:
+  int Init() {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    if (!disposed_) return 0;
+
+    char appid[512];
+    int ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+    if (ret != AUL_R_OK) {
+      _E("aul_app_get_appid_bypid() is failed. error(%d)", ret);
+      return -EIO;
+    }
+
+    pkgmgrinfo_appinfo_h handle;
+    ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
+    if (ret != PMINFO_R_OK) {
+      _E("pkgmgrinfo_appinfo_get_appinfo() is failed");
+      return -EIO;
+    }
+
+    ret = pkgmgrinfo_appinfo_foreach_appcontrol_v2(
+        handle,
+        [](const char* operation, const char* uri, const char* mime,
+           const char* id, void* user_data) {
+          auto* info = AppControlInfo::Builder()
+                           .SetId(id)
+                           .SetOperation(operation)
+                           .SetMime(mime ? mime : "NULL")
+                           .SetUri(uri ? uri : "NULL")
+                           .Build();
+          if (info == nullptr) return -1;
+
+          auto* mgr = static_cast<Manager*>(user_data);
+          mgr->infos_.emplace_back(info);
+          return 0;
+        },
+        this);
+    pkgmgrinfo_appinfo_destroy_appinfo(handle);
+    if (ret != PMINFO_R_OK) {
+      _E("pkgmgrinfo_appinfo_foreach_appcontrol_v2() is failed");
+      return -EIO;
+    }
+
+    disposed_ = false;
+    return 0;
+  }
+
+  void Dispose() {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    if (disposed_) return;
+
+    infos_.clear();
+    actions_.clear();
+    disposed_ = true;
+  }
+
+  int Invoke(bundle* b) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    if (actions_.empty()) return 0;
+
+    auto info = AppControlInfoFind(b);
+    if (info == nullptr) return 0;
+
+    for (auto& action : actions_) {
+      if (action->GetAction() == info->GetId())
+        action->Invoke(b);
+    }
+
+    _D("[ACTION] %s", info->GetId().c_str());
+    return 0;
+  }
+
+  int Add(std::string id, AppControlAction::ControlFunc func,
+          AppControlAction** h) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    if (!AppControlInfoExists(id)) {
+      _E("Failed to find control info(%s)", id.c_str());
+      return -ENOKEY;
+    }
+
+    auto action =
+        std::make_shared<AppControlAction>(std::move(id), std::move(func));
+    if (action == nullptr) {
+      _E("Failed to create AppControlAction");
+      return -ENOMEM;
+    }
+
+    *h = action.get();
+    actions_.push_back(std::move(action));
+    return 0;
+  }
+
+  int Remove(AppControlAction* h) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    auto found =
+        std::find_if(actions_.begin(), actions_.end(),
+                     [h](const auto& action) { return action.get() == h; });
+    if (found == actions_.end()) {
+      _E("Failed to find action(%p)", h);
+      return -EINVAL;
+    }
+
+    actions_.erase(found);
+    return 0;
+  }
+
+  std::recursive_mutex& GetMutex() const { return mutex_; }
+
+ private:
+  bool AppControlInfoExists(const std::string& id) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    for (const auto& info : infos_)
+      if (info->GetId() == id) return true;
+
+    return false;
+  }
+
+  std::shared_ptr<AppControlInfo> AppControlInfoCreate(bundle* b) {
+    aul_svc_info_h svc_info;
+    int ret = aul_svc_info_create(b, &svc_info);
+    if (ret!= AUL_SVC_RET_OK) return nullptr;
+
+    auto* info = AppControlInfo::Builder()
+                     .SetOperation(svc_info)
+                     .SetUri(svc_info)
+                     .SetUriScheme(svc_info)
+                     .SetUriHost(svc_info)
+                     .SetMime(svc_info)
+                     .SetMimeType(svc_info)
+                     .SetMimeSubtype(svc_info).Build();
+    if (info == nullptr) return nullptr;
+
+    return std::shared_ptr<AppControlInfo>(info);
+  }
+
+  std::shared_ptr<AppControlInfo> AppControlInfoFind(bundle* b) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    auto info = AppControlInfoCreate(b);
+    if (info == nullptr) return nullptr;
+
+    // Step 1
+    auto found =
+        std::find_if(infos_.begin(), infos_.end(),
+                     [&info](const std::shared_ptr<AppControlInfo>& a_info) {
+                       return a_info->Match(*info);
+                     });
+    if (found != infos_.end()) return *found;
+
+    // Step 2
+    if (info->GetUriScheme() != "NULL" && info->GetUriHost() != "NULL") {
+      info->SetUri(info->GetUriScheme() + "://" + info->GetUriHost());
+      found = std::find_if(
+          infos_.begin(), infos_.end(),
+          [&info](const auto& a_info) { return a_info->Match(*info); });
+      if (found != infos_.end()) return *found;
+    }
+
+    // Step 3
+    info->SetUri(info->GetUriScheme());
+    found = std::find_if(
+        infos_.begin(), infos_.end(),
+        [&info](const auto& a_info) { return a_info->Match(*info); });
+    if (found != infos_.end()) return *found;
+
+    // Step 4
+    info->SetUri("*");
+    found = std::find_if(
+        infos_.begin(), infos_.end(),
+        [&info](const auto& a_info) { return a_info->Match(*info); });
+    if (found != infos_.end()) return *found;
+
+    // Step 5
+    if (info->GetUriScheme() == "file" && info->GetMime() != "NULL")  {
+      info->SetUri("NULL");
+      found = std::find_if(
+          infos_.begin(), infos_.end(),
+          [&info](const auto& a_info) { return a_info->Match(*info); });
+      if (found != infos_.end()) return *found;
+    }
+
+    return nullptr;
+  }
+
+ private:
+  bool disposed_ = true;
+  std::vector<std::shared_ptr<AppControlInfo>> infos_;
+  std::vector<std::shared_ptr<AppControlAction>> actions_;
+  mutable std::recursive_mutex mutex_;
+};
+
+Manager manager;
+
+}  // namespace
+
+int AppControlManager::Init() { return manager.Init(); }
+
+void AppControlManager::Shutdown() { manager.Dispose(); }
+
+int AppControlManager::Invoke(bundle* b) { return manager.Invoke(b); }
+
+int AppControlManager::Add(std::string id, AppControlAction::ControlFunc func,
+                           AppControlAction** h) {
+  return manager.Add(std::move(id), std::move(func), h);
+}
+
+int AppControlManager::Remove(AppControlAction* h) { return manager.Remove(h); }
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-cpp/app_control_manager_private.hh b/tizen-cpp/app-core-cpp/app_control_manager_private.hh
new file mode 100644 (file)
index 0000000..75487a4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ *
+ * 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 TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_MANAGER_PRIVATE_HH_
+#define TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_MANAGER_PRIVATE_HH_
+
+#include <string>
+
+#include "app-core-cpp/app_control_action_private.hh"
+
+namespace tizen_cpp {
+
+class AppControlManager {
+ public:
+  static int Init();
+  static void Shutdown();
+  static int Invoke(bundle* b);
+  static int Add(std::string id, AppControlAction::ControlFunc func,
+                 AppControlAction** h);
+  static int Remove(AppControlAction* h);
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_APP_CONTROL_MANAGER_PRIVATE_HH_
index 021435e..fd2b915 100644 (file)
@@ -49,6 +49,7 @@
 #include <utility>
 #include <vector>
 
+#include "app-core-cpp/app_control_manager_private.hh"
 #include "app-core-cpp/app_core_plugin_private.hh"
 #include "app-core-cpp/exit_handler_private.hh"
 #include "app-core-cpp/sigterm_handler_private.hh"
@@ -420,6 +421,7 @@ int AppCoreBase::OnCreate() {
 }
 
 int AppCoreBase::OnControl(tizen_base::Bundle b) {
+  AppControlManager::Invoke(b.GetHandle());
   return 0;
 }
 
@@ -1015,6 +1017,7 @@ void AppCoreBase::Dispose() {
     OnTerminate();
   traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
 
+  AppControlManager::Shutdown();
   for (auto& e : impl_->events_) {
     if (impl_->core_delegator_)
       impl_->core_delegator_->OnUnsetEvent(e->GetType());