X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Faccessibility%2Fbridge%2Fbridge-impl.cpp;h=27525b4a466bce70cb116f59128e4ff28366ce46;hb=4142d89e56dd24cce6daad87562527b52f332301;hp=181b44015261383f189ec5d0cf84a094f2b6ba44;hpb=93492c5bc9f16bc609650f7ec06b89aacafacd64;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/accessibility/bridge/bridge-impl.cpp b/dali/internal/accessibility/bridge/bridge-impl.cpp index 181b440..27525b4 100644 --- a/dali/internal/accessibility/bridge/bridge-impl.cpp +++ b/dali/internal/accessibility/bridge/bridge-impl.cpp @@ -43,6 +43,13 @@ using namespace Dali::Accessibility; +namespace // unnamed namespace +{ + +const int RETRY_INTERVAL = 1000; + +} // unnamed namespace + /** * @brief The BridgeImpl class is to implement some Bridge functions. */ @@ -68,6 +75,9 @@ class BridgeImpl : public virtual BridgeBase, Dali::Actor mHighlightedActor; std::function mHighlightClearAction; Dali::CallbackBase* mIdleCallback = NULL; + Dali::Timer mInitializeTimer; + Dali::Timer mReadIsEnabledTimer; + Dali::Timer mReadScreenReaderEnabledTimer; public: BridgeImpl() @@ -217,6 +227,25 @@ public: mRegistryClient = {}; mDirectReadingClient = {}; mDirectReadingCallbacks.clear(); + mApplication.mChildren.clear(); + } + + void StopTimer() + { + if(mInitializeTimer) + { + mInitializeTimer.Stop(); + } + + if(mReadIsEnabledTimer) + { + mReadIsEnabledTimer.Stop(); + } + + if(mReadScreenReaderEnabledTimer) + { + mReadScreenReaderEnabledTimer.Stop(); + } } /** @@ -230,6 +259,7 @@ public: mData->mHighlightActor = {}; } ForceDown(); + StopTimer(); if((NULL != mIdleCallback) && Dali::Adaptor::IsAvailable()) { Dali::Adaptor::Get().RemoveIdle(mIdleCallback); @@ -287,10 +317,6 @@ public: assert(res); mApplication.mParent.SetAddress(std::move(std::get<0>(res))); - if(mIsShown) - { - EmitActivate(); - } mEnabledSignal.Emit(); @@ -298,83 +324,149 @@ public: } /** - * @brief Sends a signal to dbus that the default window is activated. + * @brief Sends a signal to dbus that the window is shown. * - * TODO : This is subject to change if/when we implement multi-window support. - * @see BridgeObject::Emit() + * @param[in] window The window to be shown + * @see Accessible::EmitShowing() and BridgeObject::EmitStateChanged() + */ + void EmitShown(Dali::Window window) + { + auto windowAccessible = mApplication.GetWindowAccessible(window); + if(windowAccessible) + { + windowAccessible->EmitShowing(true); + } + } + + /** + * @brief Sends a signal to dbus that the window is hidden. + * + * @param[in] window The window to be hidden + * @see Accessible::EmitShowing() and BridgeObject::EmitStateChanged() */ - void EmitActivate() + void EmitHidden(Dali::Window window) { - auto win = mApplication.GetActiveWindow(); - if(win) + auto windowAccessible = mApplication.GetWindowAccessible(window); + if(windowAccessible) { - win->Emit(WindowEvent::ACTIVATE, 0); + windowAccessible->EmitShowing(false); } } /** - * @brief Sends a signal to dbus that the default window is deactivated. + * @brief Sends a signal to dbus that the window is activated. * - * TODO : This is subject to change if/when we implement multi-window support. + * @param[in] window The window to be activated * @see BridgeObject::Emit() */ - void EmitDeactivate() + void EmitActivate(Dali::Window window) { - auto win = mApplication.GetActiveWindow(); - if(win) + auto windowAccessible = mApplication.GetWindowAccessible(window); + if(windowAccessible) { - win->Emit(WindowEvent::DEACTIVATE, 0); + windowAccessible->Emit(WindowEvent::ACTIVATE, 0); } } /** - * @copydoc Dali::Accessibility::Bridge::WindowHidden() + * @brief Sends a signal to dbus that the window is deactivated. + * + * @param[in] window The window to be deactivated + * @see BridgeObject::Emit() */ - void WindowHidden() override + void EmitDeactivate(Dali::Window window) { - if(mIsShown && IsUp()) + auto windowAccessible = mApplication.GetWindowAccessible(window); + if(windowAccessible) { - EmitDeactivate(); + windowAccessible->Emit(WindowEvent::DEACTIVATE, 0); } - mIsShown = false; } /** * @copydoc Dali::Accessibility::Bridge::WindowShown() */ - void WindowShown() override + void WindowShown(Dali::Window window) override { if(!mIsShown && IsUp()) { - EmitActivate(); + EmitShown(window); } mIsShown = true; } - void ReadAndListenProperty() + /** + * @copydoc Dali::Accessibility::Bridge::WindowHidden() + */ + void WindowHidden(Dali::Window window) override { - // read property - auto enabled = mAccessibilityStatusClient.property("ScreenReaderEnabled").get(); - if(enabled) + if(mIsShown && IsUp()) { - mIsScreenReaderEnabled = std::get<0>(enabled); + EmitHidden(window); } + mIsShown = false; + } - enabled = mAccessibilityStatusClient.property("IsEnabled").get(); - if(enabled) + /** + * @copydoc Dali::Accessibility::Bridge::WindowFocused() + */ + void WindowFocused(Dali::Window window) override + { + if(mIsShown && IsUp()) { - mIsEnabled = std::get<0>(enabled); + EmitActivate(window); } + } - if(mIsScreenReaderEnabled || mIsEnabled) + /** + * @copydoc Dali::Accessibility::Bridge::WindowUnfocused() + */ + void WindowUnfocused(Dali::Window window) override + { + if(mIsShown && IsUp()) { - ForceUp(); + EmitDeactivate(window); } + } - // listen property change - mAccessibilityStatusClient.addPropertyChangedEvent("ScreenReaderEnabled", [this](bool res) { - mIsScreenReaderEnabled = res; - if(mIsScreenReaderEnabled || mIsEnabled) + /** + * @copydoc Dali::Accessibility::Bridge::SuppressScreenReader() + */ + void SuppressScreenReader(bool suppress) override + { + if(mIsScreenReaderSuppressed == suppress) + { + return; + } + mIsScreenReaderSuppressed = suppress; + ReadScreenReaderEnabledProperty(); + } + + bool ReadIsEnabledTimerCallback() + { + ReadIsEnabledProperty(); + return false; + } + + void ReadIsEnabledProperty() + { + mAccessibilityStatusClient.property("IsEnabled").asyncGet([this](DBus::ValueOrError msg) { + if(!msg) + { + DALI_LOG_ERROR("Get IsEnabled property error: %s\n", msg.getError().message.c_str()); + if(msg.getError().errorType == DBus::ErrorType::INVALID_REPLY) + { + if(!mReadIsEnabledTimer) + { + mReadIsEnabledTimer = Dali::Timer::New(RETRY_INTERVAL); + mReadIsEnabledTimer.TickSignal().Connect(this, &BridgeImpl::ReadIsEnabledTimerCallback); + } + mReadIsEnabledTimer.Start(); + } + return; + } + mIsEnabled = std::get<0>(msg); + if((!mIsScreenReaderSuppressed && mIsScreenReaderEnabled) || mIsEnabled) { ForceUp(); } @@ -383,7 +475,10 @@ public: ForceDown(); } }); + } + void ListenIsEnabledProperty() + { mAccessibilityStatusClient.addPropertyChangedEvent("IsEnabled", [this](bool res) { mIsEnabled = res; if(mIsScreenReaderEnabled || mIsEnabled) @@ -397,6 +492,71 @@ public: }); } + bool ReadScreenReaderEnabledTimerCallback() + { + ReadScreenReaderEnabledProperty(); + return false; + } + + void ReadScreenReaderEnabledProperty() + { + // can be true because of SuppressScreenReader before init + if (!mAccessibilityStatusClient) + { + return; + } + + mAccessibilityStatusClient.property("ScreenReaderEnabled").asyncGet([this](DBus::ValueOrError msg) { + if(!msg) + { + DALI_LOG_ERROR("Get ScreenReaderEnabled property error: %s\n", msg.getError().message.c_str()); + if(msg.getError().errorType == DBus::ErrorType::INVALID_REPLY) + { + if(!mReadScreenReaderEnabledTimer) + { + mReadScreenReaderEnabledTimer = Dali::Timer::New(RETRY_INTERVAL); + mReadScreenReaderEnabledTimer.TickSignal().Connect(this, &BridgeImpl::ReadScreenReaderEnabledTimerCallback); + } + mReadScreenReaderEnabledTimer.Start(); + } + return; + } + mIsScreenReaderEnabled = std::get<0>(msg); + if((!mIsScreenReaderSuppressed && mIsScreenReaderEnabled) || mIsEnabled) + { + ForceUp(); + } + else + { + ForceDown(); + } + }); + } + + void ListenScreenReaderEnabledProperty() + { + mAccessibilityStatusClient.addPropertyChangedEvent("ScreenReaderEnabled", [this](bool res) { + mIsScreenReaderEnabled = res; + if((!mIsScreenReaderSuppressed && mIsScreenReaderEnabled) || mIsEnabled) + { + ForceUp(); + } + else + { + ForceDown(); + } + }); + } + + void ReadAndListenProperties() + { + ReadIsEnabledProperty(); + ListenIsEnabledProperty(); + + ReadScreenReaderEnabledProperty(); + ListenScreenReaderEnabledProperty(); + } + bool InitializeAccessibilityStatusClient() { mAccessibilityStatusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION}; @@ -410,16 +570,34 @@ public: return true; } + bool InitializeTimerCallback() + { + if ( InitializeAccessibilityStatusClient() ) + { + ReadAndListenProperties(); + return false; + } + return true; + } + bool OnIdleSignal() { if ( InitializeAccessibilityStatusClient() ) { - ReadAndListenProperty(); + ReadAndListenProperties(); mIdleCallback = NULL; return false; } - return true; + if(!mInitializeTimer) + { + mInitializeTimer = Dali::Timer::New(RETRY_INTERVAL); + mInitializeTimer.TickSignal().Connect(this, &BridgeImpl::InitializeTimerCallback); + } + mInitializeTimer.Start(); + + mIdleCallback = NULL; + return false; } /** @@ -429,7 +607,7 @@ public: { if ( InitializeAccessibilityStatusClient() ) { - ReadAndListenProperty(); + ReadAndListenProperties(); return; } @@ -543,17 +721,19 @@ void Bridge::EnableAutoInit() return; } - auto rootLayer = Dali::Stage::GetCurrent().GetRootLayer(); + auto rootLayer = Dali::Stage::GetCurrent().GetRootLayer(); // A root layer of the default window. auto window = Dali::DevelWindow::Get(rootLayer); auto applicationName = Dali::Internal::Adaptor::Adaptor::GetApplicationPackageName(); + auto accessible = Accessibility::Accessible::Get(rootLayer, true); + auto* bridge = Bridge::GetCurrentBridge(); - bridge->AddTopLevelWindow(Dali::Accessibility::Accessible::Get(rootLayer, true)); + bridge->AddTopLevelWindow(accessible); bridge->SetApplicationName(applicationName); bridge->Initialize(); if(window && window.IsVisible()) { - bridge->WindowShown(); + bridge->WindowShown(window); } }