[ATSPI] Initialize Bridge on Idler 75/264375/4
authorShinwoo Kim <cinoo.kim@samsung.com>
Thu, 16 Sep 2021 12:30:45 +0000 (21:30 +0900)
committerShinwoo Kim <cinoo.kim@samsung.com>
Fri, 17 Sep 2021 01:52:27 +0000 (10:52 +0900)
There is an application launching before dbus.
In this case application cannot use ATSPI interface.
Because the Bridge cannot get a dbus connection.

We prepared BridgeDisableAutoInit.
But someone does not want to make application change.

This patch is providing a way to initialize the Bridge
for an application launching before dbus.

Change-Id: Ic254f8e001c3d4f198b0a7bb680e5c5792b818cd

dali/internal/accessibility/bridge/bridge-impl.cpp
dali/internal/accessibility/bridge/dbus-tizen.cpp
dali/internal/adaptor/common/adaptor-impl.cpp

index aaed7fb..9724368 100644 (file)
@@ -55,7 +55,7 @@ class BridgeImpl : public virtual BridgeBase,
                    public BridgeSelection,
                    public BridgeApplication
 {
-  DBus::DBusClient                                              listenOnAtspiEnabledSignalClient;
+  DBus::DBusClient                                              accessibilityStatusClient;
   DBus::DBusClient                                              registryClient, directReadingClient;
   bool                                                          screenReaderEnabled = false;
   bool                                                          isEnabled           = false;
@@ -63,35 +63,11 @@ class BridgeImpl : public virtual BridgeBase,
   std::unordered_map<int32_t, std::function<void(std::string)>> directReadingCallbacks;
   Dali::Actor                                                   highlightedActor;
   std::function<void(Dali::Actor)>                              highlightClearAction;
+  Dali::CallbackBase* mIdleCallback = NULL;
 
 public:
   BridgeImpl()
   {
-    listenOnAtspiEnabledSignalClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION};
-
-    listenOnAtspiEnabledSignalClient.addPropertyChangedEvent<bool>("ScreenReaderEnabled", [this](bool res) {
-      screenReaderEnabled = res;
-      if(screenReaderEnabled || isEnabled)
-      {
-        ForceUp();
-      }
-      else
-      {
-        ForceDown();
-      }
-    });
-
-    listenOnAtspiEnabledSignalClient.addPropertyChangedEvent<bool>("IsEnabled", [this](bool res) {
-      isEnabled = res;
-      if(screenReaderEnabled || isEnabled)
-      {
-        ForceUp();
-      }
-      else
-      {
-        ForceDown();
-      }
-    });
   }
 
   Consumed Emit(KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) override
@@ -226,7 +202,11 @@ public:
       mData->mHighlightActor            = {};
     }
     ForceDown();
-    listenOnAtspiEnabledSignalClient = {};
+    if((NULL != mIdleCallback) && Dali::Adaptor::IsAvailable())
+    {
+      Dali::Adaptor::Get().RemoveIdle(mIdleCallback);
+    }
+    accessibilityStatusClient        = {};
     dbusServer                       = {};
     con                              = {};
   }
@@ -315,25 +295,93 @@ public:
     isShown = true;
   }
 
-  void Initialize() override
+  void ReadAndListenProperty()
   {
-    auto dbusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION};
-    auto enabled = dbusClient.property<bool>("ScreenReaderEnabled").get();
+    // read property
+    auto enabled = accessibilityStatusClient.property<bool>("ScreenReaderEnabled").get();
     if(enabled)
     {
       screenReaderEnabled = std::get<0>(enabled);
     }
-
-    enabled = dbusClient.property<bool>("IsEnabled").get();
+    enabled = accessibilityStatusClient.property<bool>("IsEnabled").get();
     if(enabled)
     {
       isEnabled = std::get<0>(enabled);
     }
-
     if(screenReaderEnabled || isEnabled)
     {
       ForceUp();
     }
+
+    // listen property change
+    accessibilityStatusClient.addPropertyChangedEvent<bool>("ScreenReaderEnabled", [this](bool res) {
+      screenReaderEnabled = res;
+      if(screenReaderEnabled || isEnabled)
+      {
+        ForceUp();
+      }
+      else
+      {
+        ForceDown();
+      }
+    });
+
+    accessibilityStatusClient.addPropertyChangedEvent<bool>("IsEnabled", [this](bool res) {
+      isEnabled = res;
+      if(screenReaderEnabled || isEnabled)
+      {
+        ForceUp();
+      }
+      else
+      {
+        ForceDown();
+      }
+    });
+  }
+
+  bool InitializeAccessibilityStatusClient()
+  {
+    accessibilityStatusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION};
+
+    if (!accessibilityStatusClient)
+    {
+      DALI_LOG_ERROR("Accessibility Status DbusClient is not ready\n");
+      return false;
+    }
+
+    return true;
+  }
+
+  bool OnIdleSignal()
+  {
+    if ( InitializeAccessibilityStatusClient() )
+    {
+      ReadAndListenProperty();
+      mIdleCallback = NULL;
+      return false;
+    }
+
+    return true;
+  }
+
+  void Initialize() override
+  {
+    if ( InitializeAccessibilityStatusClient() )
+    {
+      ReadAndListenProperty();
+      return;
+    }
+
+    // Initialize failed. Try it again on Idle
+    if( Dali::Adaptor::IsAvailable() )
+    {
+      Dali::Adaptor& adaptor = Dali::Adaptor::Get();
+      if( NULL == mIdleCallback )
+      {
+        mIdleCallback = MakeCallback( this, &BridgeImpl::OnIdleSignal );
+        adaptor.AddIdle( mIdleCallback, true );
+      }
+    }
   }
 
   bool GetScreenReaderEnabled()
index cc2a45c..bbb265d 100644 (file)
@@ -110,9 +110,12 @@ DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::str
   else
     connectionState->connection = conn;
 
-  std::ostringstream o;
-  o << "bus = " << busName << " path = " << pathName << " connection = " << DBUS_W->eldbus_connection_unique_name_get_impl(connectionState->connection);
-  info = o.str();
+
+  if (!connectionState->connection)
+  {
+    DALI_LOG_ERROR("DBusClient connection is not ready\n");
+    return;
+  }
 
   connectionState->object = DBUS_W->eldbus_object_get_impl(connectionState->connection, busName.c_str(), pathName.c_str());
   if(connectionState->object)
@@ -511,10 +514,13 @@ struct DefaultDBusWrapper : public DBusWrapper
       }
     }
 
-    eldbus_init();
     auto p = eldbus_connection_get(eldbusType);
+    if (!p)
+    {
+      DALI_LOG_ERROR("cannot get dbus connection\n");
+      return NULL;
+    }
     auto w = create(p, true);
-    eldbus_shutdown();
     return w;
   }
 
index 831b75c..e787668 100644 (file)
@@ -308,12 +308,6 @@ void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
   }
 
   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
-
-  auto appName = GetApplicationPackageName();
-  auto bridge  = Accessibility::Bridge::GetCurrentBridge();
-  bridge->SetApplicationName(appName);
-  bridge->Initialize();
-  Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
 }
 
 void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
@@ -390,6 +384,13 @@ void Adaptor::Start()
   // Start the callback manager
   mCallbackManager->Start();
 
+  // Initialize accessibility bridge after callback manager is started to use Idler callback
+  auto appName = GetApplicationPackageName();
+  auto bridge  = Accessibility::Bridge::GetCurrentBridge();
+  bridge->SetApplicationName(appName);
+  bridge->Initialize();
+  Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
+
   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
 
   unsigned int dpiHor, dpiVer;