Add codes for sending remote app control
authorInkyun Kil <inkyun.kil@samsung.com>
Wed, 2 May 2018 04:24:21 +0000 (13:24 +0900)
committer장상윤/Tizen Platform Lab(SR)/Engineer/삼성전자 <jeremy.jang@samsung.com>
Fri, 18 May 2018 07:26:29 +0000 (16:26 +0900)
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
13 files changed:
CMakeLists.txt
packaging/capmgr.spec
src/capmgr/capmgr.cc
src/common/CMakeLists.txt
src/common/appcontrol_manager.cc [new file with mode: 0644]
src/common/appcontrol_manager.h
src/common/capability_manager.cc
src/common/capability_manager.h
src/common/connection_manager.h
src/common/dbus_service.cc
src/common/dbus_service.h
src/common/iotivity.cc
src/common/iotivity.h

index 68b1c08cc930928e6a1c3d26bf892f7a8d04127d..09aa99618b8436c83dfdaaaf9538201b0694de95 100644 (file)
@@ -25,6 +25,8 @@ INCLUDE(ApplyPkgConfig)
 ADD_DEFINITIONS("-DPROJECT_TAG=\"CAPMGR\"")
 
 ## Find all needed packages once
+PKG_CHECK_MODULES(AUL_DEPS REQUIRED aul)
+PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle)
 PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
 PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
 PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
index 17cc16468b07e0598aa988e7121d526befabd42a..37cf754a0df5856d00d1d336ae85b8dcbe70cd70 100644 (file)
@@ -13,6 +13,8 @@ Requires(post): /usr/bin/chsmack
 BuildRequires:  boost-devel
 BuildRequires:  cmake
 BuildRequires:  gtest-devel
+BuildRequires:  pkgconfig(aul)
+BuildRequires:  pkgconfig(bundle)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
index 83f9b27058a3a21acb652da1f545505fbbf3c74e..018f9d5276b4908647e0585f541397cebaf6c1b3 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <functional>
 
+#include "common/capability.h"
 #include "common/capability_manager.h"
 #include "common/connection_manager.h"
 #include "common/dbus_service.h"
@@ -74,6 +75,11 @@ bool Capmgr::Initialize() {
   DBusService::RegisterMethodHandler("ExchangeCapabilities", std::bind(
       &ConnectionManager::ExchangeCapabilities, connmgr_.get()));
 
+  DBusService::RegisterSendAppcontrolHandler("SendRemoteAppControl", std::bind(
+      &ConnectionManager::SendCapability, connmgr_.get(),
+      std::placeholders::_1,
+      std::placeholders::_2));
+
   return true;
 }
 
