AurumXML: Improve performance 35/289535/6
authorChihun Jeong <chihun.jeong@samsung.com>
Tue, 7 Mar 2023 07:45:29 +0000 (16:45 +0900)
committerChihun Jeong <chihun.jeong@samsung.com>
Mon, 13 Mar 2023 10:50:51 +0000 (19:50 +0900)
Change-Id: I3a2fd3ba244b9a6055f1cb3ef2c2f67a4eab08b6

libaurum/inc/Accessibility/AccessibleWatcher.h
libaurum/inc/AurumXML.h
libaurum/inc/Impl/Accessibility/AtspiAccessibleWatcher.h
libaurum/inc/Impl/Accessibility/MockAccessibleWatcher.h
libaurum/src/AurumXML.cc
libaurum/src/Comparer.cc
libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc
libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc
libaurum/src/Impl/Accessibility/MockAccessibleWatcher.cc

index 6a26dbc..42e0756 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -130,6 +130,16 @@ public:
     virtual std::map<std::string, std::shared_ptr<AurumXML>> getXMLDocMap(void) = 0;
 
     /**
+     * @brief Gets AurumXML pointer of a specific package name.
+     *
+     * @param[in] pkgName name of package.
+     *
+     * @return pointer of AurumXML the package if exist, else null pointer
+     * @since_tizen 7.5
+     */
+    virtual std::shared_ptr<AurumXML> getXMLDoc(std::string pkgName) = 0;
+
+    /**
      * @brief Register atspi event callback.
      *
      * @param[in] type @A11yEvent
index f7b9617..025508e 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <unordered_map>
 #include <mutex>
+#include <condition_variable>
 #include <sstream>
 
 #include "Accessible.h"
@@ -46,7 +47,7 @@ public:
      *
      * @since_tizen 7.0
      */
-    AurumXML(const std::shared_ptr<AccessibleNode> root, std::mutex& XMLMutex);
+    AurumXML(const std::shared_ptr<AccessibleNode> root, int *appXMLLoadedCount, std::mutex *XMLMutex, std::condition_variable *XMLConditionVar);
 
     /**
      * @brief Destroy the AurumXML object
@@ -145,7 +146,6 @@ private:
     xml_document                                *mDoc;
     const std::shared_ptr<AccessibleNode>        mRoot;
     std::unordered_map<std::string, std::shared_ptr<AccessibleNode>> mXNodeMap;
-    std::mutex&                                  XMLMutex;
 };
 }  // namespace Aurum
 
index 2136587..9a51680 100644 (file)
@@ -31,6 +31,8 @@
 #include <vector>
 #include <set>
 #include <map>
+#include <mutex>
+#include <condition_variable>
 
 using namespace Aurum;
 
@@ -131,6 +133,11 @@ public:
     virtual std::map<std::string, std::shared_ptr<AurumXML>> getXMLDocMap(void) override;
 
     /**
+     * @copydoc @AccessibleWatcher::getXMLDoc()
+     */
+    virtual std::shared_ptr<AurumXML> getXMLDoc(std::string pkgName) override;
+
+    /**
      * @copydoc @AccessibleWatcher::registerCallback()
      */
     virtual bool registerCallback(const A11yEvent type, EventHandler cb, void *data) override;
@@ -178,8 +185,16 @@ private:
     static std::mutex mMutex;
     static GMainLoop *mLoop;
     bool isTv;
-    std::mutex XMLMutex;
     std::map<const A11yEvent, std::list<std::shared_ptr<A11yEventHandler>>> mHandlers;
+
+    int mAppCount;
+
+    // this variable should be protected by XMLMutex.
+    int mAppXMLLoadedCount;
+
+    std::mutex mXMLMutex;
+    std::condition_variable mXMLConditionVar;
+
     static GThread *mTimerThread;
     static gint64 mStartTime;
     static IdleEventState isIdle;
index 622e26d..cfe66c3 100644 (file)
@@ -79,6 +79,8 @@ public:
 
     std::map<std::string, std::shared_ptr<AurumXML>> getXMLDocMap(void);
 
