2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/accessibility/bridge/bridge-collection.h>
23 #include <unordered_set>
26 using namespace Dali::Accessibility;
31 * @brief Enumeration used for quering Accessibility objects.
33 * Refer to MatchType enumeration.
35 enum class AtspiCollection
44 } // anonymous namespace
46 void BridgeCollection::RegisterInterfaces()
48 DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::COLLECTION)};
49 AddFunctionToInterface(desc, "GetMatches", &BridgeCollection::GetMatches);
50 mDbusServer.addInterface("/", desc, true);
53 Collection* BridgeCollection::FindSelf() const
55 return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::COLLECTION>();
59 * @brief The BridgeCollection::Comparer structure.
61 * Once the data is de-serialized by DBusWrapper, the data of match rule is passed
62 * to Comparer type which do the comparison against a single accessible object.
64 struct BridgeCollection::Comparer
66 using Mode = MatchType;
69 * @brief Enumeration to check the object is found first.
71 enum class CompareFuncExit
77 static Mode ConvertToMatchType(int32_t mode)
81 case static_cast<int32_t>(AtspiCollection::MATCH_INVALID):
85 case static_cast<int32_t>(AtspiCollection::MATCH_ALL):
89 case static_cast<int32_t>(AtspiCollection::MATCH_ANY):
93 case static_cast<int32_t>(AtspiCollection::MATCH_NONE):
97 case static_cast<int32_t>(AtspiCollection::MATCH_EMPTY):
102 return Mode::INVALID;
106 * @brief The ComparerInterfaces structure
108 struct ComparerInterfaces
110 std::unordered_set<std::string> mObject;
111 std::vector<std::string> mRequested;
112 Mode mMode = Mode::INVALID;
114 ComparerInterfaces(MatchRule* rule)
115 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::INTERFACES_MATCH_TYPE)>(*rule)))
117 mRequested = {std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).begin(), std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).end()};
120 void Update(Accessible* obj)
123 for(auto& interface : obj->GetInterfacesAsStrings())
125 mObject.insert(std::move(interface));
129 bool IsRequestEmpty() const
131 return mRequested.empty();
134 bool IsObjectEmpty() const
136 return mObject.empty();
139 bool Compare(CompareFuncExit exit)
141 bool foundAny = false;
142 for(auto& iname : mRequested)
144 bool found = (mObject.find(iname) != mObject.end());
150 if(found == (exit == CompareFuncExit::FIRST_FOUND))
157 }; // ComparerInterfaces struct
160 * @brief The ComparerAttributes structure
162 struct ComparerAttributes
164 std::unordered_map<std::string, std::string> mRequested;
165 std::unordered_map<std::string, std::string> mObject;
166 Mode mMode = Mode::INVALID;
168 ComparerAttributes(MatchRule* rule)
169 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ATTRIBUTES_MATCH_TYPE)>(*rule)))
171 mRequested = std::get<static_cast<std::size_t>(Index::ATTRIBUTES)>(*rule);
174 void Update(Accessible* obj)
176 mObject = obj->GetAttributes();
179 bool IsRequestEmpty() const
181 return mRequested.empty();
184 bool IsObjectEmpty() const
186 return mObject.empty();
189 bool Compare(CompareFuncExit exit)
191 bool foundAny = false;
192 for(auto& iname : mRequested)
194 auto it = mObject.find(iname.first);
195 bool found = it != mObject.end() && iname.second == it->second;
201 if(found == (exit == CompareFuncExit::FIRST_FOUND))
208 }; // ComparerAttributes struct
211 * @brief The ComparerRoles structure
215 using Roles = EnumBitSet<Role, Role::MAX_COUNT>;
219 Mode mMode = Mode::INVALID;
221 ComparerRoles(MatchRule* rule)
222 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ROLES_MATCH_TYPE)>(*rule)))
224 mRequested = Roles{std::get<static_cast<std::size_t>(Index::ROLES)>(*rule)};
227 void Update(Accessible* obj)
230 mObject[obj->GetRole()] = true;
234 bool IsRequestEmpty() const
239 bool IsObjectEmpty() const
244 bool Compare(CompareFuncExit exit)
255 return mRequested == (mObject & mRequested);
259 return bool(mObject & mRequested);
263 return bool(mObject & mRequested);
268 }; // ComparerRoles struct
271 * @brief The ComparerStates structure
273 struct ComparerStates
277 Mode mMode = Mode::INVALID;
279 ComparerStates(MatchRule* rule)
280 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::STATES_MATCH_TYPE)>(*rule)))
282 mRequested = States{std::get<static_cast<std::size_t>(Index::STATES)>(*rule)};
285 void Update(Accessible* obj)
287 mObject = obj->GetStates();
290 bool IsRequestEmpty() const
295 bool IsObjectEmpty() const
300 bool Compare(CompareFuncExit exit)
311 return mRequested == (mObject & mRequested);
315 return bool(mObject & mRequested);
319 return bool(mObject & mRequested);
324 }; // ComparerStates struct
327 bool CompareFunc(T& cmp, Accessible* obj)
329 if(cmp.mMode == Mode::INVALID)
339 if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
347 if(cmp.IsRequestEmpty())
351 if(cmp.IsObjectEmpty())
359 if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
367 if(cmp.IsRequestEmpty() && cmp.IsObjectEmpty())
371 if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
388 if(!cmp.Compare(CompareFuncExit::FIRST_NOT_FOUND))
396 if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
404 if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
436 Comparer(MatchRule* rule)
444 bool operator()(Accessible* obj)
446 return CompareFunc(mInterface, obj) &&
447 CompareFunc(mAttribute, obj) &&
448 CompareFunc(mRole, obj) &&
449 CompareFunc(mState, obj);
452 ComparerInterfaces mInterface;
453 ComparerAttributes mAttribute;
455 ComparerStates mState;
456 }; // BridgeCollection::Comparer struct
459 void BridgeCollection::VisitNodes(Accessible* obj, std::vector<Accessible*>& result, Comparer& comparer, size_t maxCount)
461 if(maxCount > 0 && result.size() >= maxCount)
468 result.emplace_back(obj);
469 // the code below will never return for maxCount equal 0
470 if(result.size() == maxCount)
476 for(auto i = 0u; i < obj->GetChildCount(); ++i)
478 VisitNodes(obj->GetChildAtIndex(i), result, comparer, maxCount);
482 DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(MatchRule rule, uint32_t sortBy, int32_t count, bool traverse)
484 std::vector<Accessible*> res;
485 auto self = BridgeBase::FindCurrentObject();
486 auto matcher = Comparer{&rule};
487 VisitNodes(self, res, matcher, count);
489 switch(static_cast<SortOrder>(sortBy))
491 case SortOrder::CANONICAL:
496 case SortOrder::REVERSE_CANONICAL:
498 std::reverse(res.begin(), res.end());
504 throw std::domain_error{"unsupported sorting order"};