[AT-SPI] Add API for blocking automatic Bridge initialization 59/256959/2
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 15 Apr 2021 09:53:25 +0000 (11:53 +0200)
committerArtur Świgoń <a.swigon@samsung.com>
Tue, 27 Apr 2021 08:12:27 +0000 (10:12 +0200)
Change-Id: Iee34ae36bc5778e610a01da5b96e2ecf5408bcf9

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

index 7f1faae..7d4b9f9 100644 (file)
@@ -268,6 +268,37 @@ struct DALI_ADAPTOR_API Bridge
    **/
   static Bridge* GetCurrentBridge();
 
+  /**
+   * @brief Blocks auto-initialization of AT-SPI bridge
+   *
+   * Use this only if your application starts before DBus does, and call it early in main()
+   * (before GetCurrentBridge() is called by anyone). GetCurrentBridge() will then return an
+   * instance of DummyBridge.
+   *
+   * When DBus is ready, call EnableAutoInit(). Please note that GetCurrentBridge() may still
+   * return an instance of DummyBridge if AT-SPI was disabled at compile time or using an
+   * environment variable, or if creating the real bridge failed.
+   *
+   * @see Dali::Accessibility::DummyBridge
+   * @see Dali::Accessibility::Bridge::EnableAutoInit
+   */
+  static void DisableAutoInit();
+
+  /**
+   * @brief Re-enables auto-initialization of AT-SPI bridge
+   *
+   * @param topLevelWindow Accessible object for Scene::GetRootLayer()
+   * @param applicationName Application name
+   *
+   * Normal applications do not have to call this function. GetCurrentBridge() tries to
+   * initialize the AT-SPI bridge when it is called for the first time.
+   *
+   * @see Dali::Accessibility::Bridge::DisableAutoInit
+   * @see Dali::Accessibility::Bridge::AddTopLevelWindow
+   * @see Dali::Accessibility::Bridge::SetApplicationName
+   */
+  static void EnableAutoInit(Accessible* topLevelWindow, const std::string& applicationName);
+
 protected:
   struct Data
   {
@@ -279,6 +310,13 @@ protected:
   std::shared_ptr<Data> data;
   friend class Accessible;
 
+  enum class AutoInitState
+  {
+    DISABLED,
+    ENABLED
+  };
+  inline static AutoInitState autoInitState = AutoInitState::ENABLED;
+
   /**
    * @brief Registers accessible object to be known in bridge object
    *
index b3ec24d..49b2edc 100644 (file)
@@ -335,8 +335,12 @@ public:
   }
 };
 
+static bool bridgeInitialized;
+
 static Bridge* CreateBridge()
 {
+  bridgeInitialized = true;
+
   try
   {
     /* check environment variable first */
@@ -357,6 +361,42 @@ static Bridge* CreateBridge()
 
 Bridge* Bridge::GetCurrentBridge()
 {
-  static Bridge* bridge = CreateBridge();
-  return bridge;
+  static Bridge* bridge;
+
+  if (bridge)
+  {
+    return bridge;
+  }
+  else if (autoInitState == AutoInitState::ENABLED)
+  {
+    bridge = CreateBridge();
+    return bridge;
+  }
+
+  return Dali::Accessibility::DummyBridge::GetInstance();
+}
+
+void Bridge::DisableAutoInit()
+{
+  if (bridgeInitialized)
+  {
+    DALI_LOG_ERROR("Bridge::DisableAutoInit() called after bridge auto-initialization");
+  }
+
+  autoInitState = AutoInitState::DISABLED;
+}
+
+void Bridge::EnableAutoInit(Accessible* topLevelWindow, const std::string& applicationName)
+{
+  autoInitState = AutoInitState::ENABLED;
+
+  if (bridgeInitialized)
+  {
+    return;
+  }
+
+  auto* bridge = Bridge::GetCurrentBridge();
+  bridge->AddTopLevelWindow(topLevelWindow);
+  bridge->SetApplicationName(applicationName);
+  bridge->Initialize();
 }
index 8eec6b8..cd7dbec 100644 (file)
@@ -75,6 +75,14 @@ Accessibility::Bridge* Accessibility::Bridge::GetCurrentBridge()
   return Accessibility::DummyBridge::GetInstance();
 }
 
+void Accessibility::Bridge::DisableAutoInit()
+{
+}
+
+void Accessibility::Bridge::EnableAutoInit(Accessible*, const std::string&)
+{
+}
+
 void Accessibility::Accessible::EmitStateChanged(Accessibility::State state, int newValue1, int newValue2)
 {
 }