[AT-SPI] fix a crash on scroll-view 27/271527/6
authorShinwoo Kim <cinoo.kim@samsung.com>
Tue, 22 Feb 2022 11:37:51 +0000 (20:37 +0900)
committerShinwoo Kim <cinoo.kim@samsung.com>
Thu, 17 Mar 2022 03:05:25 +0000 (12:05 +0900)
This patch is resolving the crash with following stack.

__cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
Dali::Toolkit::Internal::ScrollView::ScrollTo
Dali::Toolkit::ScrollView::ScrollTo
Dali::Toolkit::Internal::ScrollView::AccessibleImpl::ScrollToChild
Dali::Toolkit::DevelControl::ControlAccessible::ScrollToSelf
Dali::Toolkit::DevelControl::ControlAccessible::GrabHighlight
Dali::Toolkit::DevelControl::GrabAccessibilityHighlight
Dali::Toolkit::Internal::AccessibilityManager::SetCurrentFocusActor
Dali::Toolkit::AccessibilityManager::SetCurrentFocusActor

It is not able to call ScrollView::ScrollTo,
if parent of child in ScrollTo is not the scrollView.

But the ControlAccessible can call ScrollTo when the parent can be
one of child's parents(ancestor).

Change-Id: Ie88c652f8a1ca348f6b8cbe9f95484a5eb5bf508

automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp

index f75d224..c156b6e 100644 (file)
@@ -11,6 +11,7 @@
 #include <dali-toolkit/devel-api/controls/buttons/toggle-button.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/popup/popup.h>
+#include <dali-toolkit/devel-api/controls/table-view/table-view.h>
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/common/stage.h>
 #include <cstdlib>
@@ -1075,6 +1076,17 @@ int UtcDaliAccessibilityScrollToChildScrollView(void)
   actorB.SetProperty( Dali::Actor::Property::POSITION, positionB );
   scrollView.Add(actorB);
 
+  TableView tableView = TableView::New( 2, 2 ); // 2 by 2 grid.
+  tableView.SetProperty( Actor::Property::SIZE, Vector2(100.0f, 100.0f) );
+  scrollView.Add(tableView);
+
+  PushButton actorC = PushButton::New();
+  actorC.SetProperty( Actor::Property::SIZE, Vector2(50.0f, 50.0f) );
+  tableView.AddChild( actorC, TableView::CellPosition( 0, 0 ) );
+
+  PushButton actorD = PushButton::New();
+  application.GetScene().Add( actorD );
+
   Wait(application);
 
   auto* accessibleParent = dynamic_cast<DevelControl::ControlAccessible*>(Dali::Accessibility::Accessible::Get(scrollView));
@@ -1083,12 +1095,22 @@ int UtcDaliAccessibilityScrollToChildScrollView(void)
   DALI_TEST_CHECK(accessibleA);
   auto* accessibleB = dynamic_cast<DevelControl::ControlAccessible*>(Dali::Accessibility::Accessible::Get(actorB));
   DALI_TEST_CHECK(accessibleB);
+  auto* accessibleC = dynamic_cast<DevelControl::ControlAccessible*>(Dali::Accessibility::Accessible::Get(actorC));
+  DALI_TEST_CHECK(accessibleC);
 
   accessibleA->GrabHighlight(); // == scrollView.ScrollTo(actorA)
   Wait(application);
   accessibleB->GrabHighlight(); // == scrollView.ScrollTo(actorB)
   Wait(application);
 
+  // scrollView is ancestor of actorC
+  // This should work without a crash
+  accessibleC->GrabHighlight(); // == scrollView.ScrollTo(actorC)
+  Wait(application);
+
+  // negative testcase calling ScrollToChild using non-child actor
+  accessibleParent->ScrollToChild(actorD);
+
   Dali::Accessibility::TestEnableSC( false );
   END_TEST;
 }
index 712cb17..218f6ae 100644 (file)
@@ -1270,6 +1270,19 @@ bool ScrollView::AccessibleImpl::ScrollToChild(Actor child)
     return false;
   }
 
+  // child can be one of descendants
+  // find direct child of ScrollView to avoid the ASSERT in ScrollTo
+  auto parent = child.GetParent();
+  while (parent && parent != Self())
+  {
+    child = parent;
+    parent = child.GetParent();
+  }
+  if (!parent)
+  {
+    return false;
+  }
+
   // FIXME: ScrollTo does not work (snaps back to original position)
   scrollView.ScrollTo(child, scrollView.GetScrollFlickDuration());
   return true;