[AT-SPI] Add Pause and Resume signals
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / control / control-data-impl.cpp
index 73769c8..c3c8062 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/object/type-registry-helper.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
 #include <cstring>
 #include <limits>
 
 #include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+
+namespace
+{
+  const std::string READING_INFO_TYPE_NAME = "name";
+  const std::string READING_INFO_TYPE_ROLE = "role";
+  const std::string READING_INFO_TYPE_DESCRIPTION = "description";
+  const std::string READING_INFO_TYPE_STATE = "state";
+  const std::string READING_INFO_TYPE_ATTRIBUTE_NAME = "reading_info_type";
+  const std::string READING_INFO_TYPE_SEPARATOR = "|";
+}
 
 namespace Dali
 {
@@ -170,22 +189,63 @@ void MoveVisual( RegisteredVisualContainer::Iterator sourceIter, RegisteredVisua
  * @param[in] attributes The attributes with which to perfrom this action.
  * @return true if action has been accepted by this control
  */
-const char* ACTION_ACCESSIBILITY_ACTIVATED = "accessibilityActivated";
+const char* ACTION_ACCESSIBILITY_ACTIVATED         = "accessibilityActivated";
+const char* ACTION_ACCESSIBILITY_READING_CANCELLED = "ReadingCancelled";
+const char* ACTION_ACCESSIBILITY_READING_PAUSED    = "ReadingPaused";
+const char* ACTION_ACCESSIBILITY_READING_RESUMED   = "ReadingResumed";
+const char* ACTION_ACCESSIBILITY_READING_SKIPPED   = "ReadingSkipped";
+const char* ACTION_ACCESSIBILITY_READING_STOPPED   = "ReadingStopped";
+
 static bool DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
 {
-  bool ret = false;
+  if (!object)
+    return false;
+
+  Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
+  if ( !control )
+    return false;
 
-  if( object && ( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ) )
+  if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_ACTIVATED ) ||
+        actionName == "activate" )
   {
-    Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
-    if( control )
-    {
-      // if cast succeeds there is an implementation so no need to check
-      ret = Internal::GetImplementation( control ).OnAccessibilityActivated();
-    }
+    // if cast succeeds there is an implementation so no need to check
+    if (!DevelControl::AccessibilityActivateSignal( control ).Empty())
+      DevelControl::AccessibilityActivateSignal( control ).Emit();
+    else
+      return Internal::GetImplementation( control ).OnAccessibilityActivated();
+  }
+  else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_SKIPPED ) )
+  {
+    // if cast succeeds there is an implementation so no need to check
+    if (!DevelControl::AccessibilityReadingSkippedSignal( control ).Empty())
+      DevelControl::AccessibilityReadingSkippedSignal( control ).Emit();
+  }
+  else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_PAUSED) )
+  {
+    // if cast succeeds there is an implementation so no need to check
+    if (!DevelControl::AccessibilityReadingPausedSignal( control ).Empty())
+      DevelControl::AccessibilityReadingPausedSignal( control ).Emit();
+  }
+  else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_RESUMED ) )
+  {
+    // if cast succeeds there is an implementation so no need to check
+    if (!DevelControl::AccessibilityReadingResumedSignal( control ).Empty())
+      DevelControl::AccessibilityReadingResumedSignal( control ).Emit();
+  }
+  else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_CANCELLED ) )
+  {
+    // if cast succeeds there is an implementation so no need to check
+    if (!DevelControl::AccessibilityReadingCancelledSignal( control ).Empty())
+      DevelControl::AccessibilityReadingCancelledSignal( control ).Emit();
+  }
+  else if( 0 == strcmp( actionName.c_str(), ACTION_ACCESSIBILITY_READING_STOPPED ) )
+  {
+    // if cast succeeds there is an implementation so no need to check
+    if (!DevelControl::AccessibilityReadingStoppedSignal( control ).Empty())
+      DevelControl::AccessibilityReadingStoppedSignal( control ).Emit();
   }
 
-  return ret;
+  return true;
 }
 
 /**
@@ -204,6 +264,9 @@ const char* SIGNAL_TAPPED = "tapped";
 const char* SIGNAL_PANNED = "panned";
 const char* SIGNAL_PINCHED = "pinched";
 const char* SIGNAL_LONG_PRESSED = "longPressed";
+const char* SIGNAL_GET_NAME = "getName";
+const char* SIGNAL_GET_DESCRIPTION = "getDescription";
+const char* SIGNAL_DO_GESTURE = "doGesture";
 static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   Dali::BaseHandle handle( object );
@@ -229,24 +292,37 @@ static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::Tap );
+      controlImpl.EnableGestureDetection( GestureType::TAP );
       controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::Pan );
+      controlImpl.EnableGestureDetection( GestureType::PAN );
       controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::Pinch );
+      controlImpl.EnableGestureDetection( GestureType::PINCH );
       controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
     else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) )
     {
-      controlImpl.EnableGestureDetection( Gesture::LongPress );
+      controlImpl.EnableGestureDetection( GestureType::LONG_PRESS );
       controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor );
     }
+    else if( 0 == strcmp( signalName.c_str(), SIGNAL_GET_NAME ) )
+    {
+      DevelControl::AccessibilityGetNameSignal( control ).Connect( tracker, functor );
+    }
+    else if( 0 == strcmp( signalName.c_str(), SIGNAL_GET_DESCRIPTION ) )
+    {
+      DevelControl::AccessibilityGetDescriptionSignal( control ).Connect( tracker, functor );
+    }
+    else if( 0 == strcmp( signalName.c_str(), SIGNAL_DO_GESTURE ) )
+    {
+      DevelControl::AccessibilityDoGestureSignal( control ).Connect( tracker, functor );
+    }
+
   }
   return connected;
 }
@@ -270,25 +346,34 @@ SignalConnectorType registerSignal4( typeRegistration, SIGNAL_TAPPED, &DoConnect
 SignalConnectorType registerSignal5( typeRegistration, SIGNAL_PANNED, &DoConnectSignal );
 SignalConnectorType registerSignal6( typeRegistration, SIGNAL_PINCHED, &DoConnectSignal );
 SignalConnectorType registerSignal7( typeRegistration, SIGNAL_LONG_PRESSED, &DoConnectSignal );
-
-TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
+SignalConnectorType registerSignal8( typeRegistration, SIGNAL_GET_NAME, &DoConnectSignal );
+SignalConnectorType registerSignal9( typeRegistration, SIGNAL_GET_DESCRIPTION, &DoConnectSignal );
+SignalConnectorType registerSignal10( typeRegistration, SIGNAL_DO_GESTURE, &DoConnectSignal );
+
+TypeAction registerAction1( typeRegistration, "activate", &DoAction );
+TypeAction registerAction2( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &DoAction );
+TypeAction registerAction3( typeRegistration, ACTION_ACCESSIBILITY_READING_SKIPPED, &DoAction );
+TypeAction registerAction4( typeRegistration, ACTION_ACCESSIBILITY_READING_CANCELLED, &DoAction );
+TypeAction registerAction5( typeRegistration, ACTION_ACCESSIBILITY_READING_STOPPED, &DoAction );
+TypeAction registerAction6( typeRegistration, ACTION_ACCESSIBILITY_READING_PAUSED, &DoAction );
+TypeAction registerAction7( typeRegistration, ACTION_ACCESSIBILITY_READING_RESUMED, &DoAction );
 
 DALI_TYPE_REGISTRATION_END()
 
 /**
- * @brief Iterate through given container and setOffStage any visual found
+ * @brief Iterate through given container and setOffScene any visual found
  *
  * @param[in] container Container of visuals
  * @param[in] parent Parent actor to remove visuals from
  */