index b1d15096532a29a20a3d6b25811b23d4b64c2073..db038cacfef3094ff7c82083c760d97ae9f5f18f 100644 (file)
@@ -8,6 +8,8 @@ ADD_LIBRARY(${TARGET_LIB_COMMON} SHARED
 )
 
 APPLY_PKG_CONFIG(${TARGET_LIB_COMMON} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
   DLOG_DEPS
   GIO_DEPS
   GLIB_DEPS
diff --git a/src/common/appcontrol_manager.cc b/src/common/appcontrol_manager.cc
new file mode 100644 (file)
index 0000000..1d39c9c
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "appcontrol_manager.h"
+
+#include <aul.h>
+#include <aul_svc.h>
+#include <bundle.h>
+
+#include "common/utils/logging.h"
+
+namespace capmgr {
+  int AppControlManager::LaunchApplication(const Capability& capability) {
+    int ret;
+
+    bundle* b = bundle_create();
+    aul_svc_set_operation(b, capability.name().c_str());
+
+    ret = aul_launch_app(capability.pkgid().c_str(), b);
+    if (ret < AUL_R_OK) {
+      LOG(ERROR) << "launch failed : " << ret;
+      bundle_free(b);
+      return ret;
+    }
+
+    bundle_free(b);
+    return 0;
+  }
+}  // namespace capmgr
index 8485268bca637c9a9fa60416d80c8160cb3800d0..f8f331738e9281a3f94f4b868d22e4a20ba0ba70 100644 (file)
@@ -7,12 +7,16 @@
 
 #include <glib.h>
 
+#include "common/capability.h"
+
 namespace capmgr {
 
 class AppControlManager {
  public:
   AppControlManager();
   ~AppControlManager();
+
+  static int LaunchApplication(const Capability& capability);
  private:
 };
 
index 9c822db106348d712530be2e3008ab55581d2ae3..e276509087e434e1c6af92e383cc011e915b9fce 100644 (file)
@@ -11,6 +11,7 @@
 #include <iostream>
 
 #include "common/capability.h"
+#include "common/dbus_service.h"
 #include "common/package_event_listener.h"
 #include "common/utils/logging.h"
 
@@ -75,13 +76,30 @@ int PkgListCb(const pkgmgrinfo_pkginfo_h handle, void* user_data) {
 
 namespace capmgr {
 
-CapabilityManager::CapabilityManager() {}
+CapabilityManager::CapabilityManager() {
+  DBusService::RegisterGetRemoteCapsHandler("GetRemoteCapabilities", std::bind(
+      &CapabilityManager::GetList, this, std::placeholders::_1));
+}
 CapabilityManager::~CapabilityManager() {}
 
 const std::vector<Capability>& CapabilityManager::GetCapabilities() const {
   return list_;
 }
 
+void CapabilityManager::GetList(GVariant **params) {
+  GVariantBuilder* builder;
+
+  builder = g_variant_builder_new (G_VARIANT_TYPE ("a(sss)"));
+  for (const auto& cap : list_) {
+    g_variant_builder_add (builder, "(sss)",
+        cap.name().c_str(),
+        cap.pkgid().c_str(),
+        cap.appid().c_str());
+  }
+  *params = g_variant_new ("a(sss)", builder);
+  g_variant_builder_unref (builder);
+}
+
 bool CapabilityManager::AddCapability(const Capability& capability) {
   list_.push_back(std::move(capability));
   return true;
index 4734a87e6de35acc3110e068ec3f755ea102af17..1bf216e7a831afb0777aa77cf989546619bfc0d7 100644 (file)
@@ -21,6 +21,7 @@ class CapabilityManager {
   ~CapabilityManager();
   const std::vector<Capability>& GetCapabilities() const;
   bool AddCapability(const Capability& capability);
+  void GetList(GVariant **params);
   bool ListCapabilities();
   bool LoadCapabilities();
   std::string PackCapabilities();
index 947ac65d2e10e58775ad79685f758c287ed6f9d5..be52a634bda60cab97e06d1cf3fc3622678bd359 100644 (file)
@@ -8,6 +8,7 @@
 namespace capmgr {
 
 class CapabilityManager;
+class Capability;
 
 class ConnectionManager {
  public:
@@ -16,6 +17,9 @@ class ConnectionManager {
   virtual void FindDevices() = 0;
   virtual void RegisterEndpoint() = 0;
   virtual void ExchangeCapabilities() = 0;
+  virtual bool SendCapability(
+                 Capability* cap,
+                 std::function<void(Capability, int)> reply) = 0;
 
  protected:
   CapabilityManager* capmgr_;
index 1528344868416886be80d6a9a5b9d5f570a7e2f6..a7cd587b6dd6c0263c7f94eb721875338661d278 100644 (file)
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "common/utils/logging.h"
+#include "common/capability.h"
 
 namespace {
 
@@ -23,7 +24,11 @@ const char kDBusInstropectionXml[] =
   "    <method name='ExchangeCapabilities'>"
   "      <arg type='b' name='result' direction='out'/>"
   "    </method>"
+  "    <method name='GetRemoteCapabilities'>"
+  "      <arg type='v' name='result' direction='out'/>"
+  "    </method>"
   "    <method name='SendRemoteAppControl'>"
+  "      <arg type='(sss)' name='appcontrol' direction='in'/>"
   "      <arg type='b' name='result' direction='out'/>"
   "    </method>"
   "  </interface>"
@@ -64,8 +69,18 @@ void DBusService::RegisterMethodHandler(const std::string& method,
     EventHandler().on_event.connect(handler);
   else if (method == "ExchangeCapabilities")
     EventHandler().on_event2.connect(handler);
-  else if (method == "SendRemoteAppControl")
-    EventHandler().on_event3.connect(handler);
+}
+
+void DBusService::RegisterSendAppcontrolHandler(const std::string& method,
+    std::function<bool(Capability*, std::function<void(Capability, int)>)> handler) {
+  if (method == "SendRemoteAppControl")
+    EventHandler().send_app_control_event.connect(handler);
+}
+
+void DBusService::RegisterGetRemoteCapsHandler(const std::string& method,
+    std::function<void(GVariant**)> handler) {
+  if (method == "GetRemoteCapabilities")
+    EventHandler().get_remote_caps_event.connect(handler);
 }
 
 bool DBusService::HandleDiscoverUnownedDevices(GVariant* params,
@@ -82,10 +97,34 @@ bool DBusService::HandleExchangeCapabilities(GVariant* params,
 
 bool DBusService::HandleSendRemoteAppControl(GVariant* params,
     GDBusMethodInvocation* invocation) {
-  EventHandler().on_event3();
+  LOG(INFO) << "HandleGetRemoteCapabilities ";
+  gchar* name;
+  gchar* appid;
+  gchar* pkgid;
+  g_variant_get(params, "((sss))", &name, &appid, &pkgid);
+
+  Capability cap(name, pkgid, appid);
+  LOG(INFO) << "From: " << cap.name();
+
+  EventHandler().send_app_control_event(&cap,
+      [=](Capability cap, int ret) {
+      LOG(INFO) << "RET: " << ret;
+
+      LOG(INFO) << "Success launch: " << cap.name();
+
+      g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", ret));
+      });
   return true;
 }
 
+void DBusService::HandleGetRemoteCapabilities(GVariant* params,
+    GDBusMethodInvocation* invocation) {
+  GVariant* temp;
+  EventHandler().get_remote_caps_event(&temp);
+
+  g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", temp));
+}
+
 void DBusService::HandleMethodCall(GDBusConnection* /* connection */,
     const gchar* /* sender */, const gchar* /* object_path */,
     const gchar* /* interface_name */, const gchar* method_name,
@@ -94,12 +133,21 @@ void DBusService::HandleMethodCall(GDBusConnection* /* connection */,
   bool r = false;
 
   LOG(INFO) << "Incomming method call: " << method_name;
-  if (g_strcmp0("DiscoverUnownedDevices", method_name) == 0)
+  if (g_strcmp0("DiscoverUnownedDevices", method_name) == 0) {
     r = HandleDiscoverUnownedDevices(parameters, invocation);
-  else if (g_strcmp0("ExchangeCapabilities", method_name) == 0)
+  }
+  else if (g_strcmp0("ExchangeCapabilities", method_name) == 0) {
     r = HandleExchangeCapabilities(parameters, invocation);
-  else if (g_strcmp0("SendRemoteAppControl", method_name) == 0)
-    r = HandleSendRemoteAppControl(parameters, invocation);
+  }
+  else if (g_strcmp0("GetRemoteCapabilities", method_name) == 0) {
+    HandleGetRemoteCapabilities(parameters, invocation);
+    return;
+  }
+  else if (g_strcmp0("SendRemoteAppControl", method_name) == 0) {
+    LOG(INFO) << " method call: " << method_name;
+    HandleSendRemoteAppControl(parameters, invocation);
+    return;
+  }
 
   g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", r));
 }
index 30121a31fdd32a66518981c5545c10ae8014e849..be480900fa3a09a7c0a14750f9fe716cf76badc0 100644 (file)
@@ -12,6 +12,8 @@
 
 namespace capmgr {
 
+class Capability;
+
 class DBusService {
  public:
   DBusService();
@@ -19,13 +21,18 @@ class DBusService {
 
   static void RegisterMethodHandler(const std::string& method,
       std::function<void()> handler);
+  static void RegisterSendAppcontrolHandler(const std::string& method,
+      std::function<bool(Capability*, std::function<void(Capability, int)>)> handler);
+  static void RegisterGetRemoteCapsHandler(const std::string& method,
+      std::function<void(GVariant**)> handler);
 
  private:
   class DBusMethodHandler {
    public:
     boost::signals2::signal<void()> on_event;
     boost::signals2::signal<void()> on_event2;
-    boost::signals2::signal<void()> on_event3;
+    boost::signals2::signal<bool(Capability*, std::function<void(Capability, int)>)> send_app_control_event;
+    boost::signals2::signal<void(GVariant**)> get_remote_caps_event;
   };
 
   static DBusMethodHandler& EventHandler() {
@@ -37,6 +44,8 @@ class DBusService {
       GDBusMethodInvocation* invocation);
   bool HandleExchangeCapabilities(GVariant* params,
       GDBusMethodInvocation* invocation);
+  void HandleGetRemoteCapabilities(GVariant* params,
+      GDBusMethodInvocation* invocation);
   bool HandleSendRemoteAppControl(GVariant* params,
       GDBusMethodInvocation* invocation);
 
index 6722280a4943338808b4a1d61d76d67ed9bf0ad1..5938e172c734961a5b7f0866cbd61def978f9839 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "common/capability.h"
 #include "common/capability_manager.h"
+#include "common/appcontrol_manager.h"
 #include "common/utils/logging.h"
 
 namespace {
@@ -90,7 +91,6 @@ Iotivity::Iotivity(CapabilityManager* capmgr) : ConnectionManager(capmgr) {
   result = OCPlatform::registerPlatformInfo(platformInfo);
 */
 }
-
 Iotivity::~Iotivity() {
 }
 
@@ -107,6 +107,37 @@ void Iotivity::ExchangeCapabilities() {
     GetResource(it.second);
 }
 
+bool Iotivity::SendCapability(Capability* cap, std::function<void(Capability, int)> reply) {
+  PutResource(cap, reply);
+  return 0;
+}
+
+void Iotivity::PutResource(Capability* cap, std::function<void(Capability, int)> putCallback) {
+    LOG(INFO) << "Put Resource";
+  for (std::map<OC::OCResourceIdentifier, std::shared_ptr<OC::OCResource>>::iterator it=resource_list_.begin(); it!=resource_list_.end(); ++it) {
+    std::shared_ptr<OC::OCResource> resource;
+    resource = it->second;
+    OC::OCRepresentation rep;
+
+    LOG(INFO) << "Putting.." << resource->uri();
+    rep.setValue("capability", cap->Serialize());
+
+    Capability dup(cap->name(), cap->pkgid(), cap->appid());
+    OC::QueryParamsMap queryParamsMap;
+    OCStackResult res = resource->put(rep, queryParamsMap,
+        [=](const OC::HeaderOptions& opts, const OC::OCRepresentation& rep,
+          const int ec) {
+        LOG(INFO) << "From: " << rep.getUri() << " of " << rep.getHost();
+        LOG(INFO) << "PUT RESULT data: " << ec;
+
+        putCallback(dup, ec);
+
+        });
+
+    LOG(INFO) << "res: " << res;
+  }
+}
+
 void Iotivity::RegisterResource() {
   std::string uri = "/capmgr/capabilities";
   uint8_t property = OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE;
@@ -163,7 +194,7 @@ void Iotivity::OwnershipTransfer() {
     sec_rsc->doOwnershipTransfer(
         [this, devaddr](OC::PMResultList_t* result, int hasError) {
           if (hasError) {
-            LOG(ERROR) << "Failed to ownership transfer";
+            LOG(ERROR) << "Failed to ownership transfer :: " << hasError;
             return;
           }
           LOG(INFO) << "Ownership transferred: "
@@ -208,30 +239,50 @@ OCEntityHandlerResult Iotivity::EntityCb(
   }
 
   std::string req_type = request->getRequestType();
-  if (req_type != "GET") {
-    LOG(WARNING) << "The request is not GET";
+  if (req_type == "GET") {
+    LOG(WARNING) << "The request is GET";
+
+    // OC::QueryParamsMap qmap = request->getQueryParameters();
+
+    OC::OCRepresentation rep;
+    rep.setUri("/capmgr/capabilities");
+    std::string capabilities = capmgr_->PackCapabilities();
+    rep.setValue("data", capabilities);
+
+    auto response = std::make_shared<OC::OCResourceResponse>();
+    response->setErrorCode(200);  // ??
+    response->setResponseResult(OC_EH_OK);
+    response->setResourceRepresentation(rep);
+    response->setRequestHandle(request->getRequestHandle());
+    response->setResourceHandle(request->getResourceHandle());
+
+    OCStackResult result = OC::OCPlatform::sendResponse(response);
+    if (result != OC_STACK_OK)
+      LOG(ERROR) << "OCPlatform::sendResponse() error: " << result;
+    else
+      LOG(INFO) << "Sending response done";
+
     return OC_EH_OK;
   }
 
-  // OC::QueryParamsMap qmap = request->getQueryParameters();
+  if (req_type == "PUT") {
+    LOG(WARNING) << "The request is PUT";
+    OC::OCRepresentation rep = request->getResourceRepresentation();
+    int ret;
 
-  OC::OCRepresentation rep;
-  rep.setUri("/capmgr/capabilities");
-  std::string capabilities = capmgr_->PackCapabilities();
-  rep.setValue("data", capabilities);
+    std::string cap_data;
+    rep.getValue("capability", cap_data);
+    LOG(INFO) << "capability : " << cap_data;
 
-  auto response = std::make_shared<OC::OCResourceResponse>();
-  response->setErrorCode(200);  // ??
-  response->setResponseResult(OC_EH_OK);
-  response->setResourceRepresentation(rep);
-  response->setRequestHandle(request->getRequestHandle());
-  response->setResourceHandle(request->getResourceHandle());
+    Capability cap(cap_data);
 
-  OCStackResult result = OC::OCPlatform::sendResponse(response);
-  if (result != OC_STACK_OK)
-    LOG(ERROR) << "OCPlatform::sendResponse() error: " << result;
-  else
-    LOG(INFO) << "Sending response done";
+    ret = AppControlManager::LaunchApplication(cap);
+    if (ret != 0) {
+      return OC_EH_ERROR;
+    }
+
+    return OC_EH_OK;
+  }
 
   return OC_EH_OK;
 }
index 9de873cfb90a65b5b191f02f05762a225d404845..293d45a6c16e39a1ce910bc41e8356e12c79b57b 100644 (file)
@@ -29,10 +29,12 @@ class Iotivity : public ConnectionManager {
   void FindDevices() override;
   void RegisterEndpoint() override;
   void ExchangeCapabilities() override;
+  bool SendCapability(Capability* cap, std::function<void(Capability, int)> reply) override;
 
  private:
   void RegisterResource();
   void FindResource(const std::string& addr);
+  void PutResource(Capability* cap, std::function<void(Capability, int)> putCallback);
   void DiscoverUnownedDevices();
   void OwnershipTransfer();
   void GetResource(std::shared_ptr<OC::OCResource> resource);