+    std::shared_ptr<AurumXML> getXMLDoc(std::string pkgName);
+
 public:
     /**
      * @brief TBD
index 2925fde..ea41c31 100644 (file)
 
 using namespace Aurum;
 
-AurumXML::AurumXML(const std::shared_ptr<AccessibleNode> root, std::mutex& XMLMutex) : mRoot(root), XMLMutex(XMLMutex)
+AurumXML::AurumXML(const std::shared_ptr<AccessibleNode> root, int *appXMLLoadedCount, std::mutex *XMLMutex, std::condition_variable *XMLConditionVar)
+: mRoot(root)
 {
-    XMLMutex.lock();
-
     mDoc = new xml_document();
     if (mRoot) this->createXMLtree();
 
-    XMLMutex.unlock();
+    XMLMutex->lock();
+    LOGI("XML Document Created: %s", root->getId().c_str());
+    (*appXMLLoadedCount)++;
+    XMLMutex->unlock();
+    XMLConditionVar->notify_all();
 }
 
 AurumXML::~AurumXML()
index fa09542..3082249 100644 (file)
@@ -59,12 +59,10 @@ std::vector<std::shared_ptr<AccessibleNode>> Comparer::findObjects(const std::sh
     if (selector->mMatchXPath) {
         std::vector<std::shared_ptr<AccessibleNode>> merged{};
 
-        auto XMLDocMap = AccessibleWatcher::getInstance()->getXMLDocMap();
         std::string pkg = root->getPkg();
+        auto XMLDoc = AccessibleWatcher::getInstance()->getXMLDoc(pkg);
 
-        if (XMLDocMap.count(pkg) == 0) return merged;
-
-        auto XMLDoc = XMLDocMap[pkg];
+        if (XMLDoc.get() == nullptr) return merged;
 
         auto tmp = XMLDoc->findObjects(selector->mXPath, earlyReturn);
         std::move(std::begin(tmp), std::end(tmp), std::back_inserter(merged));
index ead1399..2dc48ce 100644 (file)
@@ -245,10 +245,8 @@ void AtspiAccessibleNode::updateExtents()
 
 void AtspiAccessibleNode::updateXPath()
 {
-    auto XMLDocMap = AccessibleWatcher::getInstance()->getXMLDocMap();
-    if (XMLDocMap.count(mPkg) == 0) return;
-
-    auto XMLDoc = XMLDocMap[mPkg];
+    auto XMLDoc = AccessibleWatcher::getInstance()->getXMLDoc(mPkg);
+    if (XMLDoc.get() == nullptr) return;
 
     mXPath = XMLDoc->getXPath(shared_from_this());
 }
index 7ceecb5..358b191 100644 (file)
@@ -134,6 +134,9 @@ AtspiAccessibleWatcher::AtspiAccessibleWatcher()
     GVariant *result = nullptr;
     GError *error = nullptr;
 
+    mAppCount = 0;
+    mAppXMLLoadedCount = 0;
+
     atspi_init();
 
     mEventThread = g_thread_new("AtspiEventThread", eventThreadLoop, this);
@@ -204,8 +207,10 @@ void AtspiAccessibleWatcher::appendApp(AtspiAccessibleWatcher *instance, AtspiAc
         if (instance->mXMLDocMap.count(package)) {
             instance->mXMLDocMap.erase(package);
         }
+
+        mAppCount++;
         instance->mXMLDocMap.insert(std::pair<std::string, std::shared_ptr<AurumXML>>(package,
-                std::make_shared<AurumXML>(std::make_shared<AtspiAccessibleNode>(app), XMLMutex)));
+                std::make_shared<AurumXML>(std::make_shared<AtspiAccessibleNode>(app), &mAppXMLLoadedCount, &mXMLMutex, &mXMLConditionVar)));
     }
 }
 
@@ -442,19 +447,32 @@ std::map<AtspiAccessible *, std::shared_ptr<AccessibleApplication>> AtspiAccessi
 
 std::map<std::string, std::shared_ptr<AurumXML>> AtspiAccessibleWatcher::getXMLDocMap(void)
 {
-    bool isFirstWaiting = true;
-    while(!XMLMutex.try_lock())
-    {
-        if(isFirstWaiting)
-        {
-            LOGI("Waiting XMLTree Construct");
-            isFirstWaiting = false;
-        }
-    }
-    XMLMutex.unlock();
+    std::unique_lock lk(mXMLMutex);
+
+    //LOGI("mAppCount: %d, mAppXMLLoadedCount: %d", mAppCount, mAppXMLLoadedCount);
+    mXMLConditionVar.wait(lk, [&] {return mAppCount <= mAppXMLLoadedCount;});
+
+    lk.unlock();
+
     return mXMLDocMap;
 }
 
+std::shared_ptr<AurumXML> AtspiAccessibleWatcher::getXMLDoc(std::string pkgName)
+{
+    std::unique_lock lk(mXMLMutex);
+
+    //LOGI("mAppCount: %d, mAppXMLLoadedCount: %d", mAppCount, mAppXMLLoadedCount);
+    mXMLConditionVar.wait(lk, [&] {return mAppCount <= mAppXMLLoadedCount;});
+
+    lk.unlock();
+
+    if (mXMLDocMap.count(pkgName) > 0)
+        return mXMLDocMap[pkgName];
+    else
+        return std::shared_ptr<AurumXML>(nullptr);
+
+}
+
 bool AtspiAccessibleWatcher::removeFromActivatedList(AtspiAccessible *node)
 {
     LOGI("remove from activelist node %p", node);
index e054ced..1303e28 100644 (file)
@@ -60,6 +60,11 @@ std::map<std::string, std::shared_ptr<AurumXML>> MockAccessibleWatcher::getXMLDo
     return mXMLDocMap;
 }
 
+std::shared_ptr<AurumXML> MockAccessibleWatcher::getXMLDoc(std::string pkgName)
+{
+    return std::shared_ptr<AurumXML>();
+}
+
 std::shared_ptr<MockAccessibleApplication> MockAccessibleWatcher::addApplication(std::string pkgName, Rect<int> geometry, int ifaces, int properties)
 {
     std::shared_ptr<MockAccessibleNode> appNode = std::make_shared<MockAccessibleNode>(nullptr, pkgName, pkgName, "application", "", "Elm_Win", "default", "", geometry, ifaces, properties);