-void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor parent )
+void SetVisualsOffScene( const RegisteredVisualContainer& container, Actor parent )
 {
   for( auto iter = container.Begin(), end = container.End() ; iter!= end; iter++)
   {
     if( (*iter)->visual )
     {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffStage Setting visual(%d) off stage\n", (*iter)->index );
-      Toolkit::GetImplementation((*iter)->visual).SetOffStage( parent );
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffScene Setting visual(%d) off stage\n", (*iter)->index );
+      Toolkit::GetImplementation((*iter)->visual).SetOffScene( parent );
     }
   }
 }
@@ -298,8 +383,6 @@ void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor paren
 
 // Properties registered without macro to use specific member variables.
 const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName",              Toolkit::Control::Property::STYLE_NAME,                   Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "backgroundColor",        Toolkit::Control::Property::BACKGROUND_COLOR,             Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "backgroundImage",        Toolkit::Control::Property::BACKGROUND_IMAGE,             Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus",          Toolkit::Control::Property::KEY_INPUT_FOCUS,              Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background",             Toolkit::Control::Property::BACKGROUND,                   Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "margin",                 Toolkit::Control::Property::MARGIN,                       Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
@@ -311,42 +394,78 @@ const PropertyRegistration Control::Impl::PROPERTY_11( typeRegistration, "leftFo
 const PropertyRegistration Control::Impl::PROPERTY_12( typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID,Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_13( typeRegistration, "upFocusableActorId",    Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID,   Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 const PropertyRegistration Control::Impl::PROPERTY_14( typeRegistration, "downFocusableActorId",  Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
-
+const PropertyRegistration Control::Impl::PROPERTY_15( typeRegistration, "shadow",                Toolkit::DevelControl::Property::SHADOW,                  Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_16( typeRegistration, "accessibilityAttributes",         Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES,         Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_17( typeRegistration, "accessibilityName",              Toolkit::DevelControl::Property::ACCESSIBILITY_NAME,               Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_18( typeRegistration, "accessibilityDescription",       Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION,         Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_19( typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_20( typeRegistration, "accessibilityRole",              Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE,               Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_21( typeRegistration, "accessibilityHighlightable",     Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
+const PropertyRegistration Control::Impl::PROPERTY_22( typeRegistration, "accessibilityAnimated",          Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty );
 
 Control::Impl::Impl( Control& controlImpl )
 : mControlImpl( controlImpl ),
   mState( Toolkit::DevelControl::NORMAL ),
   mSubStateName(""),
-  mLayout( NULL ),
   mLeftFocusableActorId( -1 ),
   mRightFocusableActorId( -1 ),
   mUpFocusableActorId( -1 ),
   mDownFocusableActorId( -1 ),
   mStyleName(""),
   mBackgroundColor(Color::TRANSPARENT),
-  mStartingPinchScale( NULL ),
+  mStartingPinchScale(nullptr),
   mMargin( 0, 0, 0, 0 ),
   mPadding( 0, 0, 0, 0 ),
   mKeyEventSignal(),
   mKeyInputFocusGainedSignal(),
   mKeyInputFocusLostSignal(),
   mResourceReadySignal(),
+  mVisualEventSignal(),
+  mAccessibilityGetNameSignal(),
+  mAccessibilityGetDescriptionSignal(),
+  mAccessibilityDoGestureSignal(),
   mPinchGestureDetector(),
   mPanGestureDetector(),
   mTapGestureDetector(),
   mLongPressGestureDetector(),
   mTooltip( NULL ),
   mInputMethodContext(),
+  mIdleCallback(nullptr),
   mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mIsKeyboardNavigationSupported( false ),
-  mIsKeyboardFocusGroup( false )
+  mIsKeyboardFocusGroup( false ),
+  mIsEmittingResourceReadySignal(false),
+  mNeedToEmitResourceReady(false)
 {
+  Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
+      []( Dali::Actor actor ) -> Dali::Accessibility::Accessible* {
+        return Control::Impl::GetAccessibilityObject( actor );
+      } );
+
+  accessibilityConstructor =  []( Dali::Actor actor ) -> std::unique_ptr< Dali::Accessibility::Accessible > {
+        return std::unique_ptr< Dali::Accessibility::Accessible >( new AccessibleImpl( actor,
+                                Dali::Accessibility::Role::UNKNOWN ) );
+      };
+
+  size_t len = static_cast<size_t>(Dali::Accessibility::RelationType::MAX_COUNT);
+  mAccessibilityRelations.reserve(len);
+  for (auto i = 0u; i < len; ++i)
+  {
+    mAccessibilityRelations.push_back({});
+  }
 }
 
 Control::Impl::~Impl()
 {
+  AccessibilityDeregister();
   // All gesture detectors will be destroyed so no need to disconnect.
   delete mStartingPinchScale;
+
+  if(mIdleCallback && Adaptor::IsAvailable())
+  {
+    // Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
+    Adaptor::Get().RemoveIdle(mIdleCallback);
+  }
 }
 
 Control::Impl& Control::Impl::Get( Internal::Control& internalControl )
@@ -433,7 +552,7 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
         StopObservingVisual( currentRegisteredVisual );
 
         // If control staged and visual enabled then visuals will be swapped once ready
-        if(  self.OnStage() && enabled )
+        if(  self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) && enabled )
         {
           // Check if visual is currently in the process of being replaced ( is in removal container )
           RegisteredVisualContainer::Iterator visualQueuedForRemoval;
@@ -441,7 +560,7 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
           {
             // Visual with same index is already in removal container so current visual pending
             // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
-            Toolkit::GetImplementation( currentRegisteredVisual ).SetOffStage( self );
+            Toolkit::GetImplementation( currentRegisteredVisual ).SetOffScene( self );
             mVisuals.Erase( registeredVisualsiter );
           }
           else
@@ -473,19 +592,13 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
   // ( If the control has been type registered )
   if( visual.GetName().empty() )
   {
-    try
+    // returns empty string if index is not found as long as index is not -1
+    std::string visualName = self.GetPropertyName( index );
+    if( !visualName.empty() )
     {
-      std::string visualName = self.GetPropertyName( index );
-      if( !visualName.empty() )
-      {
-        DALI_LOG_INFO( gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n",
-                       index, visualName.c_str() );
-        visual.SetName( visualName );
-      }
-    }
-    catch( Dali::DaliException e )
-    {
-      DALI_LOG_WARNING( "Attempting to register visual without a registered property, index: %d\n", index );
+      DALI_LOG_INFO( gLogFilter, Debug::Concise, "Setting visual name for property %d to %s\n",
+                     index, visualName.c_str() );
+      visual.SetName( visualName );
     }
   }
 
@@ -529,9 +642,9 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
 
     Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
     // Put on stage if enabled and the control is already on the stage
-    if( ( enabled == VisualState::ENABLED ) && self.OnStage() )
+    if( ( enabled == VisualState::ENABLED ) && self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
     {
-      visualImpl.SetOnStage( self );
+      visualImpl.SetOnScene( self );
     }
     else if( visualImpl.IsResourceReady() ) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already )
     {
@@ -552,7 +665,7 @@ void Control::Impl::UnregisterVisual( Property::Index index )
     StopObservingVisual( (*iter)->visual );
 
     Actor self( mControlImpl.Self() );
-    Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
+    Toolkit::GetImplementation((*iter)->visual).SetOffScene( self );
     (*iter)->visual.Reset();
     mVisuals.Erase( iter );
   }
@@ -560,7 +673,7 @@ void Control::Impl::UnregisterVisual( Property::Index index )
   if( FindVisual( index, mRemoveVisuals, iter ) )
   {
     Actor self( mControlImpl.Self() );
-    Toolkit::GetImplementation( (*iter)->visual ).SetOffStage( self );
+    Toolkit::GetImplementation( (*iter)->visual ).SetOffScene( self );
     (*iter)->pending = false;
     (*iter)->visual.Reset();
     mRemoveVisuals.Erase( iter );
@@ -593,17 +706,17 @@ void Control::Impl::EnableVisual( Property::Index index, bool enable )
 
     (*iter)->enabled = enable;
     Actor parentActor = mControlImpl.Self();
-    if ( mControlImpl.Self().OnStage() ) // If control not on Stage then Visual will be added when StageConnection is called.
+    if ( mControlImpl.Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) // If control not on Scene then Visual will be added when SceneConnection is called.
     {
       if ( enable )
       {
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index );
-        Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor );
+        Toolkit::GetImplementation((*iter)->visual).SetOnScene( parentActor );
       }
       else
       {
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index );
-        Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor );  // No need to call if control not staged.
+        Toolkit::GetImplementation((*iter)->visual).SetOffScene( parentActor );  // No need to call if control not staged.
       }
     }
   }
@@ -628,15 +741,15 @@ void Control::Impl::StopObservingVisual( Toolkit::Visual::Base& visual )
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
   // Stop observing the visual
-  visualImpl.RemoveResourceObserver( *this );
+  visualImpl.RemoveEventObserver( *this );
 }
 
 void Control::Impl::StartObservingVisual( Toolkit::Visual::Base& visual)
 {
   Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
 
-  // start observing the visual for resource ready
-  visualImpl.AddResourceObserver( *this );
+  // start observing the visual for events
+  visualImpl.AddEventObserver( *this );
 }
 
 // Called by a Visual when it's resource is ready
@@ -661,7 +774,7 @@ void Control::Impl::ResourceReady( Visual::Base& object)
       if( FindVisual( (*registeredIter)->index, mRemoveVisuals, visualToRemoveIter ) )
       {
         (*registeredIter)->pending = false;
-        Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffStage( self );
+        Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffScene( self );
         mRemoveVisuals.Erase( visualToRemoveIter );
       }
       break;
@@ -669,7 +782,7 @@ void Control::Impl::ResourceReady( Visual::Base& object)
   }
 
   // A visual is ready so control may need relayouting if staged
-  if ( self.OnStage() )
+  if ( self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
   {
     mControlImpl.RelayoutRequest();
   }
@@ -677,8 +790,24 @@ void Control::Impl::ResourceReady( Visual::Base& object)
   // Emit signal if all enabled visuals registered by the control are ready.
   if( IsResourceReady() )
   {
-    Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
-    mResourceReadySignal.Emit( handle );
+    // Reset the flag
+    mNeedToEmitResourceReady = false;
+
+    EmitResourceReadySignal();
+  }
+}
+
+void Control::Impl::NotifyVisualEvent( Visual::Base& object, Property::Index signalId )
+{
+  for( auto registeredIter = mVisuals.Begin(),  end = mVisuals.End(); registeredIter != end; ++registeredIter )
+  {
+    Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation( (*registeredIter)->visual );
+    if( &object == &registeredVisualImpl )
+    {
+      Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
+      mVisualEventSignal.Emit( handle, (*registeredIter)->index, signalId );
+      break;
+    }
   }
 }
 
@@ -752,7 +881,7 @@ void Control::Impl::AddTransitions( Dali::Animation& animation,
       Actor child = mControlImpl.Self().FindChildByName( animator->objectName );
       if( child )
       {
-        Property::Index propertyIndex = DevelHandle::GetPropertyIndex( child, animator->propertyKey );
+        Property::Index propertyIndex = child.GetPropertyIndex( animator->propertyKey );
         if( propertyIndex != Property::INVALID_INDEX )
         {
           if( animator->animate == false )
@@ -808,6 +937,20 @@ void Control::Impl::DoAction( Dali::Property::Index visualIndex, Dali::Property:
   }
 }
 
+void Control::Impl::AppendAccessibilityAttribute( const std::string& key,
+                                               const std::string value )
+{
+  Property::Value* val = mAccessibilityAttributes.Find( key );
+  if( val )
+  {
+    mAccessibilityAttributes[key] = Property::Value( value );
+  }
+  else
+  {
+    mAccessibilityAttributes.Insert( key, value );
+  }
+}
+
 void Control::Impl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
 {
   Toolkit::Control control = Toolkit::Control::DownCast( BaseHandle( object ) );
@@ -828,7 +971,7 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
       {
         bool withTransitions=true;
         const Property::Value* valuePtr=&value;
-        Property::Map* map = value.GetMap();
+        const Property::Map* map = value.GetMap();
         if(map)
         {
           Property::Value* value2 = map->Find("withTransitions");
@@ -881,48 +1024,95 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
       }
       break;
 
-      case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
       {
-        int focusId;
-        if( value.Get( focusId ) )
+        std::string name;
+        if( value.Get( name ) )
         {
-          controlImpl.mImpl->mUpFocusableActorId = focusId;
+          controlImpl.mImpl->mAccessibilityName = name;
+          controlImpl.mImpl->mAccessibilityNameSet = true;
+        }
+        else
+        {
+          controlImpl.mImpl->mAccessibilityNameSet = false;
         }
       }
       break;
 
-      case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
       {
-        int focusId;
-        if( value.Get( focusId ) )
+        std::string txt;
+        if( value.Get( txt ) )
         {
-          controlImpl.mImpl->mDownFocusableActorId = focusId;
+          controlImpl.mImpl->mAccessibilityDescription = txt;
+          controlImpl.mImpl->mAccessibilityDescriptionSet = true;
+        }
+        else
+        {
+          controlImpl.mImpl->mAccessibilityDescriptionSet = false;
         }
       }
       break;
 
-      case Toolkit::Control::Property::BACKGROUND_COLOR:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
       {
-        DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
-        controlImpl.SetBackgroundColor( value.Get< Vector4 >() );
-        break;
+        std::string txt;
+        if( value.Get( txt ) )
+        {
+          controlImpl.mImpl->mAccessibilityTranslationDomain = txt;
+          controlImpl.mImpl->mAccessibilityTranslationDomainSet = true;
+        }
+        else
+        {
+          controlImpl.mImpl->mAccessibilityTranslationDomainSet = false;
+        }
       }
+      break;
 
-      case Toolkit::Control::Property::BACKGROUND_IMAGE:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
       {
-        DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
-        Image image = Scripting::NewImage( value );
-        if ( image )
+        bool highlightable;
+        if( value.Get( highlightable ) )
         {
-          controlImpl.SetBackgroundImage( image );
+          controlImpl.mImpl->mAccessibilityHighlightable = highlightable;
+          controlImpl.mImpl->mAccessibilityHighlightableSet = true;
         }
         else
         {
-          // An empty image means the background is no longer required
-          controlImpl.ClearBackground();
+          controlImpl.mImpl->mAccessibilityHighlightableSet = false;
+        }
+      }
+      break;
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+      {
+        Dali::Accessibility::Role val;
+        if( value.Get( val ) )
+        {
+          controlImpl.mImpl->mAccessibilityRole = val;
         }
-        break;
       }
+      break;
+
+      case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
+      {
+        int focusId;
+        if( value.Get( focusId ) )
+        {
+          controlImpl.mImpl->mUpFocusableActorId = focusId;
+        }
+      }
+      break;
+
+      case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
+      {
+        int focusId;
+        if( value.Get( focusId ) )
+        {
+          controlImpl.mImpl->mDownFocusableActorId = focusId;
+        }
+      }
+      break;
 
       case Toolkit::Control::Property::KEY_INPUT_FOCUS:
       {
@@ -998,6 +1188,32 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
         break;
       }
 
+      case Toolkit::DevelControl::Property::SHADOW:
+      {
+        const Property::Map* map = value.GetMap();
+        if( map && !map->Empty() )
+        {
+          controlImpl.mImpl->SetShadow( *map );
+        }
+        else
+        {
+          // The shadow is an empty property map, so we should clear the shadow
+          controlImpl.mImpl->ClearShadow();
+        }
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
+      {
+        value.Get( controlImpl.mImpl->mAccessibilityAttributes );
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+      {
+        value.Get( controlImpl.mImpl->mAccessibilityAnimated );
+        break;
+      }
     }
   }
 }
@@ -1044,35 +1260,57 @@ Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index
         break;
       }
 
-      case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_NAME:
       {
-        value = controlImpl.mImpl->mUpFocusableActorId;
+        if (controlImpl.mImpl->mAccessibilityNameSet)
+        {
+          value = controlImpl.mImpl->mAccessibilityName;
+        }
         break;
       }
 
-      case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_DESCRIPTION:
       {
-        value = controlImpl.mImpl->mDownFocusableActorId;
+        if (controlImpl.mImpl->mAccessibilityDescriptionSet)
+        {
+          value = controlImpl.mImpl->mAccessibilityDescription;
+        }
         break;
       }
 
-      case Toolkit::Control::Property::BACKGROUND_COLOR:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN:
       {
-        DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" );
-        value = controlImpl.GetBackgroundColor();
+        if (controlImpl.mImpl->mAccessibilityTranslationDomainSet)
+        {
+          value = controlImpl.mImpl->mAccessibilityTranslationDomain;
+        }
         break;
       }
 
-      case Toolkit::Control::Property::BACKGROUND_IMAGE:
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE:
       {
-        DALI_LOG_WARNING( "BACKGROUND_IMAGE property is deprecated. Use BACKGROUND property instead\n" );
-        Property::Map map;
-        Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::Control::Property::BACKGROUND );
-        if( visual )
+        if (controlImpl.mImpl->mAccessibilityHighlightableSet)
         {
-          visual.CreatePropertyMap( map );
+          value = controlImpl.mImpl->mAccessibilityHighlightable;
         }
-        value = map;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE:
+      {
+        value = Property::Value(controlImpl.mImpl->mAccessibilityRole);
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID:
+      {
+        value = controlImpl.mImpl->mUpFocusableActorId;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID:
+      {
+        value = controlImpl.mImpl->mDownFocusableActorId;
         break;
       }
 
@@ -1117,12 +1355,118 @@ Property::Value Control::Impl::GetProperty( BaseObject* object, Property::Index
         value = map;
         break;
       }
+
+      case Toolkit::DevelControl::Property::SHADOW:
+      {
+        Property::Map map;
+        Toolkit::Visual::Base visual = controlImpl.mImpl->GetVisual( Toolkit::DevelControl::Property::SHADOW );
+        if( visual )
+        {
+          visual.CreatePropertyMap( map );
+        }
+
+        value = map;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
+      {
+        value = controlImpl.mImpl->mAccessibilityAttributes;
+        break;
+      }
+
+      case Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED:
+      {
+        value = controlImpl.mImpl->mAccessibilityAnimated;
+        break;
+      }
     }
   }
 
   return value;
 }
 
+void Control::Impl::RemoveAccessibilityAttribute( const std::string& key )
+{
+  Property::Value* val = mAccessibilityAttributes.Find( key );
+  if( val )
+    mAccessibilityAttributes[key] = Property::Value();
+}
+
+void Control::Impl::ClearAccessibilityAttributes()
+{
+  mAccessibilityAttributes.Clear();
+}
+
+void Control::Impl::SetAccessibilityReadingInfoType( const Dali::Accessibility::ReadingInfoTypes types )
+{
+  std::string value;
+  if ( types[ Dali::Accessibility::ReadingInfoType::NAME ] )
+  {
+    value += READING_INFO_TYPE_NAME;
+  }
+  if ( types[ Dali::Accessibility::ReadingInfoType::ROLE ] )
+  {
+    if( !value.empty() )
+    {
+      value += READING_INFO_TYPE_SEPARATOR;
+    }
+    value += READING_INFO_TYPE_ROLE;
+  }
+  if ( types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] )
+  {
+    if( !value.empty() )
+    {
+      value += READING_INFO_TYPE_SEPARATOR;
+    }
+    value += READING_INFO_TYPE_DESCRIPTION;
+  }
+  if ( types[ Dali::Accessibility::ReadingInfoType::STATE ] )
+  {
+    if( !value.empty() )
+    {
+      value += READING_INFO_TYPE_SEPARATOR;
+    }
+    value += READING_INFO_TYPE_STATE;
+  }
+  AppendAccessibilityAttribute( READING_INFO_TYPE_ATTRIBUTE_NAME, value );
+}
+
+Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
+{
+  std::string value;
+  auto place = mAccessibilityAttributes.Find( READING_INFO_TYPE_ATTRIBUTE_NAME );
+  if( place )
+  {
+    place->Get( value );
+  }
+
+  if ( value.empty() )
+  {
+    return {};
+  }
+
+  Dali::Accessibility::ReadingInfoTypes types;
+
+  if ( value.find( READING_INFO_TYPE_NAME ) != std::string::npos )
+  {
+    types[ Dali::Accessibility::ReadingInfoType::NAME ] = true;
+  }
+  if ( value.find( READING_INFO_TYPE_ROLE ) != std::string::npos )
+  {
+    types[ Dali::Accessibility::ReadingInfoType::ROLE ] = true;
+  }
+  if ( value.find( READING_INFO_TYPE_DESCRIPTION ) != std::string::npos )
+  {
+    types[ Dali::Accessibility::ReadingInfoType::DESCRIPTION ] = true;
+  }
+  if ( value.find( READING_INFO_TYPE_STATE ) != std::string::npos )
+  {
+    types[ Dali::Accessibility::ReadingInfoType::STATE ] = true;
+  }
+
+  return types;
+}
 
 void  Control::Impl::CopyInstancedProperties( RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties )
 {
@@ -1148,7 +1492,7 @@ void Control::Impl::RemoveVisual( RegisteredVisualContainer& visuals, const std:
     Toolkit::Visual::Base visual = (*visualIter)->visual;
     if( visual && visual.GetName() == visualName )
     {
-      Toolkit::GetImplementation(visual).SetOffStage( self );
+      Toolkit::GetImplementation(visual).SetOffScene( self );
       (*visualIter)->visual.Reset();
       visuals.Erase( visualIter );
       break;
@@ -1362,22 +1706,22 @@ void Control::Impl::SetSubState( const std::string& subStateName, bool withTrans
   }
 }
 
-void Control::Impl::OnStageDisconnection()
+void Control::Impl::OnSceneDisconnection()
 {
   Actor self = mControlImpl.Self();
 
   // Any visuals set for replacement but not yet ready should still be registered.
-  // Reason: If a request was made to register a new visual but the control removed from stage before visual was ready
+  // Reason: If a request was made to register a new visual but the control removed from scene before visual was ready
   // then when this control appears back on stage it should use that new visual.
 
-  // Iterate through all registered visuals and set off stage
-  SetVisualsOffStage( mVisuals, self );
+  // Iterate through all registered visuals and set off scene
+  SetVisualsOffScene( mVisuals, self );
 
-  // Visuals pending replacement can now be taken out of the removal list and set off stage
-  // Iterate through all replacement visuals and add to a move queue then set off stage
+  // Visuals pending replacement can now be taken out of the removal list and set off scene
+  // Iterate through all replacement visuals and add to a move queue then set off scene
   for( auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++ )
   {
-    Toolkit::GetImplementation((*removalIter)->visual).SetOffStage( self );
+    Toolkit::GetImplementation((*removalIter)->visual).SetOffScene( self );
   }
 
   for( auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++ )
@@ -1391,6 +1735,9 @@ void Control::Impl::OnStageDisconnection()
 void Control::Impl::SetMargin( Extents margin )
 {
   mControlImpl.mImpl->mMargin = margin;
+
+  // Trigger a size negotiation request that may be needed when setting a margin.
+  mControlImpl.RelayoutRequest();
 }
 
 Extents Control::Impl::GetMargin() const
@@ -1401,6 +1748,9 @@ Extents Control::Impl::GetMargin() const
 void Control::Impl::SetPadding( Extents padding )
 {
   mControlImpl.mImpl->mPadding = padding;
+
+  // Trigger a size negotiation request that may be needed when setting a padding.
+  mControlImpl.RelayoutRequest();
 }
 
 Extents Control::Impl::GetPadding() const
@@ -1424,22 +1774,498 @@ bool Control::Impl::FilterKeyEvent( const KeyEvent& event )
   return consumed;
 }
 
-Toolkit::Internal::LayoutItemPtr Control::Impl::GetLayout() const
+DevelControl::VisualEventSignalType& Control::Impl::VisualEventSignal()
+{
+  return mVisualEventSignal;
+}
+
+void Control::Impl::SetShadow( const Property::Map& map )
+{
+  Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( map );
+  visual.SetName("shadow");
+
+  if( visual )
+  {
+    mControlImpl.mImpl->RegisterVisual( Toolkit::DevelControl::Property::SHADOW, visual, DepthIndex::BACKGROUND_EFFECT );
+
+    mControlImpl.RelayoutRequest();
+  }
+}
+
+void Control::Impl::ClearShadow()
+{
+   mControlImpl.mImpl->UnregisterVisual( Toolkit::DevelControl::Property::SHADOW );
+
+   // Trigger a size negotiation request that may be needed when unregistering a visual.
+   mControlImpl.RelayoutRequest();
+}
+
+void Control::Impl::EmitResourceReadySignal()
+{
+  if(!mIsEmittingResourceReadySignal)
+  {
+    // Guard against calls to emit the signal during the callback
+    mIsEmittingResourceReadySignal = true;
+
+    // If the signal handler changes visual, it may become ready during this call & therefore this method will
+    // get called again recursively. If so, mNeedToEmitResourceReady is set below, and we act on it after that secondary
+    // invocation has completed by notifying in an Idle callback to prevent further recursion.
+    Dali::Toolkit::Control handle(mControlImpl.GetOwner());
+    mResourceReadySignal.Emit(handle);
+
+    if(mNeedToEmitResourceReady)
+    {
+      // Add idler to emit the signal again
+      if(!mIdleCallback)
+      {
+        // The callback manager takes the ownership of the callback object.
+        mIdleCallback = MakeCallback( this, &Control::Impl::OnIdleCallback);
+        Adaptor::Get().AddIdle(mIdleCallback, false);
+      }
+    }
+
+    mIsEmittingResourceReadySignal = false;
+  }
+  else
+  {
+    mNeedToEmitResourceReady = true;
+  }
+}
+
+void Control::Impl::OnIdleCallback()
+{
+  if(mNeedToEmitResourceReady)
+  {
+    // Reset the flag
+    mNeedToEmitResourceReady = false;
+
+    // A visual is ready so control may need relayouting if staged
+    if(mControlImpl.Self().GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+    {
+      mControlImpl.RelayoutRequest();
+    }
+
+    EmitResourceReadySignal();
+  }
+
+  // Set the pointer to null as the callback manager deletes the callback after execute it.
+  mIdleCallback = nullptr;
+}
+
+Dali::Accessibility::Accessible *Control::Impl::GetAccessibilityObject()
+{
+  if( !accessibilityObject )
+    accessibilityObject = accessibilityConstructor( mControlImpl.Self() );
+  return accessibilityObject.get();
+}
+
+Dali::Accessibility::Accessible *Control::Impl::GetAccessibilityObject(Dali::Actor actor)
+{
+  if( actor )
+  {
+    auto q = Dali::Toolkit::Control::DownCast( actor );
+    if( q )
+    {
+      auto q2 = static_cast< Internal::Control* >( &q.GetImplementation() );
+      return q2->mImpl->GetAccessibilityObject();
+    }
+  }
+  return nullptr;
+}
+
+Control::Impl::AccessibleImpl::AccessibleImpl(Dali::Actor self, Dali::Accessibility::Role role, bool modal)
+  : self(self), modal(modal)
+{
+  auto control = Dali::Toolkit::Control::DownCast(self);
+
+  Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+  Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+  if( controlImpl.mAccessibilityRole == Dali::Accessibility::Role::UNKNOWN )
+    controlImpl.mAccessibilityRole = role;
+}
+
+std::string Control::Impl::AccessibleImpl::GetName()
+{
+  auto control = Dali::Toolkit::Control::DownCast(self);
+
+  Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+  Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+  if (!controlImpl.mAccessibilityGetNameSignal.Empty()) {
+      std::string ret;
+      controlImpl.mAccessibilityGetNameSignal.Emit(ret);
+      return ret;
+  }
+
+  if (controlImpl.mAccessibilityNameSet)
+    return controlImpl.mAccessibilityName;
+
+  if (auto raw = GetNameRaw(); !raw.empty())
+    return raw;
+
+  return self.GetProperty< std::string >( Actor::Property::NAME );
+}
+
+std::string Control::Impl::AccessibleImpl::GetNameRaw()
+{
+  return {};
+}
+
+std::string Control::Impl::AccessibleImpl::GetDescription()
+{
+  auto control = Dali::Toolkit::Control::DownCast(self);
+
+  Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+  Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+  if (!controlImpl.mAccessibilityGetDescriptionSignal.Empty()) {
+      std::string ret;
+      controlImpl.mAccessibilityGetDescriptionSignal.Emit(ret);
+      return ret;
+  }
+
+  if (controlImpl.mAccessibilityDescriptionSet)
+    return controlImpl.mAccessibilityDescription;
+
+  return GetDescriptionRaw();
+}
+
+std::string Control::Impl::AccessibleImpl::GetDescriptionRaw()
+{
+  return "";
+}
+
+Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetParent()
+{
+  return Dali::Accessibility::Accessible::Get( self.GetParent() );
+}
+
+size_t Control::Impl::AccessibleImpl::GetChildCount()
+{
+  return self.GetChildCount();
+}
+
+Dali::Accessibility::Accessible* Control::Impl::AccessibleImpl::GetChildAtIndex( size_t index )
+{
+  return Dali::Accessibility::Accessible::Get( self.GetChildAt( static_cast< unsigned int >( index ) ) );
+}
+
+size_t Control::Impl::AccessibleImpl::GetIndexInParent()
+{
+  auto s = self;
+  auto parent = s.GetParent();
+  DALI_ASSERT_ALWAYS( parent && "can't call GetIndexInParent on object without parent" );
+  auto count = parent.GetChildCount();
+  for( auto i = 0u; i < count; ++i )
+  {
+    auto c = parent.GetChildAt( i );
+    if( c == s )
+      return i;
+  }
+  DALI_ASSERT_ALWAYS( false && "object isn't child of it's parent" );
+  return static_cast<size_t>(-1);
+}
+
+Dali::Accessibility::Role Control::Impl::AccessibleImpl::GetRole()
+{
+  return self.GetProperty<Dali::Accessibility::Role>( Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE );
+}
+
+Dali::Accessibility::States Control::Impl::AccessibleImpl::CalculateStates()
+{
+  Dali::Accessibility::States s;
+  s[Dali::Accessibility::State::FOCUSABLE] = self.GetProperty< bool >( Actor::Property::KEYBOARD_FOCUSABLE );
+  s[Dali::Accessibility::State::FOCUSED] = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
+  if(self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).GetType() == Property::NONE )
+    s[Dali::Accessibility::State::HIGHLIGHTABLE] = false;
+  else
+    s[Dali::Accessibility::State::HIGHLIGHTABLE] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE ).Get< bool >();
+  s[Dali::Accessibility::State::HIGHLIGHTED] = GetCurrentlyHighlightedActor() == self;
+  s[Dali::Accessibility::State::ENABLED] = true;
+  s[Dali::Accessibility::State::SENSITIVE] = true;
+  s[Dali::Accessibility::State::ANIMATED] = self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >();
+  s[Dali::Accessibility::State::VISIBLE] = self.GetCurrentProperty< bool >( Actor::Property::VISIBLE );
+  if( modal )
+  {
+    s[Dali::Accessibility::State::MODAL] = true;
+  }
+  s[Dali::Accessibility::State::SHOWING] = !self.GetProperty( Dali::DevelActor::Property::CULLED ).Get< bool >();
+  s[Dali::Accessibility::State::DEFUNCT] = !self.GetProperty( Dali::DevelActor::Property::CONNECTED_TO_SCENE ).Get< bool >();
+  return s;
+}
+
+Dali::Accessibility::States Control::Impl::AccessibleImpl::GetStates()
+{
+  return CalculateStates();
+}
+
+Dali::Accessibility::Attributes Control::Impl::AccessibleImpl::GetAttributes()
+{
+  std::unordered_map< std::string, std::string > attribute_map;
+  auto q = Dali::Toolkit::Control::DownCast( self );
+  auto w =
+      q.GetProperty( Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES );
+  auto z = w.GetMap();
+
+  if( z )
+  {
+    auto map_size = z->Count();
+
+    for( unsigned int i = 0; i < map_size; i++ )
+    {
+      auto map_key = z->GetKeyAt( i );
+      if( map_key.type == Property::Key::STRING )
+      {
+        std::string map_value;
+        if( z->GetValue( i ).Get( map_value ) )
+        {
+          attribute_map.emplace( std::move( map_key.stringKey ),
+                                 std::move( map_value ) );
+        }
+      }
+    }
+  }
+
+  return attribute_map;
+}
+
+Dali::Accessibility::ComponentLayer Control::Impl::AccessibleImpl::GetLayer()
+{
+  return Dali::Accessibility::ComponentLayer::WINDOW;
+}
+
+Dali::Rect<> Control::Impl::AccessibleImpl::GetExtents( Dali::Accessibility::CoordType ctype )
+{
+  Vector2 screenPosition =
+      self.GetProperty( Dali::DevelActor::Property::SCREEN_POSITION )
+          .Get< Vector2 >();
+  auto size = self.GetCurrentProperty< Vector3 >( Actor::Property::SIZE ) * self.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_SCALE );
+  bool positionUsesAnchorPoint =
+      self.GetProperty( Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT )
+          .Get< bool >();
+  Vector3 anchorPointOffSet =
+      size * ( positionUsesAnchorPoint ? self.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT )
+                                       : AnchorPoint::TOP_LEFT );
+  Vector2 position = Vector2( screenPosition.x - anchorPointOffSet.x,
+                              screenPosition.y - anchorPointOffSet.y );
+
+  return { position.x, position.y, size.x, size.y };
+}
+
+int16_t Control::Impl::AccessibleImpl::GetMdiZOrder() { return 0; }
+double Control::Impl::AccessibleImpl::GetAlpha() { return 0; }
+
+bool Control::Impl::AccessibleImpl::GrabFocus()
+{
+  return Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( self );
+}
+
+const char* const FOCUS_BORDER_IMAGE_PATH = DALI_IMAGE_DIR "keyboard_focus.9.png";
+
+static Dali::Actor CreateHighlightIndicatorActor()
+{
+  // Create the default if it hasn't been set and one that's shared by all the
+  // keyboard focusable actors const char* const FOCUS_BORDER_IMAGE_PATH =
+  // DALI_IMAGE_DIR "keyboard_focus.9.png";
+  auto actor = Toolkit::ImageView::New( FOCUS_BORDER_IMAGE_PATH );
+  actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  DevelControl::AppendAccessibilityAttribute( actor, "highlight", "" );
+  actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED, true);
+  actor.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, false );
+
+  return actor;
+}
+
+bool Control::Impl::AccessibleImpl::GrabHighlight()
+{
+  auto old = GetCurrentlyHighlightedActor();
+
+  if( !Dali::Accessibility::IsUp() )
+      return false;
+  if( self == old )
+    return true;
+  if( old )
+  {
+    auto c = dynamic_cast< Dali::Accessibility::Component* >( GetAccessibilityObject( old ) );
+    if( c )
+      c->ClearHighlight();
+  }
+  auto highlight = GetHighlightActor();
+  if ( !highlight )
+  {
+    highlight = CreateHighlightIndicatorActor();
+    SetHighlightActor( highlight );
+  }
+  highlight.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
+  highlight.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
+  highlight.SetProperty( Actor::Property::POSITION_Z, 1.0f );
+  highlight.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, 0.0f ));
+
+  EnsureSelfVisible();
+  self.Add( highlight );
+  SetCurrentlyHighlightedActor( self );
+  EmitHighlighted( true );
+
+  return true;
+}
+
+
+
+bool Control::Impl::AccessibleImpl::ClearHighlight()
+{
+  if( !Dali::Accessibility::IsUp() )
+    return false;
+  if( GetCurrentlyHighlightedActor() == self )
+  {
+    self.Remove( GetHighlightActor() );
+    SetCurrentlyHighlightedActor( {} );
+    EmitHighlighted( false );
+    return true;
+  }
+  return false;
+}
+
+int Control::Impl::AccessibleImpl::GetHighlightIndex()
+{
+  return 0;
+}
+
+std::string Control::Impl::AccessibleImpl::GetActionName( size_t index )
+{
+  if ( index >= GetActionCount() ) return "";
+  Dali::TypeInfo type;
+  self.GetTypeInfo( type );
+  DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
+  return type.GetActionName( index );
+}
+std::string Control::Impl::AccessibleImpl::GetLocalizedActionName( size_t index )
+{
+  // TODO: add localization
+  return GetActionName( index );
+}
+std::string Control::Impl::AccessibleImpl::GetActionDescription( size_t index )
+{
+  return "";
+}
+size_t Control::Impl::AccessibleImpl::GetActionCount()
+{
+  Dali::TypeInfo type;
+  self.GetTypeInfo( type );
+  DALI_ASSERT_ALWAYS( type && "no TypeInfo object" );
+  return type.GetActionCount();
+}
+std::string Control::Impl::AccessibleImpl::GetActionKeyBinding( size_t index )
+{
+  return "";
+}
+bool Control::Impl::AccessibleImpl::DoAction( size_t index )
+{
+  std::string actionName = GetActionName( index );
+  return self.DoAction( actionName, {} );
+}
+bool Control::Impl::AccessibleImpl::DoAction(const std::string& name)
+{
+  return self.DoAction( name, {} );
+}
+
+bool Control::Impl::AccessibleImpl::DoGesture(const Dali::Accessibility::GestureInfo &gestureInfo)
+{
+  auto control = Dali::Toolkit::Control::DownCast(self);
+
+  Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+  Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+  if (!controlImpl.mAccessibilityDoGestureSignal.Empty()) {
+      auto ret = std::make_pair(gestureInfo, false);
+      controlImpl.mAccessibilityDoGestureSignal.Emit(ret);
+      return ret.second;
+  }
+
+  return false;
+}
+
+std::vector<Dali::Accessibility::Relation> Control::Impl::AccessibleImpl::GetRelationSet()
+{
+  auto control = Dali::Toolkit::Control::DownCast(self);
+
+  Internal::Control& internalControl = Toolkit::Internal::GetImplementation( control );
+  Internal::Control::Impl& controlImpl = Internal::Control::Impl::Get( internalControl );
+
+  std::vector<Dali::Accessibility::Relation> ret;
+
+  auto &v = controlImpl.mAccessibilityRelations;
+  for (auto i = 0u; i < v.size(); ++i)
+  {
+    if ( v[i].empty() )
+      continue;
+
+    ret.emplace_back( Accessibility::Relation{ static_cast<Accessibility::RelationType>(i), v[i] } );
+  }
+
+  return ret;
+}
+
+void Control::Impl::AccessibleImpl::EnsureChildVisible(Actor child)
+{
+}
+
+void Control::Impl::AccessibleImpl::EnsureSelfVisible()
 {
-  return mLayout;
+  auto parent = dynamic_cast<Control::Impl::AccessibleImpl*>(GetParent());
+  if (parent)
+  {
+    parent->EnsureChildVisible(self);
+  }
 }
 
