[AT-SPI] do not keep window in ApplicationAccessible
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-impl.cpp
index 19d519a..0cf7d17 100644 (file)
@@ -36,6 +36,7 @@
 #include <dali/internal/accessibility/bridge/bridge-hyperlink.h>
 #include <dali/internal/accessibility/bridge/bridge-object.h>
 #include <dali/internal/accessibility/bridge/bridge-selection.h>
+#include <dali/internal/accessibility/bridge/bridge-socket.h>
 #include <dali/internal/accessibility/bridge/bridge-text.h>
 #include <dali/internal/accessibility/bridge/bridge-value.h>
 #include <dali/internal/accessibility/bridge/bridge-application.h>
@@ -67,7 +68,8 @@ class BridgeImpl : public virtual BridgeBase,
                    public BridgeSelection,
                    public BridgeApplication,
                    public BridgeHypertext,
-                   public BridgeHyperlink
+                   public BridgeHyperlink,
+                   public BridgeSocket
 {
   DBus::DBusClient                                              mAccessibilityStatusClient;
   DBus::DBusClient                                              mRegistryClient;
@@ -82,6 +84,7 @@ class BridgeImpl : public virtual BridgeBase,
   Dali::Timer                                                   mInitializeTimer;
   Dali::Timer                                                   mReadIsEnabledTimer;
   Dali::Timer                                                   mReadScreenReaderEnabledTimer;
+  Dali::Timer                                                   mForceUpTimer;
 
 public:
   BridgeImpl()
@@ -141,7 +144,7 @@ public:
     mDirectReadingClient.method<DBus::ValueOrError<void>(bool)>("PauseResume").asyncCall([](DBus::ValueOrError<void> msg) {
       if(!msg)
       {
-        LOG() << "Direct reading command failed (" << msg.getError().message << ")";
+        LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
       }
     },
                                                                                         true);
@@ -160,7 +163,7 @@ public:
     mDirectReadingClient.method<DBus::ValueOrError<void>(bool)>("PauseResume").asyncCall([](DBus::ValueOrError<void> msg) {
       if(!msg)
       {
-        LOG() << "Direct reading command failed (" << msg.getError().message << ")";
+        LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
       }
     },
                                                                                         false);
@@ -179,7 +182,7 @@ public:
     mDirectReadingClient.method<DBus::ValueOrError<void>(bool)>("StopReading").asyncCall([](DBus::ValueOrError<void> msg) {
       if(!msg)
       {
-        LOG() << "Direct reading command failed (" << msg.getError().message << ")";
+        LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
       }
     },
                                                                                         alsoNonDiscardable);
@@ -198,7 +201,7 @@ public:
     mDirectReadingClient.method<DBus::ValueOrError<std::string, bool, int32_t>(std::string, bool)>("ReadCommand").asyncCall([=](DBus::ValueOrError<std::string, bool, int32_t> msg) {
       if(!msg)
       {
-        LOG() << "Direct reading command failed (" << msg.getError().message << ")";
+        LOG() << "Direct reading command failed (" << msg.getError().message << ")\n";
       }
       else if(callback)
       {
@@ -232,24 +235,33 @@ public:
     mDirectReadingClient  = {};
     mDirectReadingCallbacks.clear();
     mApplication.mChildren.clear();
-    mApplication.mWindows.clear();
+    ClearTimer();
   }
 
-  void StopTimer()
+  void ClearTimer()
   {
     if(mInitializeTimer)
     {
       mInitializeTimer.Stop();
+      mInitializeTimer.Reset();
     }
 
     if(mReadIsEnabledTimer)
     {
       mReadIsEnabledTimer.Stop();
+      mReadIsEnabledTimer.Reset();
     }
 
     if(mReadScreenReaderEnabledTimer)
     {
       mReadScreenReaderEnabledTimer.Stop();
+      mReadScreenReaderEnabledTimer.Reset();
+    }
+
+    if(mForceUpTimer)
+    {
+      mForceUpTimer.Stop();
+      mForceUpTimer.Reset();
     }
   }
 
@@ -264,7 +276,6 @@ public:
       mData->mHighlightActor            = {};
     }
     ForceDown();
-    StopTimer();
     if((NULL != mIdleCallback) && Dali::Adaptor::IsAvailable())
     {
       Dali::Adaptor::Get().RemoveIdle(mIdleCallback);
@@ -274,14 +285,34 @@ public:
     mConnectionPtr                    = {};
   }
 
+  bool ForceUpTimerCallback()
+  {
+    if(ForceUp() != ForceUpResult::FAILED)
+    {
+      return false;
+    }
+    return true;
+  }
+
   /**
    * @copydoc Dali::Accessibility::Bridge::ForceUp()
    */
   ForceUpResult ForceUp() override
   {
-    if(BridgeAccessible::ForceUp() == ForceUpResult::ALREADY_UP)
+    auto forceUpResult = BridgeAccessible::ForceUp();
+    if(forceUpResult == ForceUpResult::ALREADY_UP)
+    {
+      return forceUpResult;
+    }
+    else if(forceUpResult == ForceUpResult::FAILED)
     {
-      return ForceUpResult::ALREADY_UP;
+      if(!mForceUpTimer)
+      {
+        mForceUpTimer = Dali::Timer::New(RETRY_INTERVAL);
+        mForceUpTimer.TickSignal().Connect(this, &BridgeImpl::ForceUpTimerCallback);
+        mForceUpTimer.Start();
+      }
+      return forceUpResult;
     }
 
     BridgeObject::RegisterInterfaces();
@@ -296,10 +327,11 @@ public:
     BridgeApplication::RegisterInterfaces();
     BridgeHypertext::RegisterInterfaces();
     BridgeHyperlink::RegisterInterfaces();
+    BridgeSocket::RegisterInterfaces();
 
     RegisterOnBridge(&mApplication);
 
-    mRegistryClient      = {AtspiDbusNameRegistry, AtspiDbusPathDec, AtspiDbusInterfaceDec, mConnectionPtr};
+    mRegistryClient      = {AtspiDbusNameRegistry, AtspiDbusPathDec, Accessible::GetInterfaceName(AtspiInterface::DEVICE_EVENT_CONTROLLER), mConnectionPtr};
     mDirectReadingClient = DBus::DBusClient{DirectReadingDBusName, DirectReadingDBusPath, DirectReadingDBusInterface, mConnectionPtr};
 
     mDirectReadingClient.addSignal<void(int32_t, std::string)>("ReadingStateChanged", [=](int32_t id, std::string readingState) {
@@ -314,7 +346,7 @@ public:
       }
     });
 
-    auto    proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, AtspiDbusInterfaceSocket, mConnectionPtr};
+    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)
@@ -327,13 +359,6 @@ public:
 
     mEnabledSignal.Emit();
 
