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>
24 #include <unordered_set>
27 using namespace Dali::Accessibility;
32 * @brief Enumeration used for quering Accessibility objects.
34 * Refer to MatchType enumeration.
36 enum class AtspiCollection
45 } // anonymous namespace
47 void BridgeCollection::RegisterInterfaces()
49 DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceCollection};
50 AddFunctionToInterface(desc, "GetMatches", &BridgeCollection::GetMatches);
51 mDbusServer.addInterface("/", desc, true);
54 Collection* BridgeCollection::FindSelf() const
56 auto self = BridgeBase::FindSelf();
58 auto collectionInterface = dynamic_cast<Collection*>(self);
59 if(!collectionInterface)
61 throw std::domain_error{"object " + self->GetAddress().ToString() + " doesn't have Collection interface"};
63 return collectionInterface;
67 * @brief The BridgeCollection::Comparer structure.
69 * Once the data is de-serialized by DBusWrapper, the data of match rule is passed
70 * to Comparer type which do the comparison against a single accessible object.
72 struct BridgeCollection::Comparer
74 using Mode = MatchType;
77 * @brief Enumeration to check the object is found first.
79 enum class CompareFuncExit
85 static Mode ConvertToMatchType(int32_t mode)
89 case static_cast<int32_t>(AtspiCollection::MATCH_INVALID):
93 case static_cast<int32_t>(AtspiCollection::MATCH_ALL):
97 case static_cast<int32_t>(AtspiCollection::MATCH_ANY):
101 case static_cast<int32_t>(AtspiCollection::MATCH_NONE):
105 case static_cast<int32_t>(AtspiCollection::MATCH_EMPTY):
110 return Mode::INVALID;
114 * @brief The ComparerInterfaces structure
116 struct ComparerInterfaces
118 std::unordered_set<std::string> mObject;
119 std::vector<std::string> mRequested;
120 Mode mMode = Mode::INVALID;
122 ComparerInterfaces(MatchRule* rule)
123 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::INTERFACES_MATCH_TYPE)>(*rule)))
125 mRequested = {std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).begin(), std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).end()};
128 void Update(Accessible* obj)
131 for(auto& interface : obj->GetInterfaces())
133 mObject.insert(std::move(interface));
137 bool IsRequestEmpty() const
139 return mRequested.empty();
142 bool IsObjectEmpty() const
144 return mObject.empty();
147 bool Compare(CompareFuncExit exit)
149 bool foundAny = false;
150 for(auto& iname : mRequested)
152 bool found = (mObject.find(iname) != mObject.end());
158 if(found == (exit == CompareFuncExit::FIRST_FOUND))
165 }; // ComparerInterfaces struct
168 * @brief The ComparerAttributes structure
170 struct ComparerAttributes
172 std::unordered_map<std::string, std::string> mRequested;
173 std::unordered_map<std::string, std::string> mObject;
174 Mode mMode = Mode::INVALID;
176 ComparerAttributes(MatchRule* rule)
177 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ATTRIBUTES_MATCH_TYPE)>(*rule)))
179 mRequested = std::get<static_cast<std::size_t>(Index::ATTRIBUTES)>(*rule);
182 void Update(Accessible* obj)
184 mObject = obj->GetAttributes();
187 bool IsRequestEmpty() const
189 return mRequested.empty();
192 bool IsObjectEmpty() const
194 return mObject.empty();
197 bool Compare(CompareFuncExit exit)
199 bool foundAny = false;
200 for(auto& iname : mRequested)
202 auto it = mObject.find(iname.first);
203 bool found = it != mObject.end() && iname.second == it->second;
209 if(found == (exit == CompareFuncExit::FIRST_FOUND))
216 }; // ComparerAttributes struct
219 * @brief The ComparerRoles structure
223 using Roles = BitSets<4, Role>;
227 Mode mMode = Mode::INVALID;
229 ComparerRoles(MatchRule* rule)
230 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ROLES_MATCH_TYPE)>(*rule)))
232 mRequested = Roles{std::get<static_cast<std::size_t>(Index::ROLES)>(*rule)};
235 void Update(Accessible* obj)
238 mObject[obj->GetRole()] = true;
242 bool IsRequestEmpty() const
247 bool IsObjectEmpty() const
252 bool Compare(CompareFuncExit exit)
263 return mRequested == (mObject & mRequested);
267 return bool(mObject & mRequested);
271 return bool(mObject & mRequested);
276 }; // ComparerRoles struct
279 * @brief The ComparerStates structure
281 struct ComparerStates
285 Mode mMode = Mode::INVALID;
287 ComparerStates(MatchRule* rule)
288 : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::STATES_MATCH_TYPE)>(*rule)))
290 mRequested = States{std::get<static_cast<std::size_t>(Index::STATES)>(*rule)};
293 void Update(Accessible* obj)
295 mObject = obj->GetStates();
298 bool IsRequestEmpty() const
303 bool IsObjectEmpty() const
308 bool Compare(CompareFuncExit exit)
319 return mRequested == (mObject & mRequested);
323 return bool(mObject & mRequested);
327 return bool(mObject & mRequested);
332 }; // ComparerStates struct
335 bool CompareFunc(T& cmp, Accessible* obj)
337 if(cmp.mMode == Mode::INVALID)
347 if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
355 if(cmp.IsRequestEmpty())
359 if(cmp.IsObjectEmpty())
367 if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
375 if(cmp.IsRequestEmpty() && cmp.IsObjectEmpty())
379 if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
396 if(!cmp.Compare(CompareFuncExit::FIRST_NOT_FOUND))
404 if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
412 if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
444 Comparer(MatchRule* rule)
452 bool operator()(Accessible* obj)
454 return CompareFunc(mInterface, obj) &&
455 CompareFunc(mAttribute, obj) &&
456 CompareFunc(mRole, obj) &&
457 CompareFunc(mState, obj);
460 ComparerInterfaces mInterface;
461 ComparerAttributes mAttribute;
463 ComparerStates mState;
464 }; // BridgeCollection::Comparer struct
467 void BridgeCollection::VisitNodes(Accessible* obj, std::vector<Accessible*>& result, Comparer& comparer, size_t maxCount)
469 if(maxCount > 0 && result.size() >= maxCount)
476 result.emplace_back(obj);
479 for(auto i = 0u; i < obj->GetChildCount(); ++i)
481 VisitNodes(obj->GetChildAtIndex(i), result, comparer, maxCount);
485 DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(MatchRule rule, uint32_t sortBy, int32_t count, bool traverse)
487 std::vector<Accessible*> res;
488 auto self = BridgeBase::FindSelf();
489 auto matcher = Comparer{&rule};
490 VisitNodes(self, res, matcher, count);
492 switch(static_cast<SortOrder>(sortBy))
494 case SortOrder::CANONICAL:
499 case SortOrder::REVERSE_CANONICAL:
501 std::reverse(res.begin(), res.end());
507 throw std::domain_error{"unsupported sorting order"};