Watch rpc port and handle stub app lifecycle 75/167275/11
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 16 Jan 2018 14:13:29 +0000 (23:13 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 30 Jan 2018 02:09:41 +0000 (11:09 +0900)
Before sending a connection request, a proxy watches a dbus interface
for registering it.
When a stub is getting disconnected event, the stub notifies it to
the amd for background management feature.

Change-Id: I50544ec188bf5f8e2907f35dd926aa944373ee1d
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/fdbroker-internal.cc
src/fdbroker-internal.h
src/proxy-internal.cc
src/proxy-internal.h
src/stub-internal.cc

index 26c08f3..451ab34 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <aul.h>
+#include <aul_rpc_port.h>
 #include <dlog.h>
 
 #include "fdbroker-internal.h"
@@ -114,6 +115,13 @@ int FdBroker::DBusMock::AddListener(const std::string& port,
   return 0;
 }
 
+int FdBroker::DBusMock::Watch(FdBroker::IEventWatcher* watcher,
+                              const std::string& target_appid,
+                              const std::string& port_name) {
+  watcher->OnPortAppeared(target_appid, port_name);
+  return 0;
+}
+
 void FdBroker::DBusMock::Dispose() {
   ports_.clear();
 }
@@ -136,7 +144,7 @@ int FdBroker::SocketPair::Request() {
     return socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, socks_);
   }
 
