Merge "Use Depth attachment on the Capture" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / tizen-wayland / atspi / bridge-accessible.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/accessibility/tizen-wayland/atspi/bridge-accessible.h>
20
21 // EXTERNAL INCLUDES
22 #include <iostream>
23
24 //comment out 2 lines below to get more logs
25 #undef LOG
26 #define LOG() _LoggerEmpty()
27
28 using namespace Dali::Accessibility;
29
30 #define GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH 10000
31
32 BridgeAccessible::BridgeAccessible()
33 {
34 }
35
36 void BridgeAccessible::RegisterInterfaces()
37 {
38   DBus::DBusInterfaceDescription desc{AtspiDbusInterfaceAccessible};
39   AddGetPropertyToInterface( desc, "ChildCount", &BridgeAccessible::GetChildCount );
40   AddGetPropertyToInterface( desc, "Name", &BridgeAccessible::GetName );
41   AddGetPropertyToInterface( desc, "Description", &BridgeAccessible::GetDescription );
42   AddGetPropertyToInterface( desc, "Parent", &BridgeAccessible::GetParent );
43   AddFunctionToInterface( desc, "GetRole", &BridgeAccessible::GetRole );
44   AddFunctionToInterface( desc, "GetRoleName", &BridgeAccessible::GetRoleName );
45   AddFunctionToInterface( desc, "GetLocalizedRoleName", &BridgeAccessible::GetLocalizedRoleName );
46   AddFunctionToInterface( desc, "GetState", &BridgeAccessible::GetStates );
47   AddFunctionToInterface( desc, "GetAttributes", &BridgeAccessible::GetAttributes );
48   AddFunctionToInterface( desc, "GetInterfaces", &BridgeAccessible::GetInterfaces );
49   AddFunctionToInterface( desc, "GetChildAtIndex", &BridgeAccessible::GetChildAtIndex );
50   AddFunctionToInterface( desc, "GetChildren", &BridgeAccessible::GetChildren );
51   AddFunctionToInterface( desc, "GetIndexInParent", &BridgeAccessible::GetIndexInParent );
52   AddFunctionToInterface( desc, "GetNavigableAtPoint", &BridgeAccessible::GetNavigableAtPoint );
53   AddFunctionToInterface( desc, "GetNeighbor", &BridgeAccessible::GetNeighbor );
54   AddFunctionToInterface( desc, "GetDefaultLabelInfo", &BridgeAccessible::GetDefaultLabelInfo );
55   AddFunctionToInterface( desc, "DoGesture", &BridgeAccessible::DoGesture );
56   AddFunctionToInterface( desc, "GetReadingMaterial", &BridgeAccessible::GetReadingMaterial );
57   AddFunctionToInterface( desc, "GetRelationSet", &BridgeAccessible::GetRelationSet );
58   dbusServer.addInterface( "/", desc, true );
59 }
60
61 static bool AcceptObjectCheckRole( Component* obj )
62 {
63   if( !obj )
64     return false;
65   switch( obj->GetRole() )
66   {
67     case Role::APPLICATION:
68     case Role::FILLER:
69     case Role::SCROLL_PANE:
70     case Role::SPLIT_PANE:
71     case Role::WINDOW:
72     case Role::IMAGE:
73     case Role::IMAGE_MAP:
74     case Role::LIST:
75     case Role::ICON:
76     case Role::TOOL_BAR:
77     case Role::REDUNDANT_OBJECT:
78     case Role::COLOR_CHOOSER:
79     case Role::TREE_TABLE:
80     case Role::PAGE_TAB_LIST:
81     case Role::PAGE_TAB:
82     case Role::SPIN_BUTTON:
83     case Role::INPUT_METHOD_WINDOW:
84     case Role::EMBEDDED:
85     case Role::INVALID:
86     case Role::NOTIFICATION:
87     case Role::DATE_EDITOR:
88     case Role::TABLE:
89     {
90       return false;
91     }
92     default:
93     {
94       break;
95     }
96   }
97
98   return true;
99 }
100
101 static bool AcceptObjectCheckRelations( Component* obj)
102 {
103   auto r = obj->GetRelationSet();
104
105   for (const auto& it : r)
106     if (it.relationType == RelationType::CONTROLLED_BY)
107       return false;
108
109   return true;
110 }
111
112 static Component* GetScrollableParent( Accessible* obj )
113 {
114   while( obj )
115   {
116     obj = obj->GetParent();
117     auto comp = dynamic_cast< Component* >( obj );
118     if( comp && comp->IsScrollable() )
119       return comp;
120   }
121   return nullptr;
122 }
123
124 static bool ObjectIsItem( Component* obj )
125 {
126   if( !obj )
127     return false;
128   auto role = obj->GetRole();
129   return role == Role::LIST_ITEM || role == Role::MENU_ITEM;
130 }
131
132 static bool ObjectIsCollapsed( Component* obj )
133 {
134   if( !obj )
135     return false;
136   const auto states = obj->GetStates();
137   return states[State::EXPANDABLE] && !states[State::EXPANDED];
138 }
139
140 static bool OobjectIsZeroSize( Component* obj )
141 {
142   if( !obj )
143     return false;
144   auto extents = obj->GetExtents( CoordType::WINDOW );
145   return extents.height == 0 || extents.width == 0;
146 }
147
148 static bool AcceptObject( Component* obj )
149 {
150   if( !obj )
151     return false;
152   const auto states = obj->GetStates();
153   if( !states[State::VISIBLE] )
154     return false;
155   if( !AcceptObjectCheckRole( obj ) )
156     return false;
157   if ( !AcceptObjectCheckRelations( obj ) )
158     return false;
159   //   if (CALL(get_object_in_relation_by_type, obj, ATSPI_RELATION_CONTROLLED_BY) != NULL) return 0;
160   if ( !AcceptObjectCheckRelations( obj ) )
161     return false;
162   if( !states[State::HIGHLIGHTABLE] )
163     return false;
164
165   if( GetScrollableParent( obj ) != nullptr )
166   {
167     auto parent = dynamic_cast< Component* >( obj->GetParent() );
168
169     if( parent )
170     {
171       return !ObjectIsItem( obj ) || !ObjectIsCollapsed( parent );
172     }
173   }
174   else
175   {
176     if( OobjectIsZeroSize( obj ) )
177     {
178       return false;
179     }
180     if( !states[State::SHOWING] )
181     {
182       return false;
183     }
184   }
185   return true;
186 }
187
188 static bool AcceptObject( Accessible* obj )
189 {
190   auto c = dynamic_cast< Component* >( obj );
191   return AcceptObject( c );
192 }
193
194 static std::string objDump( Component* obj )
195 {
196   if ( !obj )
197     return "nullptr";
198   std::ostringstream o;
199   auto e = obj->GetExtents( CoordType::SCREEN );
200   o << "name: " << obj->GetName() << " extent: (" << e.x << ", "
201       << e.y << "), [" << e.width << ", " << e.height << "]";
202   return o.str();
203 }
204
205 Component * BridgeAccessible::GetObjectInRelation( Accessible * obj, RelationType ralationType )
206 {
207   if ( !obj )
208     return nullptr;
209   for ( auto &relation : obj->GetRelationSet() )
210   {
211     if ( relation.relationType == ralationType )
212     {
213       for ( auto &address : relation.targets )
214       {
215         auto component = dynamic_cast<Component*>( Find( address ) );
216         if ( component )
217           return component;
218       }
219     }
220   }
221   return nullptr;
222 }
223
224 static std::string makeIndent( unsigned int maxRecursionDepth )
225 {
226   return std::string( GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH - maxRecursionDepth, ' ' );
227 }
228
229 Component* BridgeAccessible::CalculateNavigableAccessibleAtPoint( Accessible* root, Point p, CoordType cType, unsigned int maxRecursionDepth )
230 {
231   if( !root || maxRecursionDepth == 0 )
232     return nullptr;
233   auto root_component = dynamic_cast< Component* >( root );
234   LOG() << "CalculateNavigableAccessibleAtPoint: checking: " << makeIndent(maxRecursionDepth) << objDump(root_component);
235
236   if( root_component && !root_component->Contains( p, cType ) )
237     return nullptr;
238
239   auto children = root->GetChildren();
240   for( auto childIt = children.rbegin(); childIt != children.rend(); childIt++ )
241   {
242     //check recursively all children first
243     auto result = CalculateNavigableAccessibleAtPoint( *childIt, p, cType, maxRecursionDepth - 1 );
244     if( result )
245       return result;
246   }
247   if( root_component )
248   {
249     //Found a candidate, all its children are already checked
250     auto controledBy = GetObjectInRelation( root_component, RelationType::CONTROLLED_BY );
251     if ( !controledBy )
252       controledBy = root_component;
253
254     if ( controledBy->IsProxy() || AcceptObject( controledBy ) )
255     {
256       LOG() << "CalculateNavigableAccessibleAtPoint: found:    " << makeIndent(maxRecursionDepth) << objDump( root_component );
257       return controledBy;
258     }
259   }
260   return nullptr;
261 }
262
263 BridgeAccessible::ReadingMaterialType BridgeAccessible::GetReadingMaterial()
264 {
265   auto self = FindSelf();
266   auto attributes = self->GetAttributes();
267   auto name = self->GetName();
268   std::string labeledByName = "";
269   std::string textIfceName = "";
270   auto role = static_cast< uint32_t >( self->GetRole() );
271   auto states = self->GetStates();
272   auto localizedName = self->GetLocalizedRoleName();
273   auto childCount = static_cast< int32_t >( self->GetChildCount() );
274
275   double currentValue = 0.0;
276   double minimumIncrement = 0.0;
277   double maximumValue = 0.0;
278   double minimumValue = 0.0;
279
280   auto description = self->GetDescription();
281   auto indexInParent = static_cast< int32_t >( self->GetIndexInParent() );
282   bool isSelectedInParent = false;
283   bool hasCheckBoxChild = false;
284   int32_t firstSelectedChildIndex = 0;
285   int32_t selectedChildCount = 0;
286
287   for( auto i = 0u; i < static_cast< size_t >( childCount ); ++i )
288   {
289     auto q = self->GetChildAtIndex( i );
290     auto s = q->GetStates();
291     if( s[State::SELECTABLE] )
292     {
293       ++selectedChildCount;
294       if( s[State::SELECTED] )
295       {
296         if( firstSelectedChildIndex < 0 )
297           firstSelectedChildIndex = static_cast< int32_t >( i );
298       }
299     }
300     if( q->GetRole() == Role::CHECK_BOX )
301       hasCheckBoxChild = true;
302   }
303
304   int32_t listChildrenCount = 0;
305   Accessible* parent = self->GetParent();
306   auto parentStateSet = parent ? parent->GetStates() : States{};
307   auto parentChildCount = parent ? static_cast< int32_t >( parent->GetChildCount() ) : 0;
308   auto parentRole = static_cast< uint32_t >( parent ? parent->GetRole() : Role{} );
309   Accessible* describedByObject = nullptr;
310
311   return {
312       attributes,
313       name,
314       labeledByName,
315       textIfceName,
316       role,
317       states,
318       localizedName,
319       childCount,
320       currentValue,
321       minimumIncrement,
322       maximumValue,
323       minimumValue,
324       description,
325       indexInParent,
326       isSelectedInParent,
327       hasCheckBoxChild,
328       listChildrenCount,
329       firstSelectedChildIndex,
330       parent,
331       parentStateSet,
332       parentChildCount,
333       parentRole,
334       selectedChildCount,
335       describedByObject};
336 }
337
338 DBus::ValueOrError< bool > BridgeAccessible::DoGesture( Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime )
339 {
340  return FindSelf()->DoGesture( Dali::Accessibility::GestureInfo {type, xBeg, xEnd, yBeg, yEnd, state, eventTime});
341 }
342
343 DBus::ValueOrError< Accessible*, uint8_t, Accessible* > BridgeAccessible::GetNavigableAtPoint( int32_t x, int32_t y, uint32_t coordType )
344 {
345   Accessible* deputy = nullptr;
346   auto accessible = FindSelf();
347   auto cType = static_cast< CoordType >( coordType );
348   LOG() << "GetNavigableAtPoint: " << x << ", " << y << " type: " << coordType;
349   auto component = CalculateNavigableAccessibleAtPoint( accessible, {x, y}, cType, GET_NAVIGABLE_AT_POINT_MAX_RECURSION_DEPTH );
350   bool recurse = false;
351   if( component )
352   {
353     const auto states = component->GetStates();
354     if( states[State::MODAL] )
355     {
356       component = nullptr;
357     }
358   }
359   if( component )
360   {
361     recurse = component->IsProxy();
362   }
363   //TODO: add deputy
364   return {component, recurse, deputy};
365 }
366
367 static bool CheckChainEndWithAttribute( Accessible* obj, unsigned char forward )
368 {
369   if( !obj )
370     return false;
371   auto attrs = obj->GetAttributes();
372   for( auto& attr : attrs )
373   {
374     if( attr.first == "relation_chain_end" )
375     {
376       if( ( attr.second == "prev,end" && forward == 0 ) || ( attr.second == "next,end" && forward == 1 ) || attr.second == "prev,next,end" )
377       {
378         return true;
379       }
380     }
381   }
382   return false;
383 }
384
385 static Accessible* DeputyOfProxyInParentGet( Accessible* obj )
386 {
387   return nullptr;
388 }
389
390 Accessible* BridgeAccessible::GetCurrentlyHighlighted()
391 {
392   //TODO: add currently highlighted object
393   return nullptr;
394 }
395
396 std::vector< Accessible* > BridgeAccessible::ValidChildrenGet( const std::vector< Accessible* >& children, Accessible* start, Accessible* root )
397 {
398   return children;
399 }
400
401 static bool DeputyIs( Accessible* obj )
402 {
403   //TODO: add deputy
404   return false;
405 }
406
407 static Accessible* ProxyInParentGet( Accessible* obj )
408 {
409   if( !obj )
410     return nullptr;
411   auto children = obj->GetChildren();
412   for( auto& child : children )
413   {
414     if( child->IsProxy() )
415       return child;
416   }
417   return nullptr;
418 }
419
420 static bool ObjectRoleIsAcceptableWhenNavigatingNextPrev( Accessible* obj )
421 {
422   if( !obj )
423     return false;
424   auto role = obj->GetRole();
425   return role != Role::POPUP_MENU && role != Role::DIALOG;
426 }
427
428 template < class T >
429 struct CycleDetection
430 {
431   CycleDetection( const T value ) : key( value ), currentSearchSize( 1 ), counter( 1 ) {}
432   bool check( const T value )
433   {
434     if( key == value )
435       return true;
436     if( --counter == 0 )
437     {
438       currentSearchSize <<= 1;
439       if( currentSearchSize == 0 )
440         return true; // UNDEFINED BEHAVIOR
441       counter = currentSearchSize;
442       key = value;
443     }
444     return false;
445   }
446   T key;
447   unsigned int currentSearchSize;
448   unsigned int counter;
449 };
450
451 static Accessible* FindNonDefunctChild( const std::vector< Accessible* >& children, unsigned int currentIndex, unsigned char forward )
452 {
453   unsigned int childrenCount = children.size();
454   for( ; currentIndex < childrenCount; forward ? ++currentIndex : --currentIndex )
455   {
456     Accessible* n = children[currentIndex];
457     if( n && !n->GetStates()[State::DEFUNCT] )
458       return n;
459   }
460   return nullptr;
461 }
462
463 static Accessible* DirectionalDepthFirstSearchTryNonDefunctChild( Accessible* node, const std::vector< Accessible* >& children, unsigned char forward )
464 {
465   if( !node )
466     return nullptr;
467   auto childrenCount = children.size();
468   if( childrenCount > 0 )
469   {
470     const bool isShowing = GetScrollableParent( node ) == nullptr ? node->GetStates()[State::SHOWING] : true;
471     if( isShowing )
472     {
473       return FindNonDefunctChild( children, forward ? 0 : childrenCount - 1, forward );
474     }
475   }
476   return nullptr;
477 }
478
479 Accessible* BridgeAccessible::GetNextNonDefunctSibling( Accessible* obj, Accessible* start, Accessible* root, unsigned char forward )
480 {
481   if( !obj )
482     return nullptr;
483   auto parent = obj->GetParent();
484   if( !parent )
485     return nullptr;
486
487   auto children = ValidChildrenGet( parent->GetChildren(), start, root );
488
489   unsigned int children_count = children.size();
490   if( children_count == 0 )
491   {
492     return nullptr;
493   }
494   unsigned int current = 0;
495   for( ; current < children_count && children[current] != obj; ++current )
496     ;
497   if( current >= children_count )
498   {
499     return nullptr;
500   }
501   forward ? ++current : --current;
502   auto ret = FindNonDefunctChild( children, current, forward );
503   return ret;
504 }
505
506 Accessible* BridgeAccessible::DirectionalDepthFirstSearchTryNonDefunctSibling( bool& all_children_visited, Accessible* node, Accessible* start, Accessible* root, unsigned char forward )
507 {
508   while( true )
509   {
510     Accessible* sibling = GetNextNonDefunctSibling( node, start, root, forward );
511     if( sibling )
512     {
513       node = sibling;
514       all_children_visited = false;
515       break;
516     }
517     // walk up...
518     node = node->GetParent();
519     if( node == nullptr || node == root )
520       return nullptr;
521
522     // in backward traversing stop the walk up on parent
523     if( !forward )
524       break;
525   }
526   return node;
527 }
528
529 Accessible* BridgeAccessible::CalculateNeighbor( Accessible* root, Accessible* start, unsigned char forward, BridgeAccessible::GetNeighborSearchMode search_mode )
530 {
531   if( start && CheckChainEndWithAttribute( start, forward ) )
532     return start;
533   if( root && root->GetStates()[State::DEFUNCT] )
534     return NULL;
535   if( start && start->GetStates()[State::DEFUNCT] )
536   {
537     start = NULL;
538     forward = 1;
539   }
540
541   if( search_mode == BridgeAccessible::GetNeighborSearchMode::recurseToOutside )
542   {
543     // This only works if we navigate backward, and it is not possible to
544     // find in embedded process. In this case the deputy should be used */
545     return DeputyOfProxyInParentGet( start );
546   }
547
548   Accessible* node = start ? start : root;
549   if( !node )
550     return nullptr;
551
552   // initialization of all-children-visited flag for start node - we assume
553   // that when we begin at start node and we navigate backward, then all children
554   // are visited, so navigation will ignore start's children and go to
555   // previous sibling available.
556   // Regarding condtion (start != root):
557   // The last object can be found only if all_children_visited is false.
558   // The start is same with root, when looking for the last object.
559   bool all_children_visited = ( start != root ) && ( search_mode != BridgeAccessible::GetNeighborSearchMode::recurseFromRoot && !forward );
560   // true, if starting element should be ignored. this is only used in rare case of
561   // recursive search failing to find an object.
562   // consider tree, where element A on bus BUS_A has child B on bus BUS_B. when going "next" from
563   // element A algorithm has to descend into BUS_B and search element B and its children. this is done
564   // by returning to our caller object B with special flag set (meaning - continue the search from B on bus BUS_B).
565   // if next object will be found there (on BUS_B), then search ends. but if not, then our caller will find it out
566   // and will call us again with object A and flag search_mode set to NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING.
567   // this flag means, that object A was already checked previously and we should skip it and its children.
568   bool force_next = ( search_mode == BridgeAccessible::GetNeighborSearchMode::continueAfterFailedRecursion );
569
570   CycleDetection< Accessible* > cycleDetection( node );
571   while( node )
572   {
573     if( node->GetStates()[State::DEFUNCT] )
574       return nullptr;
575
576     // always accept proxy object from different world
577     if( !force_next && node->IsProxy() )
578       return node;
579
580     auto children = node->GetChildren();
581     children = ValidChildrenGet( children, start, root );
582
583     // do accept:
584     // 1. not start node
585     // 2. parent after all children in backward traversing
586     // 3. Nodes with roles: ATSPI_ROLE_PAGE_TAB, ATSPI_ROLE_POPUP_MENU and ATSPI_ROLE_DIALOG, only when looking for first or last element.
587     //    Objects with those roles shouldnt be reachable, when navigating next / prev.
588     bool all_children_visited_or_moving_forward = ( children.size() == 0 || forward || all_children_visited );
589     if( !force_next && node != start && all_children_visited_or_moving_forward && AcceptObject( node ) )
590     {
591       if( start == NULL || ObjectRoleIsAcceptableWhenNavigatingNextPrev( node ) )
592         return node;
593     }
594
595     Accessible* next_related_in_direction = !force_next ? GetObjectInRelation( node, forward ? RelationType::FLOWS_TO : RelationType::FLOWS_FROM ) : nullptr;
596     // force_next means that the search_mode is NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING
597     // in this case the node is elm_layout which is parent of proxy object.
598     // There is an access object working for the proxy object, and the access
599     // object could have relation information. This relation information should
600     // be checked first before using the elm_layout as a node.
601     if( force_next && forward )
602     {
603       auto deputy = DeputyOfProxyInParentGet( node );
604       next_related_in_direction =
605           GetObjectInRelation( deputy, forward ? RelationType::FLOWS_TO : RelationType::FLOWS_FROM );
606     }
607
608     if( next_related_in_direction && start->GetStates()[State::DEFUNCT] )
609       next_related_in_direction = NULL;
610     unsigned char want_cycle_detection = 0;
611     if( next_related_in_direction )
612     {
613       // Check next_related_in_direction is deputy object
614       Accessible* parent;
615       if( !forward )
616       {
617         // If the prev object is deputy, then go to inside of its proxy first
618         if( DeputyIs( next_related_in_direction ) )
619         {
620           parent = next_related_in_direction->GetParent();
621           next_related_in_direction = ProxyInParentGet( parent );
622         }
623       }
624       else
625       {
626         // If current object is deputy, and it has relation next object,
627         // then do not use the relation next object, and use proxy first
628         if( DeputyIs( node ) )
629         {
630           parent = node->GetParent();
631           next_related_in_direction = ProxyInParentGet( parent );
632         }
633       }
634       node = next_related_in_direction;
635       want_cycle_detection = 1;
636     }
637     else
638     {
639       auto child = !force_next && !all_children_visited ? DirectionalDepthFirstSearchTryNonDefunctChild( node, children, forward ) : nullptr;
640       if( child )
641       {
642         want_cycle_detection = 1;
643       }
644       else
645       {
646         if( !force_next && node == root )
647           return NULL;
648         all_children_visited = true;
649         child = DirectionalDepthFirstSearchTryNonDefunctSibling( all_children_visited, node, start, root, forward );
650       }
651       node = child;
652     }
653     force_next = 0;
654     if( want_cycle_detection && cycleDetection.check( node ) )
655     {
656       return NULL;
657     }
658   }
659   return NULL;
660 }
661
662 DBus::ValueOrError< Accessible*, uint8_t > BridgeAccessible::GetNeighbor( std::string rootPath, int32_t direction, int32_t search_mode )
663 {
664   auto start = FindSelf();
665   rootPath = StripPrefix( rootPath );
666   auto root = !rootPath.empty() ? Find( rootPath ) : nullptr;
667   auto accessible = CalculateNeighbor( root, start, direction == 1, static_cast< GetNeighborSearchMode >( search_mode ) );
668   unsigned char recurse = 0;
669   if( accessible )
670   {
671     recurse = accessible->IsProxy();
672   }
673   return {accessible, recurse};
674 }
675
676 Accessible* BridgeAccessible::GetParent()
677 {
678   // NOTE: currently bridge supports single application root element.
679   // only element set as application root might return nullptr from GetParent
680   // if you want more, then you need to change setApplicationRoot to
681   // add/remove ApplicationRoot and make roots a vector.
682   auto p = FindSelf()->GetParent();
683   assert( p );
684   return p;
685 }
686 DBus::ValueOrError< std::vector< Accessible* > > BridgeAccessible::GetChildren()
687 {
688   return FindSelf()->GetChildren();
689 }
690 std::string BridgeAccessible::GetDescription()
691 {
692   return FindSelf()->GetDescription();
693 }
694 DBus::ValueOrError< uint32_t > BridgeAccessible::GetRole()
695 {
696   return static_cast< unsigned int >( FindSelf()->GetRole() );
697 }
698 DBus::ValueOrError< std::string > BridgeAccessible::GetRoleName()
699 {
700   return FindSelf()->GetRoleName();
701 }
702 DBus::ValueOrError< std::string > BridgeAccessible::GetLocalizedRoleName()
703 {
704   return FindSelf()->GetLocalizedRoleName();
705 }
706 DBus::ValueOrError< int32_t > BridgeAccessible::GetIndexInParent()
707 {
708   return FindSelf()->GetIndexInParent();
709 }
710 DBus::ValueOrError< std::array< uint32_t, 2 > > BridgeAccessible::GetStates()
711 {
712   return FindSelf()->GetStates().GetRawData();
713 }
714 DBus::ValueOrError< std::unordered_map< std::string, std::string > > BridgeAccessible::GetAttributes()
715 {
716   return FindSelf()->GetAttributes();
717 }
718 DBus::ValueOrError< std::vector< std::string > > BridgeAccessible::GetInterfaces()
719 {
720   return FindSelf()->GetInterfaces();
721 }
722 int BridgeAccessible::GetChildCount()
723 {
724   return FindSelf()->GetChildCount();
725 }
726 DBus::ValueOrError< Accessible* > BridgeAccessible::GetChildAtIndex( int index )
727 {
728   if( index < 0 )
729     throw std::domain_error{"negative index (" + std::to_string( index ) + ")"};
730   return FindSelf()->GetChildAtIndex( static_cast< size_t >( index ) );
731 }
732
733 std::string BridgeAccessible::GetName()
734 {
735   return FindSelf()->GetName();
736 }
737
738 DBus::ValueOrError< Accessible*, uint32_t , std::unordered_map< std::string, std::string > > BridgeAccessible::GetDefaultLabelInfo()
739 {
740   auto defaultLabel = FindSelf()->GetDefaultLabel();
741   return {defaultLabel, static_cast< uint32_t >( defaultLabel->GetRole() ) , defaultLabel->GetAttributes()};
742 }
743
744 DBus::ValueOrError<std::vector< BridgeAccessible::Relation >> BridgeAccessible::GetRelationSet()
745 {
746   auto relations = FindSelf()->GetRelationSet();
747   std::vector< BridgeAccessible::Relation > ret;
748
749   for (auto &it : relations)
750     ret.emplace_back(Relation{static_cast<uint32_t>(it.relationType), it.targets});
751
752   return ret;
753 }