-void Control::Impl::SetLayout( Toolkit::Internal::LayoutItem& layout )
+void Control::Impl::PositionOrSizeChangedCallback( PropertyNotification &p )
 {
-  if( mLayout )
+  auto self = Dali::Actor::DownCast(p.GetTarget());
+  if (Dali::Accessibility::IsUp() && !self.GetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_ANIMATED ).Get< bool >())
   {
-    mLayout->Unparent();
-    mLayout.Reset();
+    auto extents = DevelActor::CalculateScreenExtents( self );
+    Dali::Accessibility::Accessible::Get( self )->EmitBoundsChanged( extents );
   }
-  mLayout = &layout;
+}
 
-  auto controlHandle = Toolkit::Control::DownCast( mControlImpl.Self() ); // Get a handle of this control implementation without copying internals.
-  mLayout->Initialize( controlHandle, controlHandle.GetTypeName() ); // LayoutGroup takes ownership of existing children
+void Control::Impl::CulledChangedCallback( PropertyNotification &p)
+{
+  if (Dali::Accessibility::IsUp())
+  {
+    auto self = Dali::Actor::DownCast(p.GetTarget());
+    Dali::Accessibility::Accessible::Get(self)->EmitShowing( !self.GetProperty( DevelActor::Property::CULLED ).Get<bool>() );
+  }
+}
+
+void Control::Impl::AccessibilityRegister()
+{
+  if (!accessibilityNotificationSet)
+  {
+    accessibilityNotificationPosition = mControlImpl.Self().AddPropertyNotification( Actor::Property::POSITION, StepCondition( 0.01f ) );
+    accessibilityNotificationPosition.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
+    accessibilityNotificationPosition.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
+
+    accessibilityNotificationSize = mControlImpl.Self().AddPropertyNotification( Actor::Property::SIZE, StepCondition( 0.01f ) );
+    accessibilityNotificationSize.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
+    accessibilityNotificationSize.NotifySignal().Connect( &Control::Impl::PositionOrSizeChangedCallback );
+
+    accessibilityNotificationCulled = mControlImpl.Self().AddPropertyNotification( DevelActor::Property::CULLED, LessThanCondition( 0.5f ) );
+    accessibilityNotificationCulled.SetNotifyMode( PropertyNotification::NOTIFY_ON_CHANGED );
+    accessibilityNotificationCulled.NotifySignal().Connect( &Control::Impl::CulledChangedCallback );
+
+    accessibilityNotificationSet = true;
+  }
+}
+
+void Control::Impl::AccessibilityDeregister()
+{
+  if (accessibilityNotificationSet)
+  {
+    accessibilityNotificationPosition = {};
+    accessibilityNotificationSize = {};
+    accessibilityNotificationCulled = {};
+    accessibilityNotificationSet = false;
+  }
 }
 
 } // namespace Internal