[AT-SPI] do not keep window in ApplicationAccessible
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / bridge-base.h
index 62a0094..bf2a22c 100644 (file)
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/layer.h>
 #include <dali/public-api/dali-adaptor-version.h>
 #include <dali/public-api/signals/connection-tracker.h>
-#include <dali/public-api/actors/layer.h>
 #include <memory>
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/proxy-accessible.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/devel-api/atspi-interfaces/accessible.h>
+#include <dali/devel-api/atspi-interfaces/application.h>
+#include <dali/devel-api/atspi-interfaces/collection.h>
 #include <dali/internal/accessibility/bridge/accessibility-common.h>
 
 /**
- * @brief The AppAccessible class is to define Accessibility Application.
+ * @brief The ApplicationAccessible class is to define Accessibility Application.
  */
-class AppAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection, public virtual Dali::Accessibility::Application
+class ApplicationAccessible : public virtual Dali::Accessibility::Accessible, public virtual Dali::Accessibility::Collection, public virtual Dali::Accessibility::Application
 {
 public:
-  Dali::Accessibility::EmptyAccessibleWithAddress mParent;
-  std::vector<Dali::Accessibility::Accessible*>   mChildren;
-  std::vector<Dali::Window>                       mWindows;
-  std::string                                     mName;
+  Dali::Accessibility::ProxyAccessible          mParent;
+  std::vector<Dali::Accessibility::Accessible*> mChildren;
+  std::string                                   mName;
 
-  std::string GetName() override
+  std::string GetName() const override
   {
     return mName;
   }
 
-  std::string GetDescription() override
+  std::string GetDescription() const override
   {
     return "";
   }
@@ -54,11 +57,16 @@ public:
     return &mParent;
   }
 
-  size_t GetChildCount() override
+  size_t GetChildCount() const override
   {
     return mChildren.size();
   }
 
+  std::vector<Dali::Accessibility::Accessible*> GetChildren() override
+  {
+    return mChildren;
+  }
+
   Dali::Accessibility::Accessible* GetChildAtIndex(size_t index) override
   {
     auto size = mChildren.size();
@@ -74,7 +82,7 @@ public:
     throw std::domain_error{"can't call GetIndexInParent on application object"};
   }
 
-  Dali::Accessibility::Role GetRole() override
+  Dali::Accessibility::Role GetRole() const override
   {
     return Dali::Accessibility::Role::APPLICATION;
   }
@@ -84,7 +92,7 @@ public:
     return {};
   }
 
-  Dali::Accessibility::Attributes GetAttributes() override
+  Dali::Accessibility::Attributes GetAttributes() const override
   {
     return {};
   }
@@ -133,17 +141,17 @@ public:
     return Dali::Actor{};
   }
 
-  Dali::Accessibility::Address GetAddress() override
+  Dali::Accessibility::Address GetAddress() const override
   {
     return {"", "root"};
   }
 
-  std::string GetToolkitName() override
+  std::string GetToolkitName() const override
   {
     return {"dali"};
   }
 
-  std::string GetVersion() override
+  std::string GetVersion() const override
   {
     return std::to_string(Dali::ADAPTOR_MAJOR_VERSION) + "." + std::to_string(Dali::ADAPTOR_MINOR_VERSION);
   }
@@ -227,14 +235,22 @@ public:
   void RemoveTopLevelWindow(Dali::Accessibility::Accessible* windowAccessible) override;
 
   /**
-   * @copydoc Dali::Accessibility::Bridge::AddPopup()
+   * @copydoc Dali::Accessibility::Bridge::RegisterDefaultLabel()
+   */
+  void RegisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
+
+  /**
+   * @copydoc Dali::Accessibility::Bridge::UnregisterDefaultLabel()
    */
-  void AddPopup(Dali::Accessibility::Accessible* object) override;
+  void UnregisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
 
   /**
-   * @copydoc Dali::Accessibility::Bridge::RemovePopup()
+   * @copydoc Dali::Accessibility::Bridge::GetDefaultLabel()
    */
-  void RemovePopup(Dali::Accessibility::Accessible* object) override;
+  Dali::Accessibility::Accessible* GetDefaultLabel() const override
+  {
+    return mDefaultLabels.empty() ? nullptr : mDefaultLabels.back();
+  }
 
   /**
    * @copydoc Dali::Accessibility::Bridge::GetApplication()
@@ -408,14 +424,52 @@ public:
   /**
    * @brief Returns the target object of the currently executed DBus method call.
    *
-   * And any subclasses redefine `FindSelf` with a different return type as a convenient wrapper around dynamic_cast.
    * @return The Accessible object
    * @note When a DBus method is called on some object, this target object (`currentObject`) is temporarily saved by the bridge,
    * because DBus handles the invocation target separately from the method arguments.
    * We then use the saved object inside the 'glue' method (e.g. BridgeValue::GetMinimum)
    * to call the equivalent method on the respective C++ object (this could be ScrollBar::AccessibleImpl::GetMinimum in the example given).
    */
-  Dali::Accessibility::Accessible* FindSelf() const;
+  Dali::Accessibility::Accessible* FindCurrentObject() const;
+
+  /**
+   * @brief Returns the target object of the currently executed DBus method call.
+   *
+   * This method tries to downcast the return value of FindCurrentObject() to the requested type,
+   * issuing an error reply to the DBus caller if the requested type is not implemented. Whether
+   * a given type is implemented is decided based on the return value of Accessible::GetInterfaces()
+   * for the current object.
+   *
+   * @tparam I The requested AT-SPI interface
+   * @return The Accessible object (cast to a more derived type)
+   *
+   * @see FindCurrentObject()
+   * @see Dali::Accessibility::AtspiInterface
+   * @see Dali::Accessibility::AtspiInterfaceType
+   * @see Dali::Accessibility::Accessible::GetInterfaces()
+   */
+  template<Dali::Accessibility::AtspiInterface I>
+  auto* FindCurrentObjectWithInterface() const
+  {
+    using Type = Dali::Accessibility::AtspiInterfaceType<I>;
+
+    Type* result;
+    auto* currentObject = FindCurrentObject();
+    DALI_ASSERT_DEBUG(currentObject); // FindCurrentObject() throws domain_error
+
+    if(!(result = Dali::Accessibility::Accessible::DownCast<I>(currentObject)))
+    {
+      std::stringstream s;
+
+      s << "Object " << currentObject->GetAddress().ToString();
+      s << " does not implement ";
+      s << Dali::Accessibility::Accessible::GetInterfaceName(I);
+
+      throw std::domain_error{s.str()};
+    }
+
+    return result;
+  }
 
   /**
    * @copydoc Dali::Accessibility::Bridge::FindByPath()
@@ -431,11 +485,11 @@ public:
   }
 
 protected:
-  mutable AppAccessible                         mApplication;
-  std::vector<Dali::Accessibility::Accessible*> mPopups;
+  mutable ApplicationAccessible                 mApplication;
+  std::vector<Dali::Accessibility::Accessible*> mDefaultLabels;
+  bool                                          mIsScreenReaderSuppressed = false;
 
 private:
-
   /**
    * @brief Sets an ID.
    * @param[in] id An ID (integer value)