-  if (aul_request_message_port_socket_pair(socks_) != AUL_R_OK) {
+  if (aul_rpc_port_create_socket_pair(&socks_) != AUL_R_OK) {
     LOGE("error create socket pair");
     return -1;
   }
@@ -183,6 +191,9 @@ GUnixFDList* FdBroker::FdList::GetRaw() {
 }
 
 FdBroker::~FdBroker() {
+  if (watcher_id_ > 0)
+    g_bus_unwatch_name(watcher_id_);
+
   if (registration_id_ > 0) {
     g_dbus_connection_unregister_object(
         DBusConnectionManager::GetInst().GetConnection(),
@@ -464,5 +475,71 @@ AccessController& FdBroker::GetAccessController() {
   return ac_;
 }
 
+void FdBroker::OnNameAppeared(GDBusConnection *connection,
+                              const gchar *name,
+                              const gchar *name_owner,
+                              gpointer user_data) {
+  FdBroker* broker = static_cast<FdBroker*>(user_data);
+  broker->watcher_->OnPortAppeared(broker->watch_appid_,
+      broker->watch_port_name_);
+}
+
+void FdBroker::OnNameVanished(GDBusConnection *connection,
+                              const gchar *name,
+                              gpointer user_data) {
+  FdBroker* broker = static_cast<FdBroker*>(user_data);
+  broker->watcher_->OnPortVanished(broker->watch_appid_,
+      broker->watch_port_name_);
+}
+
+int FdBroker::Watch(IEventWatcher* ev, const std::string& target_appid,
+                    const std::string& port_name) {
+  int r;
+
+  if (watcher_ != nullptr)
+    return -1;
+
+  if (ev == nullptr)
+    return -1;
+
+  if (!mock_) {
+    r = aul_rpc_port_prepare_stub(target_appid.c_str(), port_name.c_str());
+    if (r != AUL_R_OK) {
+      LOGE("Failed to prepare stub %s:%s",
+          target_appid.c_str(), port_name.c_str());
+      return -1;
+    }
+  }
+
+  watcher_ = ev;
+  watch_appid_ = target_appid;
+  watch_port_name_ = port_name;
+
+  if (mock_) {
+    r = DBusMock::GetInst().Watch(ev, target_appid, port_name);
+    if (r < 0)
+      return -1;
+
+    return 0;
+  }
+
+  std::string interface_name = GetInterfaceName(target_appid, port_name);
+  watcher_id_ = g_bus_watch_name_on_connection(
+      DBusConnectionManager::GetInst().GetConnection(),
+      interface_name.c_str(),
+      G_BUS_NAME_WATCHER_FLAGS_NONE,
+      OnNameAppeared,
+      OnNameVanished,
+      this,
+      NULL);
+  if (watcher_id_ == 0) {
+    LOGE("Failed to watch connection(%s)", interface_name.c_str());
+    watcher_ = nullptr;
+    return -1;
+  }
+
+  return 0;
+}
+
 }  // namespace internal
 }  // namespace rpc_port
index d1f31b7..77ff32d 100644 (file)
@@ -38,6 +38,14 @@ class FdBroker {
     virtual void OnFdReceived(const std::string& sender, int fd) = 0;
   };
 
+  class IEventWatcher {
+   public:
+    virtual void OnPortAppeared(const std::string& appid,
+                                const std::string& port_name) = 0;
+    virtual void OnPortVanished(const std::string& appid,
+                                const std::string& port_name) = 0;
+  };
+
   FdBroker(bool mock = false) : mock_(mock) {}
   ~FdBroker();
 
@@ -48,6 +56,8 @@ class FdBroker {
   int Send(const std::string& target_appid, const std::string& port_name);
   int Listen(IEventListener* ev, const std::string& port_name);
   AccessController& GetAccessController();
+  int Watch(IEventWatcher* ev, const std::string& target_appid,
+            const std::string& port_name);
 
  private:
   class DBusConnectionManager {
@@ -80,6 +90,8 @@ class FdBroker {
     int Send(const std::string& sender, const std::string& port, int fd);
     int AddListener(const std::string& port,
                     FdBroker::IEventListener* listener);
+    int Watch(FdBroker::IEventWatcher* watcher, const std::string& target_appid,
+              const std::string& port_name);
     void Dispose();
 
    private:
@@ -135,12 +147,23 @@ class FdBroker {
   void ReceiveMessage(GVariant* parameters, GDBusMethodInvocation* invocation);
   std::string GetInterfaceName(const std::string& target_appid,
                                const std::string& port_name);
+  static void OnNameAppeared(GDBusConnection *connection,
+                             const gchar *name,
+                             const gchar *name_owner,
+                             gpointer user_data);
+  static void OnNameVanished(GDBusConnection *connection,
+                             const gchar *name,
+                             gpointer user_data);
 
  private:
   IEventListener* listener_ = nullptr;
   int registration_id_ = 0;
   bool mock_;
   AccessController ac_;
+  IEventWatcher* watcher_ = nullptr;
+  guint watcher_id_ = 0;
+  std::string watch_appid_;
+  std::string watch_port_name_;
 };
 
 }  // namespace internal
index 5c8f592..82fae45 100644 (file)
@@ -115,16 +115,14 @@ int Proxy::Watch(int fd) {
   return 0;
 }
 
-void Proxy::Connect(const std::string appid, const std::string& port_name,
-                    IEventListener* ev) {
-  if (ev == nullptr || listener_ != nullptr)
+void Proxy::OnPortAppeared(const std::string& appid,
+                           const std::string& port_name) {
+  LOGD("endpoint(%s), port_name(%s)", appid.c_str(), port_name.c_str());
+
+  if (listener_ == nullptr)
     return;
 
-  listener_ = ev;
-  target_appid_ = appid;
-  port_name_ = port_name;
   int fd = fd_broker_.Send(appid, port_name);
-
   if (fd <= 0) {
     listener_->OnRejected(appid);
     listener_ = nullptr;
@@ -136,5 +134,23 @@ void Proxy::Connect(const std::string appid, const std::string& port_name,
   Watch(fd);
 }
 
+void Proxy::OnPortVanished(const std::string& appid,
+                           const std::string& port_name) {
+  LOGD("endpoint(%s), port_name(%s)", appid.c_str(), port_name.c_str());
+}
+
+void Proxy::Connect(const std::string appid, const std::string& port_name,
+                    IEventListener* ev) {
+  if (ev == nullptr || listener_ != nullptr)
+    return;
+
+  listener_ = ev;
+  target_appid_ = appid;
+  port_name_ = port_name;
+  int r = fd_broker_.Watch(this, appid, port_name);
+  if (r < 0)
+    listener_ = nullptr;
+}
+
 }  // namespace internal
-}  // namespace rpc_port
\ No newline at end of file
+}  // namespace rpc_port
index 3fe0f13..7c12f9c 100644 (file)
@@ -30,7 +30,7 @@
 namespace rpc_port {
 namespace internal {
 
-class Proxy {
+class Proxy : public FdBroker::IEventWatcher {
  public:
   Proxy(bool mock = false);
   virtual ~Proxy();
@@ -59,6 +59,10 @@ class Proxy {
   static gboolean OnDataReceived(GIOChannel *gio, GIOCondition cond,
                                  gpointer data);
   int Watch(int fd);
+  void OnPortAppeared(const std::string& appid,
+                      const std::string& port_name) override;
+  void OnPortVanished(const std::string& appid,
+                      const std::string& port_name) override;
 
  private:
   std::string port_name_;
index cff9295..994195b 100644 (file)
@@ -21,6 +21,8 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <dlog.h>
+#include <aul.h>
+#include <aul_rpc_port.h>
 
 #include "stub-internal.h"
 
@@ -65,6 +67,10 @@ gboolean Stub::OnDataReceived(GIOChannel *gio, GIOCondition cond,
         LOGW("Socket was disconnected from proxy");
         stub->listener_->OnDisconnected(p->GetId());
         stub->ports_.remove(p);
+
+        if (aul_rpc_port_notify_rpc_finished() != AUL_R_OK)
+          LOGW("Failed to notify rpc finished");
+
         return FALSE;
       }
 
@@ -74,6 +80,10 @@ gboolean Stub::OnDataReceived(GIOChannel *gio, GIOCondition cond,
         LOGW("Invalid protocol");
         stub->listener_->OnDisconnected(p->GetId());
         stub->ports_.remove(p);
+
+        if (aul_rpc_port_notify_rpc_finished() != AUL_R_OK)
+          LOGW("Failed to notify rpc finished");
+
         return FALSE;
       }
 
@@ -98,6 +108,9 @@ gboolean Stub::OnSocketDisconnected(GIOChannel *gio, GIOCondition cond,
     }
   }
 
+  if (aul_rpc_port_notify_rpc_finished() != AUL_R_OK)
+    LOGW("Failed to notify rpc finished");
+
   return FALSE;
 }