[AT-SPI] Add Bridge::{Embed,Unembed}Socket() 12/263212/16
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 21 Apr 2022 15:48:04 +0000 (17:48 +0200)
committerArtur Świgoń <a.swigon@samsung.com>
Thu, 12 May 2022 10:56:30 +0000 (12:56 +0200)
This patch adds three new utility methods to Bridge:

* EmbedSocket() - calls org.a11y.atspi.Socket.Embed

The manually contstructed D-Bus call in Bridge::ForceUp()
is replaced by EmbedSocket().

* UnembedSocket() - calls org.a11y.atspi.Socket.Unembed

A missing UnembedSocket() is added in Bridge::ForceDown().

* EmbedAtkSocket() - calls org.a11y.atspi.Socket.Embedded

The "Embedded" method is an ATK extension, but is required
to embed an ATK-based subtree, e.g. a Chromium-based WebView,
in a DALi application.

Change-Id: I562072864d6a67272325562eabb91962c6813eab

dali/devel-api/adaptor-framework/accessibility-bridge.h
dali/internal/accessibility/bridge/bridge-impl.cpp
dali/internal/accessibility/bridge/dummy-atspi.h

index db09b45..1b59436 100644 (file)
@@ -366,6 +366,41 @@ struct DALI_ADAPTOR_API Bridge
   virtual bool IsEnabled() = 0;
 
   /**
+   * @brief Calls socket.Embed(plug) via D-Bus.
+   *
+   * @param[in] plug The plug
+   * @param[in] socket The socket
+   *
+   * @return Address returned by the D-Bus call.
+   *
+   * @note Remote object pointed to by 'socket' must implement 'org.a11y.atspi.Socket'.
+   * @see UnembedSocket()
+   */
+  virtual Address EmbedSocket(const Address& plug, const Address& socket) = 0;
+
+  /**
+   * @brief Calls socket.Embedded(plug) via D-Bus.
+   *
+   * The "Embedded" D-Bus method is an ATK extension.
+   * See 'impl_Embedded' in AT_SPI2_ATK/atk-adaptor/adaptors/socket-adaptor.c for more information.
+   *
+   * @param[in] plug The plug
+   * @param[in] socket The socket
+   */
+  virtual void EmbedAtkSocket(const Address& plug, const Address& socket) = 0;
+
+  /**
+   * @brief Calls socket.Unmbed(plug) via D-Bus.
+   *
+   * @param[in] plug The plug
+   * @param[in] socket The socket
+   *
+   * @note Remote object pointed to by 'socket' must implement 'org.a11y.atspi.Socket'.
+   * @see EmbedSocket()
+   */
+  virtual void UnembedSocket(const Address& plug, const Address& socket) = 0;
+
+  /**
    * @brief Returns instance of bridge singleton object.
    *
    * @return The current bridge object
index c48240c..551a89a 100644 (file)
@@ -227,7 +227,9 @@ public:
       mData->mHighlightActor            = {};
 
       mDisabledSignal.Emit();
+      UnembedSocket(mApplication.GetAddress(), {AtspiDbusNameRegistry, "root"});
     }
+
     mHighlightedActor     = {};
     mHighlightClearAction = {};
     BridgeAccessible::ForceDown();
@@ -351,17 +353,8 @@ public:
       }
     });
 
-    auto    proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, Accessible::GetInterfaceName(AtspiInterface::SOCKET), mConnectionPtr};
-    Address root{"", "root"};
-    auto    res = proxy.method<Address(Address)>("Embed").call(root);
-    if(!res)
-    {
-      LOG() << "Call to Embed failed: " << res.getError().message;
-    }
-    assert(res);
-
-    mApplication.mParent.SetAddress(std::move(std::get<0>(res)));
-
+    auto parentAddress = EmbedSocket(mApplication.GetAddress(), {AtspiDbusNameRegistry, "root"});
+    mApplication.mParent.SetAddress(std::move(parentAddress));
     mEnabledSignal.Emit();
 
     return ForceUpResult::JUST_STARTED;
@@ -693,6 +686,40 @@ public:
   {
     return mIsEnabled;
   }
+
+  Address EmbedSocket(const Address& plug, const Address& socket) override
+  {
+    auto client = CreateSocketClient(socket);
+    auto reply  = client.method<Address(Address)>("Embed").call(plug);
+
+    if(!reply)
+    {
+      DALI_LOG_ERROR("Failed to embed socket %s: %s", socket.ToString().c_str(), reply.getError().message.c_str());
+      return {};
+    }
+
+    return std::get<0>(reply.getValues());
+  }
+
+  void EmbedAtkSocket(const Address& plug, const Address& socket) override
+  {
+    auto client = CreateSocketClient(socket);
+
+    client.method<void(std::string)>("Embedded").call(ATSPI_PREFIX_PATH + plug.GetPath());
+  }
+
+  void UnembedSocket(const Address& plug, const Address& socket) override
+  {
+    auto client = CreateSocketClient(socket);
+
+    client.method<void(Address)>("Unembed").call(plug);
+  }
+
+private:
+  DBus::DBusClient CreateSocketClient(const Address& socket)
+  {
+    return {socket.GetBus(), ATSPI_PREFIX_PATH + socket.GetPath(), Accessible::GetInterfaceName(AtspiInterface::SOCKET), mConnectionPtr};
+  }
 }; // BridgeImpl
 
 namespace // unnamed namespace
index b8cbc03..911b9da 100644 (file)
@@ -180,6 +180,19 @@ struct DummyBridge : Dali::Accessibility::Bridge
   {
     return false;
   }
+
+  Address EmbedSocket(const Address& plug, const Address& socket) override
+  {
+    return {};
+  }
+
+  void EmbedAtkSocket(const Address& plug, const Address& socket) override
+  {
+  }
+
+  void UnembedSocket(const Address& plug, const Address& socket) override
+  {
+  }
 };
 
 } // namespace Dali::Accessibility