Merge "[AT-SPI] Add Bridge::{Enabled,Disabled}Signal()" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-impl.cpp
index 181b440..b5c275e 100644 (file)
@@ -217,6 +217,8 @@ public:
     mRegistryClient       = {};
     mDirectReadingClient  = {};
     mDirectReadingCallbacks.clear();
+    mApplication.mChildren.clear();
+    mApplication.mWindows.clear();
   }
 
   /**
@@ -287,9 +289,12 @@ public:
     assert(res);
 
     mApplication.mParent.SetAddress(std::move(std::get<0>(res)));
+
     if(mIsShown)
     {
-      EmitActivate();
+      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.
     }
 
     mEnabledSignal.Emit();
@@ -298,82 +303,135 @@ public:
   }
 
   /**
-   * @brief Sends a signal to dbus that the default window is activated.
+   * @brief Sends a signal to dbus that the window is shown.
    *
-   * TODO : This is subject to change if/when we implement multi-window support.
-   * @see BridgeObject::Emit()
+   * @param[in] window The window to be shown
+   * @see Accessible::EmitShowing() and BridgeObject::EmitStateChanged()
+   */
+  void EmitShown(Dali::Window window)
+  {
+    auto windowAccessible = mApplication.GetWindowAccessible(window);
+    if(windowAccessible)
+    {
+      windowAccessible->EmitShowing(true);
+    }
+  }
+
+  /**
+   * @brief Sends a signal to dbus that the window is hidden.
+   *
+   * @param[in] window The window to be hidden
+   * @see Accessible::EmitShowing() and BridgeObject::EmitStateChanged()
    */
-  void EmitActivate()
+  void EmitHidden(Dali::Window window)
   {
-    auto win = mApplication.GetActiveWindow();
-    if(win)
+    auto windowAccessible = mApplication.GetWindowAccessible(window);
+    if(windowAccessible)
     {
-      win->Emit(WindowEvent::ACTIVATE, 0);
+      windowAccessible->EmitShowing(false);
     }
   }
 
   /**
-   * @brief Sends a signal to dbus that the default window is deactivated.
+   * @brief Sends a signal to dbus that the window is activated.
    *
-   * TODO : This is subject to change if/when we implement multi-window support.
+   * @param[in] window The window to be activated
    * @see BridgeObject::Emit()
    */
-  void EmitDeactivate()
+  void EmitActivate(Dali::Window window)
   {
-    auto win = mApplication.GetActiveWindow();
-    if(win)
+    auto windowAccessible = mApplication.GetWindowAccessible(window);
+    if(windowAccessible)
     {
-      win->Emit(WindowEvent::DEACTIVATE, 0);
+      windowAccessible->Emit(WindowEvent::ACTIVATE, 0);
     }
   }
 
   /**
-   * @copydoc Dali::Accessibility::Bridge::WindowHidden()
+   * @brief Sends a signal to dbus that the window is deactivated.
+   *
+   * @param[in] window The window to be deactivated
+   * @see BridgeObject::Emit()
    */
-  void WindowHidden() override
+  void EmitDeactivate(Dali::Window window)
   {
-    if(mIsShown && IsUp())
+    auto windowAccessible = mApplication.GetWindowAccessible(window);
+    if(windowAccessible)
     {
-      EmitDeactivate();
+      windowAccessible->Emit(WindowEvent::DEACTIVATE, 0);
     }
-    mIsShown = false;
   }
 
   /**
    * @copydoc Dali::Accessibility::Bridge::WindowShown()
    */
-  void WindowShown() override
+  void WindowShown(Dali::Window window) override
   {
     if(!mIsShown && IsUp())
     {
-      EmitActivate();
+      EmitShown(window);
     }
     mIsShown = true;
   }
 
-  void ReadAndListenProperty()
+  /**
+   * @copydoc Dali::Accessibility::Bridge::WindowHidden()
+   */
+  void WindowHidden(Dali::Window window) override
   {
-    // read property
-    auto enabled = mAccessibilityStatusClient.property<bool>("ScreenReaderEnabled").get();
-    if(enabled)
+    if(mIsShown && IsUp())
     {
-      mIsScreenReaderEnabled = std::get<0>(enabled);
+      EmitHidden(window);
     }
+    mIsShown = false;
+  }
 
-    enabled = mAccessibilityStatusClient.property<bool>("IsEnabled").get();
-    if(enabled)
+  /**
+   * @copydoc Dali::Accessibility::Bridge::WindowFocused()
+   */
+  void WindowFocused(Dali::Window window) override
+  {
+    if(mIsShown && IsUp())
     {
-      mIsEnabled = std::get<0>(enabled);
+      EmitActivate(window);
     }
+  }
 