-    if(mIsShown)
-    {
-      auto rootLayer = Dali::Stage::GetCurrent().GetRootLayer();
-      auto window    = Dali::DevelWindow::Get(rootLayer);
-      EmitActivate(window); // Currently, sends a signal that the default window is activated here.
-    }
-
     return ForceUpResult::JUST_STARTED;
   }
 
@@ -443,6 +468,31 @@ public:
     }
   }
 
+  /**
+   * @copydoc Dali::Accessibility::Bridge::SuppressScreenReader()
+   */
+  void SuppressScreenReader(bool suppress) override
+  {
+    if(mIsScreenReaderSuppressed == suppress)
+    {
+      return;
+    }
+    mIsScreenReaderSuppressed = suppress;
+    ReadScreenReaderEnabledProperty();
+  }
+
+  void SwitchBridge()
+  {
+    if((!mIsScreenReaderSuppressed && mIsScreenReaderEnabled) || mIsEnabled)
+    {
+      ForceUp();
+    }
+    else
+    {
+      ForceDown();
+    }
+  }
+
   bool ReadIsEnabledTimerCallback()
   {
     ReadIsEnabledProperty();
@@ -466,11 +516,15 @@ public:
         }
         return;
       }
-      mIsEnabled = std::get<0>(msg);
-      if(mIsEnabled)
+
+      if(mReadIsEnabledTimer)
       {
-        ForceUp();
+        mReadIsEnabledTimer.Stop();
+        mReadIsEnabledTimer.Reset();
       }
