/*
- * 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.
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
#include <unordered_map>
#include <mutex>
+#include <condition_variable>
#include <sstream>
#include "Accessible.h"
*
* @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
xml_document *mDoc;
const std::shared_ptr<AccessibleNode> mRoot;
std::unordered_map<std::string, std::shared_ptr<AccessibleNode>> mXNodeMap;
- std::mutex& XMLMutex;
};
} // namespace Aurum
#include <vector>
#include <set>
#include <map>
+#include <mutex>
+#include <condition_variable>
using namespace Aurum;
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;
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;
std::map<std::string, std::shared_ptr<AurumXML>> getXMLDocMap(void);
+ std::shared_ptr<AurumXML> getXMLDoc(std::string pkgName);
+
public:
/**
* @brief TBD
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()
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));
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());
}
GVariant *result = nullptr;
GError *error = nullptr;
+ mAppCount = 0;
+ mAppXMLLoadedCount = 0;
+
atspi_init();
mEventThread = g_thread_new("AtspiEventThread", eventThreadLoop, this);
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)));
}
}
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);
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);