[Tizen][ATSPI) Fix native TC fails 03/214403/1 submit/tizen/20190921.104130 submit/tizen/20190921.112950
authordongsug.song <dongsug.song@samsung.com>
Sat, 21 Sep 2019 10:13:39 +0000 (19:13 +0900)
committerdongsug.song <dongsug.song@samsung.com>
Sat, 21 Sep 2019 10:13:39 +0000 (19:13 +0900)
Change-Id: Id33ef233f74514eefa6be4751ac476fcd5089be5

dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index e752eda..9eeab0e
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <cstring> // for strcmp
 #include <dali/public-api/actors/layer.h>
+#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
 #include <dali/devel-api/adaptor-framework/sound-player.h>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/devel-api/events/hit-test-algorithm.h>
@@ -31,7 +32,6 @@
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
-#include <dali/devel-api/adaptor-framework/accessibility.h>
 
 namespace Dali
 {
@@ -42,7 +42,84 @@ namespace Toolkit
 namespace Internal
 {
 
+namespace // unnamed namespace
+{
+
+// Signals
+
+const char* const SIGNAL_FOCUS_CHANGED =           "focusChanged";
+const char* const SIGNAL_FOCUS_OVERSHOT =          "focusOvershot";
+const char* const SIGNAL_FOCUSED_ACTOR_ACTIVATED = "focusedActorActivated";
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FOCUS_MANAGER");
+#endif
+
+const char* const ACTOR_FOCUSABLE("focusable");
+const char* const IS_FOCUS_GROUP("isFocusGroup");
+
+const char* FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "B16-8_TTS_focus.9.png";
+
+const char* FOCUS_SOUND_FILE = DALI_SOUND_DIR "Focus.ogg";
+const char* FOCUS_CHAIN_END_SOUND_FILE = DALI_SOUND_DIR "End_of_List.ogg";
+
+/**
+ * The function to be used in the hit-test algorithm to check whether the actor is hittable.
+ */
+bool IsActorFocusableFunction(Actor actor, Dali::HitTestAlgorithm::TraverseType type)
+{
+  bool hittable = false;
+
+  switch (type)
+  {
+    case Dali::HitTestAlgorithm::CHECK_ACTOR:
+    {
+      // Check whether the actor is visible and not fully transparent.
+      if( actor.IsVisible()
+       && actor.GetCurrentWorldColor().a > 0.01f) // not FULLY_TRANSPARENT
+      {
+        // Check whether the actor is focusable
+        Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
+        if(propertyActorFocusable != Property::INVALID_INDEX)
+        {
+          hittable = actor.GetProperty<bool>(propertyActorFocusable);
+        }
+      }
+      break;
+    }
+    case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
+    {
+      if( actor.IsVisible() ) // Actor is visible, if not visible then none of its children are visible.
+      {
+        hittable = true;
+      }
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+
+  return hittable;
+};
+
+}
+
 AccessibilityManager::AccessibilityManager()
+: mCurrentFocusActor(FocusIDPair(0, 0)),
+  mCurrentGesturedActor(),
+  mFocusIndicatorActor(),
+  mPreviousPosition( 0.0f, 0.0f ),
+  mRecursiveFocusMoveCounter(0),
+  mIsWrapped(false),
+  mIsFocusWithinGroup(false),
+  mIsEndcapFeedbackEnabled(false),
+  mIsEndcapFeedbackPlayed(false),
+  mIsAccessibilityTtsEnabled(false),
+  mTtsCreated(false),
+  mIsFocusIndicatorEnabled(false),
+  mContinuousPlayMode(false)
 {
 }
 
@@ -52,118 +129,1251 @@ AccessibilityManager::~AccessibilityManager()
 
 void AccessibilityManager::Initialise()
 {
+  AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
+  adaptor.SetActionHandler(*this);
+  adaptor.SetGestureHandler(*this);
+
+  ChangeAccessibilityStatus();
+}
+
+AccessibilityManager::ActorAdditionalInfo AccessibilityManager::GetActorAdditionalInfo(const unsigned int actorID) const
+{
+  ActorAdditionalInfo data;
+  IDAdditionalInfoConstIter iter = mIDAdditionalInfoContainer.find(actorID);
+  if(iter != mIDAdditionalInfoContainer.end())
+  {
+    data = (*iter).second;
+  }
+
+  return data;
+}
+
+void AccessibilityManager::SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order)
+{
+  ActorAdditionalInfo actorInfo = GetActorAdditionalInfo(actorID);
+  actorInfo.mFocusOrder = order;
+  mIDAdditionalInfoContainer.erase(actorID);
+  mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, actorInfo));
 }
 
 void AccessibilityManager::SetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type, const std::string& text)
 {
+  if(actor)
+  {
+    unsigned int actorID = actor.GetId();
+
+    ActorAdditionalInfo info = GetActorAdditionalInfo(actorID);
+    info.mAccessibilityAttributes[type] = text;
+
+    mIDAdditionalInfoContainer.erase(actorID);
+    mIDAdditionalInfoContainer.insert(IDAdditionalInfoPair(actorID, info));
+  }
 }
 
 std::string AccessibilityManager::GetAccessibilityAttribute(Actor actor, Toolkit::AccessibilityManager::AccessibilityAttribute type) const
 {
-  return "";
+  std::string text;
+
+  if(actor)
+  {
+    ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
+    text = data.mAccessibilityAttributes[type];
+  }
+
+  return text;
 }
 
 void AccessibilityManager::SetFocusOrder(Actor actor, const unsigned int order)
 {
+  // Do nothing if the focus order of the actor is not changed.
+  if(actor && GetFocusOrder(actor) != order)
+  {
+    // Firstly delete the actor from the focus chain if it's already there with a different focus order.
+    mFocusIDContainer.erase(GetFocusOrder(actor));
+
+    // Create/retrieve actor focusable property
+    Property::Index propertyActorFocusable = actor.RegisterProperty( ACTOR_FOCUSABLE, true, Property::READ_WRITE );
+
+    if(order == 0)
+    {
+      // The actor is not focusable without a defined focus order.
+      actor.SetProperty(propertyActorFocusable, false);
+
+      // If the actor is currently being focused, it should clear the focus
+      if(actor == GetCurrentFocusActor())
+      {
+        ClearFocus();
+      }
+    }
+    else // Insert the actor to the focus chain
+    {
+      // Check whether there is another actor in the focus chain with the same focus order already.
+      FocusIDIter focusIDIter = mFocusIDContainer.find(order);
+      if(focusIDIter != mFocusIDContainer.end())
+      {
+        // We need to increase the focus order of that actor and all the actors followed it
+        // in the focus chain.
+        FocusIDIter lastIter = mFocusIDContainer.end();
+        --lastIter;//We want forward iterator to the last element here
+        mFocusIDContainer.insert(FocusIDPair((*lastIter).first + 1, (*lastIter).second));
+
+        // Update the actor's focus order in its additional data
+        SynchronizeActorAdditionalInfo((*lastIter).second, (*lastIter).first + 1);
+
+        for(FocusIDIter iter = lastIter; iter != focusIDIter; iter--)
+        {
+          FocusIDIter previousIter = iter;
+          --previousIter;//We want forward iterator to the previous element here
+          unsigned int actorID = (*previousIter).second;
+          (*iter).second = actorID;
+
+          // Update the actor's focus order in its additional data
+          SynchronizeActorAdditionalInfo(actorID, (*iter).first);
+        }
+
+        mFocusIDContainer.erase(order);
+      }
+
+      // The actor is focusable
+      actor.SetProperty(propertyActorFocusable, true);
+
+      // Now we insert the actor into the focus chain with the specified focus order
+      mFocusIDContainer.insert(FocusIDPair(order, actor.GetId()));
+    }
+
+    // Update the actor's focus order in its additional data
+    SynchronizeActorAdditionalInfo(actor.GetId(), order);
+  }
 }
 
 unsigned int AccessibilityManager::GetFocusOrder(Actor actor) const
 {
-  return 0;
+  unsigned int focusOrder = 0;
+
+  if(actor)
+  {
+    ActorAdditionalInfo data = GetActorAdditionalInfo(actor.GetId());
+    focusOrder = data.mFocusOrder;
+  }
+
+  return focusOrder;
 }
 
 unsigned int AccessibilityManager::GenerateNewFocusOrder() const
 {
-  return 0;
+  unsigned int order = 1;
+  FocusIDContainer::const_reverse_iterator iter = mFocusIDContainer.rbegin();
+
+  if(iter != mFocusIDContainer.rend())
+  {
+    order = (*iter).first + 1;
+  }
+
+  return order;
 }
 
 Actor AccessibilityManager::GetActorByFocusOrder(const unsigned int order)
 {
-  return {};
+  Actor actor = Actor();
+
+  FocusIDIter focusIDIter = mFocusIDContainer.find(order);
+  if(focusIDIter != mFocusIDContainer.end())
+  {
+    Actor rootActor = Stage::GetCurrent().GetRootLayer();
+    actor = rootActor.FindChildById(mFocusIDContainer[order]);
+  }
+
+  return actor;
 }
 
 bool AccessibilityManager::SetCurrentFocusActor(Actor actor)
 {
+  if(actor)
+  {
+    return DoSetCurrentFocusActor(actor.GetId());
+  }
+
+  return false;
+}
+
+bool AccessibilityManager::DoSetCurrentFocusActor(const unsigned int actorID)
+{
+  Actor rootActor = Stage::GetCurrent().GetRootLayer();
+
+  // If the group mode is enabled, check which focus group the current focused actor belongs to
+  Actor focusGroup;
+  if(mIsFocusWithinGroup)
+  {
+    focusGroup = GetFocusGroup(GetCurrentFocusActor());
+  }
+
+  if(!focusGroup)
+  {
+    focusGroup = rootActor;
+  }
+
+  Actor actor = focusGroup.FindChildById(actorID);
+
+  // Check whether the actor is in the stage
+  if(actor)
+  {
+    // Check whether the actor is focusable
+    bool actorFocusable = false;
+    Property::Index propertyActorFocusable = actor.GetPropertyIndex(ACTOR_FOCUSABLE);
+    if(propertyActorFocusable != Property::INVALID_INDEX)
+    {
+      actorFocusable = actor.GetProperty<bool>(propertyActorFocusable);
+    }
+
+    // Go through the actor's hierarchy to check whether the actor is visible
+    bool actorVisible = actor.IsVisible();
+    Actor parent = actor.GetParent();
+    while (actorVisible && parent && parent != rootActor)
+    {
+      actorVisible = parent.IsVisible();
+      parent = parent.GetParent();
+    }
+
+    // Check whether the actor is fully transparent
+    bool actorOpaque = actor.GetCurrentWorldColor().a > 0.01f;
+
+    // Set the focus only when the actor is focusable and visible and not fully transparent
+    if(actorVisible && actorFocusable && actorOpaque)
+    {
+      // Draw the focus indicator upon the focused actor
+      if( mIsFocusIndicatorEnabled )
+      {
+        actor.Add( GetFocusIndicatorActor() );
+      }
+
+      // Send notification for the change of focus actor
+      mFocusChangedSignal.Emit( GetCurrentFocusActor(), actor );
+
+      // Save the current focused actor
+      mCurrentFocusActor = FocusIDPair(GetFocusOrder(actor), actorID);
+
+      if(mIsAccessibilityTtsEnabled)
+      {
+        Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
+        if(soundPlayer)
+        {
+          soundPlayer.PlaySound(FOCUS_SOUND_FILE);
+        }
+
+        // Play the accessibility attributes with the TTS player.
+        Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
+
+        // Combine attribute texts to one text
+        std::string informationText;
+        for(int i = 0; i < Toolkit::AccessibilityManager::ACCESSIBILITY_ATTRIBUTE_NUM; i++)
+        {
+          if(!GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i].empty())
+          {
+            if( i > 0 )
+            {
+              informationText += ", "; // for space time between each information
+            }
+            informationText += GetActorAdditionalInfo(actorID).mAccessibilityAttributes[i];
+          }
+        }
+        player.Play(informationText);
+      }
+
+      return true;
+    }
+  }
+
+  DALI_LOG_WARNING("[%s:%d] FAILED\n", __FUNCTION__, __LINE__);
   return false;
 }
 
 Actor AccessibilityManager::GetCurrentFocusActor()
 {
-  return {};
+  Actor rootActor = Stage::GetCurrent().GetRootLayer();
+  return rootActor.FindChildById(mCurrentFocusActor.second);
 }
 
 Actor AccessibilityManager::GetCurrentFocusGroup()
 {
-  return {};
+  return GetFocusGroup(GetCurrentFocusActor());
 }
 
 unsigned int AccessibilityManager::GetCurrentFocusOrder()
 {
-  return 0;
+  return mCurrentFocusActor.first;
 }
 
 bool AccessibilityManager::MoveFocusForward()
 {
-  return false;
+  bool ret = false;
+  mRecursiveFocusMoveCounter = 0;
+
+  FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
+  if(focusIDIter != mFocusIDContainer.end())
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
+    ret = DoMoveFocus(focusIDIter, true, mIsWrapped);
+  }
+  else
+  {
+    // TODO: if there is not focused actor, move first actor
+    if(!mFocusIDContainer.empty())
+    {
+      //if there is not focused actor, move 1st actor
+      focusIDIter = mFocusIDContainer.begin(); // TODO: I'm not sure it was sorted.
+      DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
+      ret = DoSetCurrentFocusActor((*focusIDIter).second);
+    }
+  }
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
+
+  return ret;
 }
 
 bool AccessibilityManager::MoveFocusBackward()
 {
-  return false;
+  bool ret = false;
+  mRecursiveFocusMoveCounter = 0;
+
+  FocusIDIter focusIDIter = mFocusIDContainer.find(mCurrentFocusActor.first);
+  if(focusIDIter != mFocusIDContainer.end())
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
+    ret = DoMoveFocus(focusIDIter, false, mIsWrapped);
+  }
+  else
+  {
+    // TODO: if there is not focused actor, move last actor
+    if(!mFocusIDContainer.empty())
+    {
+      //if there is not focused actor, move last actor
+      focusIDIter = mFocusIDContainer.end();
+      --focusIDIter;//We want forward iterator to the last element here
+      DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
+      ret = DoSetCurrentFocusActor((*focusIDIter).second);
+    }
+  }
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "[%s] %s\n", __FUNCTION__, ret?"SUCCEED!!!":"FAILED!!!");
+
+  return ret;
+}
+
+void AccessibilityManager::DoActivate(Actor actor)
+{
+  if(actor)
+  {
+    Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+    if(control)
+    {
+      // Notify the control that it is activated
+      GetImplementation( control ).AccessibilityActivate();
+    }
+
+    // Send notification for the activation of focused actor
+    mFocusedActorActivatedSignal.Emit(actor);
+  }
 }
 
 void AccessibilityManager::ClearFocus()
 {
+  Actor actor = GetCurrentFocusActor();
+  if( actor && mFocusIndicatorActor )
+  {
+    actor.Remove( mFocusIndicatorActor );
+  }
+
+  mCurrentFocusActor = FocusIDPair(0, 0);
+
+  // Send notification for the change of focus actor
+  mFocusChangedSignal.Emit(actor, Actor());
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    // Stop the TTS playing if any
+    Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
+    player.Stop();
+  }
 }
 
 void AccessibilityManager::Reset()
 {
+  ClearFocus();
+  mFocusIDContainer.clear();
+  mIDAdditionalInfoContainer.clear();
 }
 
 void AccessibilityManager::SetFocusGroup(Actor actor, bool isFocusGroup)
 {
+  if(actor)
+  {
+    // Create/Set focus group property.
+    actor.RegisterProperty( IS_FOCUS_GROUP, isFocusGroup, Property::READ_WRITE );
+  }
 }
 
 bool AccessibilityManager::IsFocusGroup(Actor actor) const
 {
-  return false;
+  // Check whether the actor is a focus group
+  bool isFocusGroup = false;
+
+  if(actor)
+  {
+    Property::Index propertyIsFocusGroup = actor.GetPropertyIndex(IS_FOCUS_GROUP);
+    if(propertyIsFocusGroup != Property::INVALID_INDEX)
+    {
+      isFocusGroup = actor.GetProperty<bool>(propertyIsFocusGroup);
+    }
+  }
+
+  return isFocusGroup;
 }
 
 Actor AccessibilityManager::GetFocusGroup(Actor actor)
 {
-  return {};
+  // Go through the actor's hierarchy to check which focus group the actor belongs to
+  while (actor && !IsFocusGroup(actor))
+  {
+    actor = actor.GetParent();
+  }
+
+  return actor;
 }
 
 Vector2 AccessibilityManager::GetReadPosition() const
 {
-  return {};
+  AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
+  return adaptor.GetReadPosition();
 }
 
 void AccessibilityManager::SetGroupMode(bool enabled)
 {
+  mIsFocusWithinGroup = enabled;
 }
 
 bool AccessibilityManager::GetGroupMode() const
 {
-  return false;
+  return mIsFocusWithinGroup;
 }
 
 void AccessibilityManager::SetWrapMode(bool wrapped)
 {
+  mIsWrapped = wrapped;
 }
 
 bool AccessibilityManager::GetWrapMode() const
 {
-  return false;
+  return mIsWrapped;
 }
 
 void AccessibilityManager::SetFocusIndicatorActor(Actor indicator)
 {
+  if( mFocusIndicatorActor != indicator )
+  {
+    Actor currentFocusActor = GetCurrentFocusActor();
+    if( currentFocusActor )
+    {
+      // The new focus indicator should be added to the current focused actor immediately
+      if( mFocusIndicatorActor )
+      {
+        currentFocusActor.Remove( mFocusIndicatorActor );
+      }
+
+      if( indicator )
+      {
+        currentFocusActor.Add( indicator );
+      }
+    }
+
+    mFocusIndicatorActor = indicator;
+  }
 }
 
 Actor AccessibilityManager::GetFocusIndicatorActor()
 {
-        return {};
+  if( ! mFocusIndicatorActor )
+  {
+    // Create the default if it hasn't been set and one that's shared by all the keyboard focusable actors
+    mFocusIndicatorActor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH );
+    mFocusIndicatorActor.SetParentOrigin( ParentOrigin::CENTER );
+    mFocusIndicatorActor.SetZ( 1.0f );
+
+    // Apply size constraint to the focus indicator
+    mFocusIndicatorActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  }
+
+  return mFocusIndicatorActor;
+}
+
+bool AccessibilityManager::DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped)
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] %d focusable actors\n", __FUNCTION__, __LINE__, mFocusIDContainer.size());
+  DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] focus order : %d\n", __FUNCTION__, __LINE__, (*focusIDIter).first);
+
+  if( (forward && ++focusIDIter == mFocusIDContainer.end())
+    || (!forward && focusIDIter-- == mFocusIDContainer.begin()) )
+  {
+    if(mIsEndcapFeedbackEnabled)
+    {
+      if(mIsEndcapFeedbackPlayed == false)
+      {
+        // play sound & skip moving once
+        Dali::SoundPlayer soundPlayer = Dali::SoundPlayer::Get();
+        if(soundPlayer)
+        {
+          soundPlayer.PlaySound(FOCUS_CHAIN_END_SOUND_FILE);
+        }
+
+        mIsEndcapFeedbackPlayed = true;
+        return true;
+      }
+      mIsEndcapFeedbackPlayed = false;
+    }
+
+    if(wrapped)
+    {
+      if(forward)
+      {
+        focusIDIter = mFocusIDContainer.begin();
+      }
+      else
+      {
+        focusIDIter = mFocusIDContainer.end();
+        --focusIDIter;//We want forward iterator to the last element here
+      }
+    }
+    else
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] Overshot\n", __FUNCTION__, __LINE__);
+      // Send notification for handling overshooted situation
+      mFocusOvershotSignal.Emit(GetCurrentFocusActor(), forward ? Toolkit::AccessibilityManager::OVERSHOT_NEXT : Toolkit::AccessibilityManager::OVERSHOT_PREVIOUS);
+
+      return false; // Try to move the focus out of the scope
+    }
+  }
+
+  // Invalid focus.
+  if( focusIDIter == mFocusIDContainer.end() )
+  {
+    return false;
+  }
+
+  // Note: This function performs the focus change.
+  if( !DoSetCurrentFocusActor( (*focusIDIter).second ) )
+  {
+    mRecursiveFocusMoveCounter++;
+    if(mRecursiveFocusMoveCounter > mFocusIDContainer.size())
+    {
+      // We've attempted to focus all the actors in the whole focus chain and no actor
+      // can be focused successfully.
+      DALI_LOG_WARNING("[%s] There is no more focusable actor in %d focus chains\n", __FUNCTION__, mRecursiveFocusMoveCounter);
+
+      return false;
+    }
+    else
+    {
+      return DoMoveFocus(focusIDIter, forward, wrapped);
+    }
+  }
+
+  return true;
+}
+
+void AccessibilityManager::SetFocusable(Actor actor, bool focusable)
+{
+  if(actor)
+  {
+    // Create/Set actor focusable property.
+    actor.RegisterProperty( ACTOR_FOCUSABLE, focusable, Property::READ_WRITE );
+  }
+}
+
+bool AccessibilityManager::ChangeAccessibilityStatus()
+{
+  AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
+  mIsAccessibilityTtsEnabled = adaptor.IsEnabled();
+  Dali::Toolkit::AccessibilityManager handle( this );
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    // Show indicator when tts turned on if there is focused actor.
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      actor.Add( GetFocusIndicatorActor() );
+    }
+    mIsFocusIndicatorEnabled = true;
+
+    // Connect a signal to the TTS player to implement continuous reading mode.
+    Dali::TtsPlayer player = Dali::TtsPlayer::Get( Dali::TtsPlayer::SCREEN_READER );
+    player.StateChangedSignal().Connect( this, &AccessibilityManager::TtsStateChanged );
+    mTtsCreated = true;
+  }
+  else
+  {
+    // Hide indicator when tts turned off
+    Actor actor = GetCurrentFocusActor();
+    if( actor && mFocusIndicatorActor )
+    {
+      actor.Remove( mFocusIndicatorActor );
+    }
+    mIsFocusIndicatorEnabled = false;
+
+    if( mTtsCreated )
+    {
+      // Disconnect the TTS state change signal.
+      Dali::TtsPlayer player = Dali::TtsPlayer::Get( Dali::TtsPlayer::SCREEN_READER );
+      player.StateChangedSignal().Disconnect( this, &AccessibilityManager::TtsStateChanged );
+      mTtsCreated = true;
+    }
+  }
+
+  mStatusChangedSignal.Emit( handle );
+
+  return true;
+}
+
+bool AccessibilityManager::AccessibilityActionNext(bool allowEndFeedback)
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionNextSignal.Empty() )
+  {
+    mActionNextSignal.Emit( handle );
+  }
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    mIsEndcapFeedbackEnabled = allowEndFeedback;
+    return MoveFocusForward();
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool AccessibilityManager::AccessibilityActionPrevious(bool allowEndFeedback)
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionPreviousSignal.Empty() )
+  {
+    mActionPreviousSignal.Emit( handle );
+  }
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    mIsEndcapFeedbackEnabled = allowEndFeedback;
+    return MoveFocusBackward();
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool AccessibilityManager::AccessibilityActionActivate()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionActivateSignal.Empty() )
+  {
+    mActionActivateSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  Actor actor = GetCurrentFocusActor();
+  if(actor)
+  {
+    DoActivate(actor);
+    ret = true;
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionRead(bool allowReadAgain)
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+
+  if( allowReadAgain )
+  {
+    if ( !mActionReadSignal.Empty() )
+    {
+      mActionReadSignal.Emit( handle );
+    }
+  }
+  else
+  {
+    if ( !mActionOverSignal.Empty() )
+    {
+      mActionOverSignal.Emit( handle );
+    }
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    // Find the focusable actor at the read position
+    AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
+    Dali::HitTestAlgorithm::Results results;
+    Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), adaptor.GetReadPosition(), results, IsActorFocusableFunction );
+
+    FocusIDIter focusIDIter = mFocusIDContainer.find(GetFocusOrder(results.actor));
+    if(focusIDIter != mFocusIDContainer.end())
+    {
+      if( allowReadAgain || (results.actor != GetCurrentFocusActor()) )
+      {
+        // Move the focus to the actor
+        ret = SetCurrentFocusActor(results.actor);
+        DALI_LOG_INFO( gLogFilter, Debug::General, "[%s:%d] SetCurrentFocusActor returns %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionReadNext(bool allowEndFeedback)
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionReadNextSignal.Empty() )
+  {
+    mActionReadNextSignal.Emit( handle );
+  }
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    return MoveFocusForward();
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool AccessibilityManager::AccessibilityActionReadPrevious(bool allowEndFeedback)
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionReadPreviousSignal.Empty() )
+  {
+    mActionReadPreviousSignal.Emit( handle );
+  }
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    return MoveFocusBackward();
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool AccessibilityManager::AccessibilityActionUp()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionUpSignal.Empty() )
+  {
+    mActionUpSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // Notify the control that it is activated
+        ret = GetImplementation( control ).OnAccessibilityValueChange(true);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionDown()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionDownSignal.Empty() )
+  {
+    mActionDownSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // Notify the control that it is activated
+        ret = GetImplementation( control ).OnAccessibilityValueChange(false);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::ClearAccessibilityFocus()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionClearFocusSignal.Empty() )
+  {
+    mActionClearFocusSignal.Emit( handle );
+  }
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    ClearFocus();
+    return true;
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool AccessibilityManager::AccessibilityActionScroll( Dali::TouchEvent& touchEvent )
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionScrollSignal.Empty() )
+  {
+    mActionScrollSignal.Emit( handle, touchEvent );
+  }
+
+  return true;
+}
+
+bool AccessibilityManager::AccessibilityActionBack()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionBackSignal.Empty() )
+  {
+    mActionBackSignal.Emit( handle );
+  }
+
+  // TODO: Back to previous view
+
+  return mIsAccessibilityTtsEnabled;
+}
+
+bool AccessibilityManager::AccessibilityActionScrollUp()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionScrollUpSignal.Empty() )
+  {
+    mActionScrollUpSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // TODO: Notify the control to scroll up. Should control handle this?
+//        ret = GetImplementation( control ).OnAccessibilityScroll(Direction::UP);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionScrollDown()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionScrollDownSignal.Empty() )
+  {
+    mActionScrollDownSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // TODO: Notify the control to scroll down. Should control handle this?
+//        ret = GetImplementation( control ).OnAccessibilityScrollDown(Direction::DOWN);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionPageLeft()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionPageLeftSignal.Empty() )
+  {
+    mActionPageLeftSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // TODO: Notify the control to scroll left to the previous page. Should control handle this?
+//        ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::LEFT);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionPageRight()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionPageRightSignal.Empty() )
+  {
+    mActionPageRightSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // TODO: Notify the control to scroll right to the next page. Should control handle this?
+//        ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::RIGHT);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionPageUp()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionPageUpSignal.Empty() )
+  {
+    mActionPageUpSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // TODO: Notify the control to scroll up to the previous page. Should control handle this?
+//        ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::UP);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionPageDown()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionPageDownSignal.Empty() )
+  {
+    mActionPageDownSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // TODO: Notify the control to scroll down to the next page. Should control handle this?
+//        ret = GetImplementation( control ).OnAccessibilityScrollToPage(Direction::DOWN);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionMoveToFirst()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionMoveToFirstSignal.Empty() )
+  {
+    mActionMoveToFirstSignal.Emit( handle );
+  }
+
+  // TODO: Move to the first item on screen
+
+  return mIsAccessibilityTtsEnabled;
+}
+
+bool AccessibilityManager::AccessibilityActionMoveToLast()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionMoveToLastSignal.Empty() )
+  {
+    mActionMoveToLastSignal.Emit( handle );
+  }
+
+  // TODO: Move to the last item on screen
+
+  return mIsAccessibilityTtsEnabled;
+}
+
+bool AccessibilityManager::AccessibilityActionReadFromTop()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionReadFromTopSignal.Empty() )
+  {
+    mActionReadFromTopSignal.Emit( handle );
+  }
+
+  // TODO: Move to the top item on screen and read from the item continuously
+
+  return mIsAccessibilityTtsEnabled;
+}
+
+bool AccessibilityManager::AccessibilityActionReadFromNext()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+
+  if( !mActionReadFromNextSignal.Empty() )
+  {
+    mActionReadFromNextSignal.Emit( handle );
+  }
+
+  if( mIsAccessibilityTtsEnabled )
+  {
+    // Mark that we are in continuous play mode, so TTS signals can move focus.
+    mContinuousPlayMode = true;
+
+    // Attempt to move to the next item and read from the item continuously.
+    MoveFocusForward();
+  }
+
+  return mIsAccessibilityTtsEnabled;
+}
+
+void AccessibilityManager::TtsStateChanged( const Dali::TtsPlayer::State previousState, const Dali::TtsPlayer::State currentState )
+{
+  if( mContinuousPlayMode )
+  {
+    // If we were playing and now we have stopped, attempt to play the next item.
+    if( ( previousState == Dali::TtsPlayer::PLAYING ) && ( currentState == Dali::TtsPlayer::READY ) )
+    {
+      // Attempt to move the focus forward and play.
+      // If we can't cancel continuous play mode.
+      if( !MoveFocusForward() )
+      {
+        // We are done, exit continuous play mode.
+        mContinuousPlayMode = false;
+      }
+    }
+    else
+    {
+      // Unexpected play state change, exit continuous play mode.
+      mContinuousPlayMode = false;
+    }
+  }
+}
+
+bool AccessibilityManager::AccessibilityActionZoom()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionZoomSignal.Empty() )
+  {
+    mActionZoomSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    Actor actor = GetCurrentFocusActor();
+    if(actor)
+    {
+      Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+      if(control)
+      {
+        // Notify the control to zoom
+        ret = GetImplementation( control ).OnAccessibilityZoom();
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionReadPauseResume()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionReadPauseResumeSignal.Empty() )
+  {
+    mActionReadPauseResumeSignal.Emit( handle );
+  }
+
+  bool ret = false;
+
+  if(mIsAccessibilityTtsEnabled)
+  {
+    // Pause or resume the TTS player
+    Dali::TtsPlayer player = Dali::TtsPlayer::Get(Dali::TtsPlayer::SCREEN_READER);
+    Dali::TtsPlayer::State state = player.GetState();
+    if(state == Dali::TtsPlayer::PLAYING)
+    {
+      player.Pause();
+      ret = true;
+    }
+    else if(state == Dali::TtsPlayer::PAUSED)
+    {
+      player.Resume();
+      ret = true;
+    }
+  }
+
+  return ret;
+}
+
+bool AccessibilityManager::AccessibilityActionStartStop()
+{
+  Dali::Toolkit::AccessibilityManager handle( this );
+  if( !mActionStartStopSignal.Empty() )
+  {
+    mActionStartStopSignal.Emit( handle );
+  }
+
+  // TODO: Start/stop the current action
+
+  return mIsAccessibilityTtsEnabled;
+}
+
+bool AccessibilityManager::AccessibilityActionTouch(const TouchEvent& touchEvent)
+{
+  bool handled = false;
+
+  // TODO: Need to convert the touchevent for the focused actor?
+
+  Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(GetCurrentFocusActor());
+  if(control)
+  {
+    handled = GetImplementation( control ).OnAccessibilityTouch(touchEvent);
+  }
+
+  return handled;
+}
+
+bool AccessibilityManager::HandlePanGesture(const AccessibilityGestureEvent& panEvent)
+{
+  bool handled = false;
+
+  if( panEvent.state == AccessibilityGestureEvent::Started )
+  {
+    // Find the focusable actor at the event position
+    Dali::HitTestAlgorithm::Results results;
+    AccessibilityAdaptor adaptor = AccessibilityAdaptor::Get();
+
+    Dali::HitTestAlgorithm::HitTest( Stage::GetCurrent(), panEvent.currentPosition, results, IsActorFocusableFunction );
+    mCurrentGesturedActor = results.actor;
+
+    if(!mCurrentGesturedActor)
+    {
+      DALI_LOG_ERROR("Gesture detected, but no hit actor\n");
+    }
+  }
+
+  // Gesture::Finished (Up) events are delivered with previous (Motion) event position
+  // Use the real previous position; otherwise we may incorrectly get a ZERO velocity
+  if ( AccessibilityGestureEvent::Finished != panEvent.state )
+  {
+    // Store the previous position for next Gesture::Finished iteration.
+    mPreviousPosition = panEvent.previousPosition;
+  }
+
+  Actor rootActor = Stage::GetCurrent().GetRootLayer();
+
+  Dali::PanGesture pan( static_cast<Dali::Gesture::State>(panEvent.state) );
+
+  pan.time = panEvent.time;
+  pan.numberOfTouches = panEvent.numberOfTouches;
+  pan.screenPosition = panEvent.currentPosition;
+  pan.screenDisplacement = mPreviousPosition - panEvent.currentPosition;
+  pan.screenVelocity.x = pan.screenDisplacement.x / panEvent.timeDelta;
+  pan.screenVelocity.y = pan.screenDisplacement.y / panEvent.timeDelta;
+
+  // Only handle the pan gesture when the current focused actor is scrollable or within a scrollable actor
+  while(mCurrentGesturedActor && mCurrentGesturedActor != rootActor && !handled)
+  {
+    Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(mCurrentGesturedActor);
+    if(control)
+    {
+      Vector2 localCurrent;
+      control.ScreenToLocal( localCurrent.x, localCurrent.y, panEvent.currentPosition.x, panEvent.currentPosition.y );
+      pan.position = localCurrent;
+
+      Vector2 localPrevious;
+      control.ScreenToLocal( localPrevious.x, localPrevious.y, mPreviousPosition.x, mPreviousPosition.y );
+
+      pan.displacement = localCurrent - localPrevious;
+      pan.velocity.x = pan.displacement.x / panEvent.timeDelta;
+      pan.velocity.y = pan.displacement.y / panEvent.timeDelta;
+
+      handled = GetImplementation( control ).OnAccessibilityPan(pan);
+    }
+
+    // If the gesture is not handled by the control, check its parent
+    if(!handled)
+    {
+      mCurrentGesturedActor = mCurrentGesturedActor.GetParent();
+
+      if(!mCurrentGesturedActor)
+      {
+        DALI_LOG_ERROR("no more gestured actor\n");
+      }
+    }
+    else
+    {
+      // If handled, then update the pan gesture properties
+      PanGestureDetector::SetPanGestureProperties( pan );
+    }
+  }
+
+  return handled;
 }
 
 Toolkit::AccessibilityManager::FocusChangedSignalType& AccessibilityManager::FocusChangedSignal()
old mode 100644 (file)
new mode 100755 (executable)
index 7266a42..d51d753
@@ -21,6 +21,9 @@
 // EXTERNAL INCLUDES
 #include <string>
 #include <dali/devel-api/common/map-wrapper.h>
+#include <dali/devel-api/adaptor-framework/accessibility-action-handler.h>
+#include <dali/devel-api/adaptor-framework/accessibility-gesture-handler.h>
+#include <dali/devel-api/adaptor-framework/accessibility-gesture-event.h>
 #include <dali/public-api/object/base-object.h>
 
 // INTERNAL INCLUDES
@@ -41,7 +44,7 @@ class AccessibilityManager;
 /**
  * @copydoc Toolkit::AccessibilityManager
  */
-class AccessibilityManager : public Dali::BaseObject, public Dali::ConnectionTracker
+class AccessibilityManager : public Dali::BaseObject, Dali::AccessibilityActionHandler, Dali::AccessibilityGestureHandler, public Dali::ConnectionTracker
 {
 public:
 
@@ -443,36 +446,299 @@ protected:
   virtual ~AccessibilityManager();
 
 private:
-  AccessibilityActionSignalType mStatusChangedSignal;
-  AccessibilityActionSignalType mActionNextSignal;
-  AccessibilityActionSignalType mActionPreviousSignal;
-  AccessibilityActionSignalType mActionActivateSignal;
-  AccessibilityActionSignalType mActionOverSignal;
-  AccessibilityActionSignalType mActionReadSignal;
-  AccessibilityActionSignalType mActionReadNextSignal;
-  AccessibilityActionSignalType mActionReadPreviousSignal;
-  AccessibilityActionSignalType mActionUpSignal;
-  AccessibilityActionSignalType mActionDownSignal;
-  AccessibilityActionSignalType mActionClearFocusSignal;
-  AccessibilityActionSignalType mActionBackSignal;
-  AccessibilityActionSignalType mActionScrollUpSignal;
-  AccessibilityActionSignalType mActionScrollDownSignal;
-  AccessibilityActionSignalType mActionPageLeftSignal;
-  AccessibilityActionSignalType mActionPageRightSignal;
-  AccessibilityActionSignalType mActionPageUpSignal;
-  AccessibilityActionSignalType mActionPageDownSignal;
-  AccessibilityActionSignalType mActionMoveToFirstSignal;
-  AccessibilityActionSignalType mActionMoveToLastSignal;
-  AccessibilityActionSignalType mActionReadFromTopSignal;
-  AccessibilityActionSignalType mActionReadFromNextSignal;
-  AccessibilityActionSignalType mActionZoomSignal;
-  AccessibilityActionSignalType mActionReadIndicatorInformationSignal;
-  AccessibilityActionSignalType mActionReadPauseResumeSignal;
-  AccessibilityActionSignalType mActionStartStopSignal;
+
+  /**
+   * Get the additional information (e.g. focus order and description) of the given actor.
+   * @param actorID The ID of the actor to be queried
+   * @return The additional information of the actor
+   */
+  ActorAdditionalInfo GetActorAdditionalInfo(const unsigned int actorID) const;
+
+  /**
+   * Synchronize the actor's additional information to reflect its latest focus order
+   * @param actorID The ID of the actor
+   * @param order The focus order of the actor
+   * @return The additional information of the actor
+   */
+  void SynchronizeActorAdditionalInfo(const unsigned int actorID, const unsigned int order);
+
+  /**
+   * Move the focus to the specified actor and send notification for the focus change.
+   * @param actorID The ID of the actor to be queried
+   * @return Whether the focus is successful or not
+   */
+  bool DoSetCurrentFocusActor(const unsigned int actorID);
+
+  /**
+   * Move the focus to the next actor in the focus chain towards the specified direction.
+   * @param focusIDIter The iterator pointing to the current focused actor
+   * @param forward Whether the focus movement is forward or not. The focus movement will be backward if this is false.
+   * @param wrapped Whether the focus shoule be moved wrapped around or not
+   * @return Whether the focus is successful or not
+   */
+  bool DoMoveFocus(FocusIDIter focusIDIter, bool forward, bool wrapped);
+
+  /**
+   * Activate the actor. If the actor is control, call OnAccessibilityActivated virtual function.
+   * This function will emit FocusedActorActivatedSignal.
+   * @param actor The actor to activate
+   */
+  void DoActivate(Actor actor);
+
+  /**
+   * Set whether the actor is focusable or not. A focusable property will be registered for
+   * the actor if not yet.
+   * @param actor The actor to be focused
+   * @param focusable Whether the actor is focusable or not
+   */
+  void SetFocusable(Actor actor, bool focusable);
+
+  /**
+   * Handle the accessibility pan gesture.
+   * @param[in]  panEvent  The pan event to be handled.
+   * @return whether the gesture is handled successfully or not.
+   */
+  virtual bool HandlePanGesture(const AccessibilityGestureEvent& panEvent);
+
+  /**
+   * Change the accessibility status when Accessibility feature(screen-reader) turned on or off.
+   * @return whether the status is changed or not.
+   */
+  virtual bool ChangeAccessibilityStatus();
+
+  /**
+   * Clear the accessibility focus from the current focused actor.
+   * @return whether the focus is cleared or not.
+   */
+  virtual bool ClearAccessibilityFocus();
+
+  /**
+   * Perform the accessibility action associated with a scroll event.
+   * @param touchEvent The touch point (and time) of the event.
+   * @return whether the focus is cleared or not.
+   */
+  virtual bool AccessibilityActionScroll( Dali::TouchEvent& touchEvent );
+
+  /**
+   * Perform the accessibility action to move focus to the previous focusable actor (by one finger flick up).
+   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionPrevious(bool allowEndFeedback);
+
+  /**
+   * Perform the accessibility action to move focus to the next focusable actor (by one finger flick down).
+   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionNext(bool allowEndFeedback);
+
+  /**
+   * Perform the accessibility action to move focus to the previous focusable actor (by one finger flick left).
+   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionReadPrevious(bool allowEndFeedback);
+
+  /**
+   * Perform the accessibility action to move focus to the next focusable actor (by one finger flick right).
+   * @param allowEndFeedback true if end of list feedback should be played when the focus is alread reached to the end
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionReadNext(bool allowEndFeedback);
+
+  /**
+   * Perform the accessibility action to focus and read the actor (by one finger tap or move).
+   * @param allowReadAgain true if the action read again the same object (i.e. read action)
+   *                       false if the action just read when the focus object is changed (i.e. over action)
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionRead(bool allowReadAgain);
+
+  /**
+   * Perform the accessibility action to activate the current focused actor (by one finger double tap).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionActivate();
+
+  /**
+   * Perform the accessibility action to change the value when the current focused actor is a slider
+   * (by double finger down and move up and right).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionUp();
+
+  /**
+   * Perform the accessibility action to change the value when the current focused actor is a slider
+   * (by double finger down and move down and left).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionDown();
+
+  /**
+   * Perform the accessibility action to navigate back (by two fingers circle draw).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionBack();
+
+  /**
+   * Perform the accessibility action to scroll up the list and focus on the first item on the list
+   * after the scrolling and read the item (by two finger swipe up).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionScrollUp();
+
+  /**
+   * Perform the accessibility action to scroll down the list and focus on the first item on the list
+   * after the scrolling and read the item (by two finger swipe down).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionScrollDown();
+
+  /**
+   * Perform the accessibility action to scroll left to the previous page (by two finger swipe left).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionPageLeft();
+
+  /**
+   * Perform the accessibility action to scroll right to the next page (by two finger swipe right).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionPageRight();
+
+  /**
+   * Perform the accessibility action to scroll up to the previous page (by one finger swipe left and right).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionPageUp();
+
+  /**
+   * Perform the accessibility action to scroll down to the next page (by one finger swipe right and left).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionPageDown();
+
+  /**
+   * Perform the accessibility action to move the focus to the first item on the screen
+   * (by one finger swipe up and down).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionMoveToFirst();
+
+  /**
+   * Perform the accessibility action to move the focus to the last item on the screen
+   * (by one finger swipe down and up).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionMoveToLast();
+
+  /**
+   * Perform the accessibility action to move the focus to the first item on the top
+   * and read from the top item continuously (by three fingers single tap).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionReadFromTop();
+
+  /**
+   * Perform the accessibility action to move the focus to and read from the next item
+   * continuously (by three fingers double tap).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionReadFromNext();
+
+  /**
+   * Perform the accessibility action to move the focus to do the zooming (by one finger triple tap).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionZoom();
+
+  /**
+   * Perform the accessibility action to pause/resume the current read out (by two fingers single tap).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionReadPauseResume();
+
+  /**
+   * Perform the accessibility action to start/stop the current action (by two fingers double tap).
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionStartStop();
+
+  /**
+   * Perform the accessibility action to mouse move (by one finger tap & hold and move).
+   * @param touchEvent touch event structure
+   * @return whether the accessibility action is performed or not.
+   */
+  virtual bool AccessibilityActionTouch(const TouchEvent& touchEvent);
+
+  /**
+   * This function is connected to the TtsPlayer StateChangeSignal.
+   * It is called when the TTS players state changes.
+   * @param previousState The previous state of the TTS player (for comparison)
+   * @param currentState  The current state of the TTS player
+   */
+  void TtsStateChanged( const Dali::TtsPlayer::State previousState, const Dali::TtsPlayer::State currentState );
+
+private:
+
+  // Undefined
+  AccessibilityManager(const AccessibilityManager&);
+
+  AccessibilityManager& operator=(const AccessibilityManager& rhs);
+
+private:
+
+  Toolkit::AccessibilityManager::FocusChangedSignalType mFocusChangedSignal; ///< The signal to notify the focus change
+  Toolkit::AccessibilityManager::FocusOvershotSignalType mFocusOvershotSignal; ///< The signal to notify the focus overshooted
+  Toolkit::AccessibilityManager::FocusedActorActivatedSignalType mFocusedActorActivatedSignal; ///< The signal to notify the activation of focused actor
+
+  // Action signals.
+  AccessibilityActionSignalType       mStatusChangedSignal;
+  AccessibilityActionSignalType       mActionNextSignal;
+  AccessibilityActionSignalType       mActionPreviousSignal;
+  AccessibilityActionSignalType       mActionActivateSignal;
+  AccessibilityActionSignalType       mActionOverSignal;
+  AccessibilityActionSignalType       mActionReadSignal;
+  AccessibilityActionSignalType       mActionReadNextSignal;
+  AccessibilityActionSignalType       mActionReadPreviousSignal;
+  AccessibilityActionSignalType       mActionUpSignal;
+  AccessibilityActionSignalType       mActionDownSignal;
+  AccessibilityActionSignalType       mActionClearFocusSignal;
+  AccessibilityActionSignalType       mActionBackSignal;
+  AccessibilityActionSignalType       mActionScrollUpSignal;
+  AccessibilityActionSignalType       mActionScrollDownSignal;
+  AccessibilityActionSignalType       mActionPageLeftSignal;
+  AccessibilityActionSignalType       mActionPageRightSignal;
+  AccessibilityActionSignalType       mActionPageUpSignal;
+  AccessibilityActionSignalType       mActionPageDownSignal;
+  AccessibilityActionSignalType       mActionMoveToFirstSignal;
+  AccessibilityActionSignalType       mActionMoveToLastSignal;
+  AccessibilityActionSignalType       mActionReadFromTopSignal;
+  AccessibilityActionSignalType       mActionReadFromNextSignal;
+  AccessibilityActionSignalType       mActionZoomSignal;
+  AccessibilityActionSignalType       mActionReadIndicatorInformationSignal;
+  AccessibilityActionSignalType       mActionReadPauseResumeSignal;
+  AccessibilityActionSignalType       mActionStartStopSignal;
   AccessibilityActionScrollSignalType mActionScrollSignal;
-  Toolkit::AccessibilityManager::FocusChangedSignalType mFocusChangedSignal;
-  Toolkit::AccessibilityManager::FocusOvershotSignalType mFocusOvershotSignal;
-  Toolkit::AccessibilityManager::FocusedActorActivatedSignalType mFocusedActorActivatedSignal;
+
+  FocusIDContainer mFocusIDContainer;       ///< The container to look up actor ID by focus order
+  IDAdditionalInfoContainer mIDAdditionalInfoContainer; ///< The container to look up additional information by actor ID
+  FocusIDPair mCurrentFocusActor;           ///< The focus order and actor ID of current focused actor
+  Actor mCurrentGesturedActor;              ///< The actor that will handle the gesture
+  Actor mFocusIndicatorActor;               ///< The focus indicator actor shared by all the focusable actors for highlight
+  Vector2 mPreviousPosition;                ///< The previous pan position; useful for calculating velocity for Gesture::Finished events
+  unsigned int mRecursiveFocusMoveCounter;  ///< The counter to count the number of recursive focus movement attempted before the focus movement is successful.
+
+  bool mIsWrapped:1;                        ///< Whether the focus movement is wrapped around or not
+  bool mIsFocusWithinGroup:1;               ///< Whether the focus movement is limited to the current focus group or not
+  bool mIsEndcapFeedbackEnabled:1;          ///< Whether the endcap feedback need to be played when the focus leaves the end or vice versa
+  bool mIsEndcapFeedbackPlayed:1;           ///< Whether the endcap feedback was played or not
+  bool mIsAccessibilityTtsEnabled:1;        ///< Whether accessibility feature(screen-reader) turned on/off
+  bool mTtsCreated:1;                       ///< Whether the TTS Player has been accessed
+  bool mIsFocusIndicatorEnabled:1;          ///< Whether indicator should be shown / hidden. It could be enabled when TTS enabled or 'Tab' key operated.
+  bool mContinuousPlayMode:1;               ///< Keeps track of whether or not we are in continuous play mode
+
 };
 
 } // namespace Internal