libaurum: rename Accessible class to AccessibleWatcher
authorWonki Kim <wonki_.kim@samsung.com>
Thu, 13 Feb 2020 07:11:35 +0000 (16:11 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Tue, 3 Mar 2020 06:59:56 +0000 (15:59 +0900)
Accessible class monitors atspi event to know the top activated node.
so this patch renames the class to another which is more reasonable.

Change-Id: Id266cba9674b6519fd9c23a928e00612c684e8eb

bootstrap/server/src/AurumServiceImpl.cc
bootstrap/server/src/Commands/SyncCommand.cc
libaurum/inc/Accessible.h [deleted file]
libaurum/inc/AccessibleWatcher.h [new file with mode: 0644]
libaurum/meson.build
libaurum/src/Accessible.cc [deleted file]
libaurum/src/AccessibleWatcher.cc [new file with mode: 0644]
libaurum/src/UiDevice.cc

index 1b689f1..05faf98 100644 (file)
@@ -1,6 +1,6 @@
 #include "AurumServiceImpl.h"
 
-#include <Accessible.h>
+#include <AccessibleWatcher.h>
 #include "Commands/Commands.h"
 #include "Commands/PostCommand.h"
 #include "Commands/PreCommand.h"
@@ -13,7 +13,7 @@ using namespace aurum;
 
 aurumServiceImpl::aurumServiceImpl()
 {
-    Accessible::getInstance();
+    AccessibleWatcher::getInstance();
 }
 
 ::grpc::Status aurumServiceImpl::execute(Command* cmd)
index 4b31ca7..84ce694 100644 (file)
@@ -1,7 +1,7 @@
 #include "SyncCommand.h"
 #include <loguru.hpp>
 
-#include <Accessible.h>
+#include <AccessibleWatcher.h>
 #include <AccessibleNode.h>
 
 SyncCommand::SyncCommand(const ::aurum::ReqEmpty *request,
@@ -13,7 +13,7 @@ SyncCommand::SyncCommand(const ::aurum::ReqEmpty *request,
 ::grpc::Status SyncCommand::execute()
 {
     LOG_SCOPE_F(INFO, "Sync Command ");
-    const Accessible *accObj = Accessible::getInstance();
+    const AccessibleWatcher *accObj = AccessibleWatcher::getInstance();
 
     AccessibleNode *root = accObj->getRootNode();
     AccessibleNode *top = accObj->getTopNode();
diff --git a/libaurum/inc/Accessible.h b/libaurum/inc/Accessible.h
deleted file mode 100644 (file)
index 9bb5f30..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef ACCESSIBLE_H
-#define ACCESSIBLE_H
-
-#include <atspi/atspi.h>
-#include "AccessibleNode.h"
-
-#include <list>
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <gio/gio.h>
-#include <mutex>
-#include <shared_mutex>
-#include "config.h"
-
-enum class WindowActivateInfoType {
-    DEFAULT_LABEL_ENALBED = 0x00,
-    DEFAULT_LABEL_ENALBED_WITHOUT_WINDOW = 0x01,
-    DEFAULT_LABEL_DISABLED = 0x02,
-    KEYBOARD = 0x04,
-};
-
-class IAtspiEvents {
-public:
-    virtual ~IAtspiEvents() {}
-    virtual void onActivate(AtspiAccessible *      node,
-                            WindowActivateInfoType type) const = 0;
-    virtual void onDeactivate(AtspiAccessible *node) const = 0;
-    virtual void onVisibilityChanged(AtspiAccessible *node,
-                                     bool             visible) const = 0;
-    virtual void onObjectDefunct(AtspiAccessible *node) const = 0;
-};
-
-class Accessible : public IAtspiEvents {
-private:
-    Accessible();
-
-public:
-    static const Accessible *getInstance();
-    virtual ~Accessible();
-
-public:
-    AccessibleNode *getRootNode() const;
-    AccessibleNode *getTopNode() const;
-
-    void onActivate(AtspiAccessible *      node,
-                    WindowActivateInfoType type) const override;
-    void onDeactivate(AtspiAccessible *node) const override;
-    void onVisibilityChanged(AtspiAccessible *node,
-                             bool             visible) const override;
-    void onObjectDefunct(AtspiAccessible *node) const override;
-
-private:
-    void        clearWindowList() const;
-    static void onAtspiWindowEvent(AtspiEvent *event, void *user_data);
-
-private:
-    static AtspiEventListener *                   listener;
-    mutable std::list<AtspiAccessible *>          mWindowList;
-    GDBusProxy *                                  mDbusProxy;
-    std::map<AtspiAccessible *, AccessibleNode *> mAccessibleNode;
-    mutable std::mutex                            mLock;
-};
-
-#endif
diff --git a/libaurum/inc/AccessibleWatcher.h b/libaurum/inc/AccessibleWatcher.h
new file mode 100644 (file)
index 0000000..7e3a3a8
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef ACCESSIBLE_H
+#define ACCESSIBLE_H
+
+#include <atspi/atspi.h>
+#include "AccessibleNode.h"
+
+#include <list>
+#include <map>
+#include <memory>
+#include <vector>
+#include <set>
+
+
+#include <gio/gio.h>
+#include <mutex>
+#include <shared_mutex>
+#include "config.h"
+
+
+
+enum class WindowActivateInfoType {
+    DEFAULT_LABEL_ENALBED = 0x00,
+    DEFAULT_LABEL_ENALBED_WITHOUT_WINDOW = 0x01,
+    DEFAULT_LABEL_DISABLED = 0x02,
+    KEYBOARD = 0x04,
+};
+
+class IAtspiEvents {
+public:
+    virtual ~IAtspiEvents() {}
+    virtual void onWindowActivated(AtspiAccessible *      node,
+                                   WindowActivateInfoType type) = 0;
+    virtual void onWindowDeactivated(AtspiAccessible *node) = 0;
+
+    virtual void onWindowCreated(AtspiAccessible *node) = 0;
+    virtual void onWindowDestroyed(AtspiAccessible *node) = 0;
+
+    virtual void onVisibilityChanged(AtspiAccessible *node,
+                                     bool             visible) = 0;
+    virtual void onObjectDefunct(AtspiAccessible *node) = 0;
+};
+
+class AccessibleWatcher : public IAtspiEvents {
+private:
+    AccessibleWatcher();
+
+public:
+    static const AccessibleWatcher *getInstance();
+    virtual ~AccessibleWatcher();
+
+public:
+    AccessibleNode *getRootNode() const;
+    AccessibleNode *getTopNode() const;
+
+    void onWindowActivated(AtspiAccessible *      node,
+                                   WindowActivateInfoType type) override;
+    void onWindowDeactivated(AtspiAccessible *node) override;
+
+    void onWindowCreated(AtspiAccessible *node) override;
+    void onWindowDestroyed(AtspiAccessible *node) override;
+
+    void onVisibilityChanged(AtspiAccessible *node,
+                                     bool             visible) override;
+    void onObjectDefunct(AtspiAccessible *node) override;
+
+    void printDbgInformation() const;
+
+private:
+    void        clearWindowList() const;
+    static void onAtspiWindowEvent(AtspiEvent *event, void *user_data);
+
+    bool removeFromActivatedList(AtspiAccessible *node);
+    bool addToActivatedList(AtspiAccessible *node);
+    bool removeFromWindowSet(AtspiAccessible *node);
+    bool addToWindowSet(AtspiAccessible *node);
+
+private:
+    static AtspiEventListener *                   listener;
+    mutable std::list<AtspiAccessible *>          mActivatedWindowList;
+    mutable std::list<AtspiAccessible *>          mActivatedApplicationList;
+    mutable std::set<AtspiAccessible *>           mWindowSet;;
+
+    GDBusProxy *                                  mDbusProxy;
+    std::map<AtspiAccessible *, AccessibleNode *> mAccessibleNode;
+    mutable std::mutex                            mLock;
+};
+
+#endif
index 662b665..b47e870 100644 (file)
@@ -9,7 +9,7 @@ libaurum_src = [
   files('src/UiDevice.cc'),
   files('src/UiObject.cc'),
   files('src/UiSelector.cc'),
-  files('src/Accessible.cc'),
+  files('src/AccessibleWatcher.cc'),
   files('src/AccessibleNode.cc'),
   files('src/Comparer.cc'),
   files('src/Until.cc'),
diff --git a/libaurum/src/Accessible.cc b/libaurum/src/Accessible.cc
deleted file mode 100644 (file)
index 7275c64..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-
-#include "Accessible.h"
-
-#include <string.h>
-#include <iostream>
-#include <utility>
-
-#include "loguru.hpp"
-
-AtspiEventListener *Accessible::listener = nullptr;
-
-static bool iShowingNode(AtspiAccessible *node)
-{
-    char *name = atspi_accessible_get_name(node, NULL);
-    char *pname = atspi_accessible_get_name(
-        atspi_accessible_get_parent(node, NULL), NULL);
-
-    LOG_SCOPE_F(INFO, "isShowing %s %s", name, pname);
-
-    if (!strcmp(name, "Keyboard") && !strcmp(pname, "ise-default")) {
-        free(name);
-        free(pname);
-        return false;
-    }
-    free(name);
-    free(pname);
-
-    AtspiStateSet *stateSet = atspi_accessible_get_state_set(node);
-    if (atspi_state_set_contains(stateSet, ATSPI_STATE_ACTIVE) &&
-        atspi_state_set_contains(stateSet, ATSPI_STATE_SHOWING)) {
-        g_object_unref(stateSet);
-        return true;
-    }
-    return false;
-}
-
-static AtspiAccessible *findActiveNode(AtspiAccessible *node, int depth,
-                                       int max_depth)
-{
-    if (depth >= max_depth) return NULL;
-
-    if (iShowingNode(node)) {
-        g_object_ref(node);
-
-        char *name = atspi_accessible_get_name(node, NULL);
-        char *pname = atspi_accessible_get_name(
-            atspi_accessible_get_parent(node, NULL), NULL);
-        LOG_SCOPE_F(INFO, "%s %s", name, pname);
-        return node;
-    }
-
-    int nchild = atspi_accessible_get_child_count(node, NULL);
-    for (int i = 0; i < nchild; i++) {
-        AtspiAccessible *child =
-            atspi_accessible_get_child_at_index(node, i, NULL);
-        AtspiAccessible *active = findActiveNode(child, depth + 1, max_depth);
-        g_object_unref(child);
-        if (active) return active;
-    }
-
-    return NULL;
-}
-
-Accessible::Accessible() : mWindowList{}
-{
-    GVariant *enabled_variant = nullptr, *result = nullptr;
-    GError *  error = nullptr;
-    atspi_init();
-
-    mDbusProxy = g_dbus_proxy_new_for_bus_sync(
-        G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE,
-        NULL, /* GDBusInterfaceInfo */
-        "org.a11y.Bus", "/org/a11y/bus", "org.freedesktop.DBus.Properties",
-        NULL, &error);
-
-    enabled_variant = g_variant_new_boolean(true);
-    result = g_dbus_proxy_call_sync(
-        mDbusProxy, "Set",
-        g_variant_new("(ssv)", "org.a11y.Status", "IsEnabled", enabled_variant),
-        G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
-
-    g_variant_unref(enabled_variant);
-    g_variant_unref(result);
-
-    listener =
-        atspi_event_listener_new(Accessible::onAtspiWindowEvent, this, NULL);
-    atspi_event_listener_register(listener, "window:", NULL);
-    atspi_event_listener_register(listener, "object:", NULL);
-}
-
-Accessible::~Accessible()
-{
-    for (auto it = mAccessibleNode.begin(); it != mAccessibleNode.end(); ++it) {
-        g_object_unref(it->first);
-        delete it->second;
-    }
-    atspi_event_listener_deregister(listener, "window:", NULL);
-    atspi_event_listener_deregister(listener, "object:", NULL);
-
-    g_object_unref(listener);
-    g_object_unref(mDbusProxy);
-
-    atspi_event_quit();
-    atspi_exit();
-}
-
-AccessibleNode *Accessible::getRootNode() const
-{
-    AtspiAccessible *node = atspi_get_desktop(0);
-    AccessibleNode * accNode = AccessibleNode::get(node);
-    if (node) g_object_unref(node);
-    return accNode;
-}
-
-AccessibleNode *Accessible::getTopNode() const
-{
-    AtspiAccessible *topNode = nullptr, *activeNode = nullptr,
-                    *rootNode = nullptr;
-    {
-        std::unique_lock<std::mutex> lock(mLock);
-        if (!mWindowList.empty()) {
-            topNode = mWindowList.front();
-        }
-    }
-
-#ifdef TIZEN
-    char *name, *pname;
-    name = atspi_accessible_get_name(topNode, NULL);
-    pname = atspi_accessible_get_parent(topNode, NULL)
-                ? atspi_accessible_get_name(
-                      atspi_accessible_get_parent(topNode, NULL), NULL)
-                : NULL;
-
-    LOG_F(INFO, "topNode unique id: %s  /  name: %s pname :%s",
-          atspi_accessible_get_unique_id(topNode, NULL), name, pname);
-
-    free(name);
-    free(pname);
-#endif
-
-    if (topNode) {
-        if (iShowingNode(topNode)) {
-            AccessibleNode *node = AccessibleNode::get(topNode);
-            // g_object_unref(activeNode);
-            return node;
-        }
-    }
-
-    rootNode = atspi_get_desktop(0);
-
-    if (rootNode) {
-        activeNode = findActiveNode(rootNode, 0, 2);
-
-#ifdef TIZEN
-        char *name, *pname;
-        name = atspi_accessible_get_name(activeNode, NULL);
-        pname = atspi_accessible_get_parent(activeNode, NULL)
-                    ? atspi_accessible_get_name(
-                          atspi_accessible_get_parent(activeNode, NULL), NULL)
-                    : NULL;
-
-        LOG_F(INFO, "activeNode unique id: %s  /   name: %s pname:%s",
-              atspi_accessible_get_unique_id(activeNode, NULL), name, pname);
-        free(name);
-        free(pname);
-#endif
-
-        if (activeNode) {
-            AccessibleNode *node = AccessibleNode::get(activeNode);
-            return node;
-        }
-        AccessibleNode *node = AccessibleNode::get(rootNode);
-        return node;
-    }
-    return nullptr;
-}
-
-void Accessible::onAtspiWindowEvent(AtspiEvent *event, void *user_data)
-{
-    char *              name, *pname;
-    const IAtspiEvents *instance = (IAtspiEvents *)user_data;
-
-    AtspiAccessible *p = atspi_accessible_get_parent(event->source, NULL);
-
-    name = atspi_accessible_get_name(event->source, NULL);
-    pname = atspi_accessible_get_name(p, NULL);
-
-    LOG_SCOPE_F(INFO, "event:%s, src:%p(%s), p:%p(%s), d1:%p d2:%p instance:%p",
-                event->type, event->source, name, p, pname, event->detail1,
-                event->detail2, instance);
-
-    if (!strcmp(event->type, "window:activate")) {
-        instance->onActivate(
-            static_cast<AtspiAccessible *>(event->source),
-            static_cast<WindowActivateInfoType>(event->detail1));
-    } else if (!strcmp(event->type, "window:deactivate")) {
-        instance->onDeactivate(static_cast<AtspiAccessible *>(event->source));
-    } else if (!strcmp(event->type, "object:state-changed:visible")) {
-        instance->onVisibilityChanged(
-            static_cast<AtspiAccessible *>(event->source),
-            (event->detail1 != 0));
-    } else if (!strcmp(event->type, "object:state-changed:defunct")) {
-        instance->onObjectDefunct(
-            static_cast<AtspiAccessible *>(event->source));
-    }
-}
-
-const Accessible *Accessible::getInstance()
-{
-    static Accessible *mInstance = nullptr;
-    if (!mInstance) mInstance = new Accessible();
-    return mInstance;
-}
-
-void Accessible::clearWindowList() const
-{
-    std::unique_lock<std::mutex> lock(mLock);
-    while (!mWindowList.empty()) {
-        AtspiAccessible *n = mWindowList.front();
-        mWindowList.pop_front();
-        g_object_unref(n);
-    }
-}
-
-void Accessible::onActivate(AtspiAccessible *      node,
-                            WindowActivateInfoType type) const
-{
-    std::unique_lock<std::mutex> lock(mLock);
-
-    char *name = atspi_accessible_get_name(node, NULL);
-    char *pname = atspi_accessible_get_name(
-        atspi_accessible_get_parent(node, NULL), NULL);
-    LOG_SCOPE_F(INFO, "%s %s", name, pname);
-
-    mWindowList.remove_if([&](auto &n) { return n == node; });
-    if (!strcmp(name, "Keyboard") && !strcmp(pname, "ise-default")) return;
-    mWindowList.push_front(node);
-}
-
-void Accessible::onDeactivate(AtspiAccessible *node) const
-{
-    std::unique_lock<std::mutex> lock(mLock);
-    mWindowList.remove_if([&](auto &n) { return n == node; });
-    mWindowList.push_back(node);
-}
-
-void Accessible::onVisibilityChanged(AtspiAccessible *node, bool visible) const
-{
-}
-
-void Accessible::onObjectDefunct(AtspiAccessible *node) const
-{
-    LOG_SCOPE_F(INFO, "object defuncted %p", node);
-}
\ No newline at end of file
diff --git a/libaurum/src/AccessibleWatcher.cc b/libaurum/src/AccessibleWatcher.cc
new file mode 100644 (file)
index 0000000..72b02e4
--- /dev/null
@@ -0,0 +1,304 @@
+
+#include "AccessibleWatcher.h"
+
+#include <string.h>
+#include <iostream>
+#include <utility>
+
+#include "loguru.hpp"
+
+AtspiEventListener *AccessibleWatcher::listener = nullptr;
+
+static bool iShowingNode(AtspiAccessible *node)
+{
+    char *name = atspi_accessible_get_name(node, NULL);
+    char *pname = atspi_accessible_get_name(
+        atspi_accessible_get_parent(node, NULL), NULL);
+
+    LOG_SCOPE_F(INFO, "isShowing %s %s", name, pname);
+
+    // if (!strcmp(name, "Keyboard") && !strcmp(pname, "ise-default")) {
+    //     free(name);
+    //     free(pname);
+    //     return false;
+    // }
+    free(name);
+    free(pname);
+
+    AtspiStateSet *stateSet = atspi_accessible_get_state_set(node);
+    if (atspi_state_set_contains(stateSet, ATSPI_STATE_ACTIVE) &&
+        atspi_state_set_contains(stateSet, ATSPI_STATE_SHOWING)) {
+        g_object_unref(stateSet);
+        return true;
+    }
+    return false;
+}
+
+static AtspiAccessible *findActiveNode(AtspiAccessible *node, int depth,
+                                       int max_depth)
+{
+    if (depth >= max_depth) return NULL;
+
+    if (iShowingNode(node)) {
+        g_object_ref(node);
+
+        char *name = atspi_accessible_get_name(node, NULL);
+        char *pname = atspi_accessible_get_name(
+            atspi_accessible_get_parent(node, NULL), NULL);
+        LOG_SCOPE_F(INFO, "%s %s", name, pname);
+        return node;
+    }
+
+    int nchild = atspi_accessible_get_child_count(node, NULL);
+    for (int i = 0; i < nchild; i++) {
+        AtspiAccessible *child =
+            atspi_accessible_get_child_at_index(node, i, NULL);
+        AtspiAccessible *active = findActiveNode(child, depth + 1, max_depth);
+        g_object_unref(child);
+        if (active) return active;
+    }
+
+    return NULL;
+}
+
+AccessibleWatcher::AccessibleWatcher() : mActivatedWindowList{}, mWindowSet{}
+{
+    GVariant *enabled_variant = nullptr, *result = nullptr;
+    GError *  error = nullptr;
+    atspi_init();
+    atspi_set_main_context (g_main_context_default ());
+
+    mDbusProxy = g_dbus_proxy_new_for_bus_sync(
+        G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE,
+        NULL, /* GDBusInterfaceInfo */
+        "org.a11y.Bus", "/org/a11y/bus", "org.freedesktop.DBus.Properties",
+        NULL, &error);
+
+    enabled_variant = g_variant_new_boolean(true);
+    result = g_dbus_proxy_call_sync(
+        mDbusProxy, "Set",
+        g_variant_new("(ssv)", "org.a11y.Status", "IsEnabled", enabled_variant),
+        G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+    g_variant_unref(enabled_variant);
+    g_variant_unref(result);
+
+    listener =
+        atspi_event_listener_new(AccessibleWatcher::onAtspiWindowEvent, this, NULL);
+    atspi_event_listener_register(listener, "window:create", NULL);
+    atspi_event_listener_register(listener, "window:destroy", NULL);
+    atspi_event_listener_register(listener, "window:activate", NULL);
+    atspi_event_listener_register(listener, "window:deactivate", NULL);
+    atspi_event_listener_register(listener, "object:", NULL);
+}
+
+AccessibleWatcher::~AccessibleWatcher()
+{
+    for (auto it = mAccessibleNode.begin(); it != mAccessibleNode.end(); ++it) {
+        g_object_unref(it->first);
+        delete it->second;
+    }
+    atspi_event_listener_deregister(listener, "window:", NULL);
+    atspi_event_listener_deregister(listener, "object:", NULL);
+
+    g_object_unref(listener);
+    g_object_unref(mDbusProxy);
+
+    atspi_event_quit();
+    atspi_exit();
+}
+
+AccessibleNode *AccessibleWatcher::getRootNode() const
+{
+    AtspiAccessible *node = atspi_get_desktop(0);
+    AccessibleNode * accNode = AccessibleNode::get(node);
+    if (node) g_object_unref(node);
+    return accNode;
+}
+
+AccessibleNode *AccessibleWatcher::getTopNode() const
+{
+    AtspiAccessible *topNode = nullptr, *activeNode = nullptr,
+                    *rootNode = nullptr;
+    {
+        std::unique_lock<std::mutex> lock(mLock);
+        if (!mActivatedWindowList.empty()) {
+            topNode = mActivatedWindowList.front();
+            if (topNode && iShowingNode(topNode))
+                return AccessibleNode::get(atspi_accessible_get_application(topNode, NULL));
+        }
+    }
+
+    LOG_F(INFO, "Mo activated window node or Invisible acticated window / topNdoe(%p)", topNode);
+    LOG_F(INFO, "Trying fallback logic");
+
+    rootNode = atspi_get_desktop(0);
+
+    if (rootNode) {
+        activeNode = atspi_accessible_get_application(findActiveNode(rootNode, 0, 2), NULL);
+        if (activeNode) {
+            AccessibleNode *node = AccessibleNode::get(activeNode);
+            return node;
+        }
+        AccessibleNode *node = AccessibleNode::get(rootNode);
+        return node;
+    }
+    return nullptr;
+}
+
+void AccessibleWatcher::onAtspiWindowEvent(AtspiEvent *event, void *user_data)
+{
+    char *              name, *pname;
+    IAtspiEvents *instance = (IAtspiEvents *)user_data;
+
+    AtspiAccessible *p = atspi_accessible_get_parent(event->source, NULL);
+
+    name = atspi_accessible_get_name(event->source, NULL);
+    pname = atspi_accessible_get_name(p, NULL);
+
+    // LOG_SCOPE_F(INFO, "event:%s, src:%p(%s), p:%p(%s), d1:%p d2:%p instance:%p",
+    //             event->type, event->source, name, p, pname, event->detail1,
+    //             event->detail2, instance);
+
+    if (!strcmp(event->type, "window:activate")) {
+        instance->onWindowActivated(
+            static_cast<AtspiAccessible *>(event->source),
+            static_cast<WindowActivateInfoType>(event->detail1));
+    } else if (!strcmp(event->type, "window:deactivate")) {
+        instance->onWindowDeactivated(static_cast<AtspiAccessible *>(event->source));
+    } else if (!strcmp(event->type, "window:create")) {
+        instance->onWindowCreated(static_cast<AtspiAccessible *>(event->source));
+    } else if (!strcmp(event->type, "window:destroy")) {
+        instance->onWindowDestroyed(static_cast<AtspiAccessible *>(event->source));
+    } else if (!strcmp(event->type, "object:state-changed:visible")) {
+        instance->onVisibilityChanged(
+            static_cast<AtspiAccessible *>(event->source),
+            (event->detail1 != 0));
+    } else if (!strcmp(event->type, "object:state-changed:defunct")) {
+        instance->onObjectDefunct(
+            static_cast<AtspiAccessible *>(event->source));
+    }
+}
+
+void AccessibleWatcher::printDbgInformation() const
+{
+    LOG_SCOPE_F(INFO, "%d %d", mActivatedWindowList.size(),  mWindowSet.size());
+
+    for (auto iter = mActivatedWindowList.begin(); iter != mActivatedWindowList.end(); ++iter) {
+        LOG_F(INFO, "%p", *iter);
+    }
+        LOG_F(INFO, "-----------");
+
+    for (auto iter = mWindowSet.begin(); iter != mWindowSet.end(); ++iter) {
+        LOG_F(INFO, "%p", *iter);
+    }
+}
+
+const AccessibleWatcher *AccessibleWatcher::getInstance()
+{
+    static AccessibleWatcher *mInstance = nullptr;
+    if (!mInstance) mInstance = new AccessibleWatcher();
+    return mInstance;
+}
+
+void AccessibleWatcher::clearWindowList() const
+{
+    std::unique_lock<std::mutex> lock(mLock);
+    while (!mActivatedWindowList.empty()) {
+        AtspiAccessible *n = mActivatedWindowList.front();
+        mActivatedWindowList.pop_front();
+        g_object_unref(n);
+    }
+
+    mWindowSet.clear();
+}
+
+bool AccessibleWatcher::removeFromActivatedList(AtspiAccessible *node)
+{
+    mActivatedWindowList.remove_if([&](auto &n) { return n == node; });
+    return true;
+}
+
+bool AccessibleWatcher::addToActivatedList(AtspiAccessible *node)
+{
+    mActivatedWindowList.remove_if([&](auto &n) { return n == node; });
+    //if (!strcmp(name, "Keyboard") && !strcmp(pname, "ise-default")) return;
+    mActivatedWindowList.push_front(node);
+
+    auto iter = mWindowSet.find(node);
+    if ( iter == mWindowSet.end()) mWindowSet.insert(node);
+    return true;
+}
+
+bool AccessibleWatcher::removeFromWindowSet(AtspiAccessible *node)
+{
+    removeFromActivatedList(node);
+    auto iter = mWindowSet.find(node);
+    if ( iter != mWindowSet.end()){
+        mWindowSet.erase(node);
+        return true;
+    }
+    return false;
+}
+
+bool AccessibleWatcher::addToWindowSet(AtspiAccessible *node)
+{
+    auto iter = mWindowSet.find(node);
+    if ( iter == mWindowSet.end()){
+        mWindowSet.insert(node);
+        return true;
+    }
+    return false;
+}
+
+void AccessibleWatcher::onWindowActivated(AtspiAccessible *      node,
+                            WindowActivateInfoType type)
+{
+    std::unique_lock<std::mutex> lock(mLock);
+
+    addToActivatedList(node);
+
+    return;
+    /*
+    char *name = atspi_accessible_get_name(node, NULL);
+    char *pname = atspi_accessible_get_name(
+        atspi_accessible_get_parent(node, NULL), NULL);
+    LOG_SCOPE_F(INFO, "%s %s", name, pname);
+
+    mActivatedWindowList.remove_if([&](auto &n) { return n == node; });
+    if (!strcmp(name, "Keyboard") && !strcmp(pname, "ise-default")) return;
+    mActivatedWindowList.push_front(node);
+    */
+}
+
+void AccessibleWatcher::onWindowDeactivated(AtspiAccessible *node)
+{
+    std::unique_lock<std::mutex> lock(mLock);
+    removeFromActivatedList(node);
+    return;
+/*
+    mActivatedWindowList.remove_if([&](auto &n) { return n == node; });
+    mActivatedWindowList.push_back(node);
+    */
+}
+
+void AccessibleWatcher::onWindowCreated(AtspiAccessible *node)
+{
+    std::unique_lock<std::mutex> lock(mLock);
+    addToWindowSet(node);
+}
+
+void AccessibleWatcher::onWindowDestroyed(AtspiAccessible *node)
+{
+    std::unique_lock<std::mutex> lock(mLock);
+    removeFromWindowSet(node);
+}
+
+void AccessibleWatcher::onVisibilityChanged(AtspiAccessible *node, bool visible)
+{
+}
+
+void AccessibleWatcher::onObjectDefunct(AtspiAccessible *node)
+{
+    LOG_SCOPE_F(INFO, "object defuncted %p", node);
+}
\ No newline at end of file
index 4646cb9..e60bcfb 100644 (file)
@@ -1,5 +1,5 @@
 #include "UiDevice.h"
-#include "Accessible.h"
+#include "AccessibleWatcher.h"
 #include "Comparer.h"
 #include "DeviceImpl/TM1Impl.h"
 
@@ -31,7 +31,7 @@ UiDevice *UiDevice::getInstance(DeviceType type)
 
 const AccessibleNode *UiDevice::getWindowRoot() const
 {
-    AccessibleNode *root = Accessible::getInstance()->getTopNode();
+    AccessibleNode *root = AccessibleWatcher::getInstance()->getTopNode();
     // root->print(0,6);
     return root;
 }