-    if(mIsScreenReaderEnabled || mIsEnabled)
+  /**
+   * @copydoc Dali::Accessibility::Bridge::WindowUnfocused()
+   */
+  void WindowUnfocused(Dali::Window window) override
+  {
+    if(mIsShown && IsUp())
     {
-      ForceUp();
+      EmitDeactivate(window);
     }
+  }
 
-    // listen property change
-    mAccessibilityStatusClient.addPropertyChangedEvent<bool>("ScreenReaderEnabled", [this](bool res) {
-      mIsScreenReaderEnabled = res;
+  void ReadIsEnabledProperty()
+  {
+    mAccessibilityStatusClient.property<bool>("IsEnabled").asyncGet([this](DBus::ValueOrError<bool> msg) {
+      if(!msg)
+      {
+        DALI_LOG_ERROR("Get IsEnabled property error: %s\n", msg.getError().message.c_str());
+        if(msg.getError().errorType == DBus::ErrorType::INVALID_REPLY)
+        {
+          ReadIsEnabledProperty();
+        }
+        return;
+      }
+      mIsEnabled = std::get<0>(msg);
+      if(mIsEnabled)
+      {
+        ForceUp();
+      }
+    });
+  }
+
+  void ListenIsEnabledProperty()
+  {
+    mAccessibilityStatusClient.addPropertyChangedEvent<bool>("IsEnabled", [this](bool res) {
+      mIsEnabled = res;
       if(mIsScreenReaderEnabled || mIsEnabled)
       {
         ForceUp();
@@ -383,9 +441,32 @@ public:
         ForceDown();
       }
     });
+  }
 
-    mAccessibilityStatusClient.addPropertyChangedEvent<bool>("IsEnabled", [this](bool res) {
-      mIsEnabled = res;
+  void ReadScreenReaderEnabledProperty()
+  {
+    mAccessibilityStatusClient.property<bool>("ScreenReaderEnabled").asyncGet([this](DBus::ValueOrError<bool> msg) {
+      if(!msg)
+      {
+        DALI_LOG_ERROR("Get ScreenReaderEnabled property error: %s\n", msg.getError().message.c_str());
+        if(msg.getError().errorType == DBus::ErrorType::INVALID_REPLY)
+        {
+          ReadScreenReaderEnabledProperty();
+        }
+        return;
+      }
+      mIsScreenReaderEnabled = std::get<0>(msg);
+      if(mIsScreenReaderEnabled)
+      {
+        ForceUp();
+      }
+    });
+  }
+
+  void ListenScreenReaderEnabledProperty()
+  {
+    mAccessibilityStatusClient.addPropertyChangedEvent<bool>("ScreenReaderEnabled", [this](bool res) {
+      mIsScreenReaderEnabled = res;
       if(mIsScreenReaderEnabled || mIsEnabled)
       {
         ForceUp();
@@ -397,6 +478,15 @@ public:
     });
   }
 
+  void ReadAndListenProperties()
+  {
+    ReadIsEnabledProperty();
+    ListenIsEnabledProperty();
+
+    ReadScreenReaderEnabledProperty();
+    ListenScreenReaderEnabledProperty();
+  }
+
   bool InitializeAccessibilityStatusClient()
   {
     mAccessibilityStatusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION};
@@ -414,7 +504,7 @@ public:
   {
     if ( InitializeAccessibilityStatusClient() )
     {
-      ReadAndListenProperty();
+      ReadAndListenProperties();
       mIdleCallback = NULL;
       return false;
     }
@@ -429,7 +519,7 @@ public:
   {
     if ( InitializeAccessibilityStatusClient() )
     {
-      ReadAndListenProperty();
+      ReadAndListenProperties();
       return;
     }
 
@@ -543,17 +633,19 @@ void Bridge::EnableAutoInit()
     return;
   }
 
-  auto rootLayer       = Dali::Stage::GetCurrent().GetRootLayer();
+  auto rootLayer       = Dali::Stage::GetCurrent().GetRootLayer(); // A root layer of the default window.
   auto window          = Dali::DevelWindow::Get(rootLayer);
   auto applicationName = Dali::Internal::Adaptor::Adaptor::GetApplicationPackageName();
 
+  auto accessible = Accessibility::Accessible::Get(rootLayer, true);
+
   auto* bridge = Bridge::GetCurrentBridge();
-  bridge->AddTopLevelWindow(Dali::Accessibility::Accessible::Get(rootLayer, true));
+  bridge->AddTopLevelWindow(accessible);
   bridge->SetApplicationName(applicationName);
   bridge->Initialize();
 
   if(window && window.IsVisible())
   {
-    bridge->WindowShown();
+    bridge->WindowShown(window);
   }
 }