+
+      mIsEnabled = std::get<0>(msg);
+      SwitchBridge();
     });
   }
 
@@ -478,14 +532,7 @@ public:
   {
     mAccessibilityStatusClient.addPropertyChangedEvent<bool>("IsEnabled", [this](bool res) {
       mIsEnabled = res;
-      if(mIsScreenReaderEnabled || mIsEnabled)
-      {
-        ForceUp();
-      }
-      else
-      {
-        ForceDown();
-      }
+      SwitchBridge();
     });
   }
 
@@ -497,6 +544,12 @@ public:
 
   void ReadScreenReaderEnabledProperty()
   {
+    // can be true because of SuppressScreenReader before init
+    if (!mAccessibilityStatusClient)
+    {
+      return;
+    }
+
     mAccessibilityStatusClient.property<bool>("ScreenReaderEnabled").asyncGet([this](DBus::ValueOrError<bool> msg) {
       if(!msg)
       {
@@ -512,26 +565,36 @@ public:
         }
         return;
       }
-      mIsScreenReaderEnabled = std::get<0>(msg);
-      if(mIsScreenReaderEnabled)
+
+      if(mReadScreenReaderEnabledTimer)
       {
-        ForceUp();
+        mReadScreenReaderEnabledTimer.Stop();
+        mReadScreenReaderEnabledTimer.Reset();
       }
+
+      mIsScreenReaderEnabled = std::get<0>(msg);
+      SwitchBridge();
     });
   }
 
+  void EmitScreenReaderEnabledSignal()
+  {
+    if (mIsScreenReaderEnabled)
+    {
+      mScreenReaderEnabledSignal.Emit();
+    }
+    else
+    {
+      mScreenReaderDisabledSignal.Emit();
+    }
+  }
+
   void ListenScreenReaderEnabledProperty()
   {
     mAccessibilityStatusClient.addPropertyChangedEvent<bool>("ScreenReaderEnabled", [this](bool res) {
       mIsScreenReaderEnabled = res;
-      if(mIsScreenReaderEnabled || mIsEnabled)
-      {
-        ForceUp();
-      }
-      else
-      {
-        ForceDown();
-      }
+      EmitScreenReaderEnabledSignal();
+      SwitchBridge();
     });
   }
 
@@ -638,7 +701,7 @@ bool INITIALIZED_BRIDGE = false;
  * @return The BridgeImpl instance
  * @note This method is to check environment variable first. If ATSPI is disable using env, it returns dummy bridge instance.
  */
-Bridge* CreateBridge()
+std::shared_ptr<Bridge> CreateBridge()
 {
   INITIALIZED_BRIDGE = true;
 
@@ -651,7 +714,7 @@ Bridge* CreateBridge()
       return Dali::Accessibility::DummyBridge::GetInstance();
     }
 
-    return new BridgeImpl;
+    return std::make_shared<BridgeImpl>();
   }
   catch(const std::exception&)
   {
@@ -664,9 +727,9 @@ Bridge* CreateBridge()
 
 // Dali::Accessibility::Bridge class implementation
 
-Bridge* Bridge::GetCurrentBridge()
+std::shared_ptr<Bridge> Bridge::GetCurrentBridge()
 {
-  static Bridge* bridge;
+  static std::shared_ptr<Bridge> bridge;
 
   if(bridge)
   {
@@ -714,7 +777,7 @@ void Bridge::EnableAutoInit()
 
   auto accessible = Accessibility::Accessible::Get(rootLayer, true);
 
-  auto* bridge = Bridge::GetCurrentBridge();
+  auto bridge = Bridge::GetCurrentBridge();
   bridge->AddTopLevelWindow(accessible);
   bridge->SetApplicationName(applicationName);
   bridge->Initialize();