X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Faccessibility%2Fbridge%2Fbridge-impl.cpp;h=181b44015261383f189ec5d0cf84a094f2b6ba44;hb=93492c5bc9f16bc609650f7ec06b89aacafacd64;hp=aaed7fbf250172ad07716bc194a39faa6825ebd1;hpb=c7d6824912dc232e9e3eb46d1fb9b32710bf285d;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 aaed7fb..181b440 100644 --- a/dali/internal/accessibility/bridge/bridge-impl.cpp +++ b/dali/internal/accessibility/bridge/bridge-impl.cpp @@ -43,6 +43,9 @@ using namespace Dali::Accessibility; +/** + * @brief The BridgeImpl class is to implement some Bridge functions. + */ class BridgeImpl : public virtual BridgeBase, public BridgeAccessible, public BridgeObject, @@ -55,45 +58,25 @@ class BridgeImpl : public virtual BridgeBase, public BridgeSelection, public BridgeApplication { - DBus::DBusClient listenOnAtspiEnabledSignalClient; - DBus::DBusClient registryClient, directReadingClient; - bool screenReaderEnabled = false; - bool isEnabled = false; - bool isShown = false; - std::unordered_map> directReadingCallbacks; - Dali::Actor highlightedActor; - std::function highlightClearAction; + DBus::DBusClient mAccessibilityStatusClient; + DBus::DBusClient mRegistryClient; + DBus::DBusClient mDirectReadingClient; + bool mIsScreenReaderEnabled = false; + bool mIsEnabled = false; + bool mIsShown = false; + std::unordered_map> mDirectReadingCallbacks; + Dali::Actor mHighlightedActor; + std::function mHighlightClearAction; + Dali::CallbackBase* mIdleCallback = NULL; public: BridgeImpl() { - listenOnAtspiEnabledSignalClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION}; - - listenOnAtspiEnabledSignalClient.addPropertyChangedEvent("ScreenReaderEnabled", [this](bool res) { - screenReaderEnabled = res; - if(screenReaderEnabled || isEnabled) - { - ForceUp(); - } - else - { - ForceDown(); - } - }); - - listenOnAtspiEnabledSignalClient.addPropertyChangedEvent("IsEnabled", [this](bool res) { - isEnabled = res; - if(screenReaderEnabled || isEnabled) - { - ForceUp(); - } - else - { - ForceDown(); - } - }); } + /** + * @copydoc Dali::Accessibility::Bridge::Emit() + */ Consumed Emit(KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) override { if(!IsUp()) @@ -120,8 +103,9 @@ public: return Consumed::NO; } } - auto m = registryClient.method)>("NotifyListenersSync"); - auto result = m.call(std::tuple{keyType, 0, static_cast(keyCode), 0, static_cast(timeStamp), keyName, isText ? 1 : 0}); + + auto methodObject = mRegistryClient.method)>("NotifyListenersSync"); + auto result = methodObject.call(std::tuple{keyType, 0, static_cast(keyCode), 0, static_cast(timeStamp), keyName, isText ? 1 : 0}); if(!result) { LOG() << result.getError().message; @@ -130,6 +114,9 @@ public: return std::get<0>(result) ? Consumed::YES : Consumed::NO; } + /** + * @copydoc Dali::Accessibility::Bridge::Pause() + */ void Pause() override { if(!IsUp()) @@ -137,7 +124,7 @@ public: return; } - directReadingClient.method(bool)>("PauseResume").asyncCall([](DBus::ValueOrError msg) { + mDirectReadingClient.method(bool)>("PauseResume").asyncCall([](DBus::ValueOrError msg) { if(!msg) { LOG() << "Direct reading command failed (" << msg.getError().message << ")"; @@ -146,6 +133,9 @@ public: true); } + /** + * @copydoc Dali::Accessibility::Bridge::Resume() + */ void Resume() override { if(!IsUp()) @@ -153,7 +143,7 @@ public: return; } - directReadingClient.method(bool)>("PauseResume").asyncCall([](DBus::ValueOrError msg) { + mDirectReadingClient.method(bool)>("PauseResume").asyncCall([](DBus::ValueOrError msg) { if(!msg) { LOG() << "Direct reading command failed (" << msg.getError().message << ")"; @@ -162,6 +152,9 @@ public: false); } + /** + * @copydoc Dali::Accessibility::Bridge::StopReading() + */ void StopReading(bool alsoNonDiscardable) override { if(!IsUp()) @@ -169,7 +162,7 @@ public: return; } - directReadingClient.method(bool)>("StopReading").asyncCall([](DBus::ValueOrError msg) { + mDirectReadingClient.method(bool)>("StopReading").asyncCall([](DBus::ValueOrError msg) { if(!msg) { LOG() << "Direct reading command failed (" << msg.getError().message << ")"; @@ -178,6 +171,9 @@ public: alsoNonDiscardable); } + /** + * @copydoc Dali::Accessibility::Bridge::Say() + */ void Say(const std::string& text, bool discardable, std::function callback) override { if(!IsUp()) @@ -185,20 +181,23 @@ public: return; } - directReadingClient.method(std::string, bool)>("ReadCommand").asyncCall([=](DBus::ValueOrError msg) { + mDirectReadingClient.method(std::string, bool)>("ReadCommand").asyncCall([=](DBus::ValueOrError msg) { if(!msg) { LOG() << "Direct reading command failed (" << msg.getError().message << ")"; } else if(callback) { - directReadingCallbacks.emplace(std::get<2>(msg), callback); + mDirectReadingCallbacks.emplace(std::get<2>(msg), callback); } }, text, discardable); } + /** + * @copydoc Dali::Accessibility::Bridge::ForceDown() + */ void ForceDown() override { if(mData) @@ -209,15 +208,20 @@ public: } mData->mCurrentlyHighlightedActor = {}; mData->mHighlightActor = {}; + + mDisabledSignal.Emit(); } - highlightedActor = {}; - highlightClearAction = {}; + mHighlightedActor = {}; + mHighlightClearAction = {}; BridgeAccessible::ForceDown(); - registryClient = {}; - directReadingClient = {}; - directReadingCallbacks.clear(); + mRegistryClient = {}; + mDirectReadingClient = {}; + mDirectReadingCallbacks.clear(); } + /** + * @copydoc Dali::Accessibility::Bridge::Terminate() + */ void Terminate() override { if(mData) @@ -226,11 +230,18 @@ public: mData->mHighlightActor = {}; } ForceDown(); - listenOnAtspiEnabledSignalClient = {}; - dbusServer = {}; - con = {}; + if((NULL != mIdleCallback) && Dali::Adaptor::IsAvailable()) + { + Dali::Adaptor::Get().RemoveIdle(mIdleCallback); + } + mAccessibilityStatusClient = {}; + mDbusServer = {}; + mConnectionPtr = {}; } + /** + * @copydoc Dali::Accessibility::Bridge::ForceUp() + */ ForceUpResult ForceUp() override { if(BridgeAccessible::ForceUp() == ForceUpResult::ALREADY_UP) @@ -249,21 +260,24 @@ public: BridgeSelection::RegisterInterfaces(); BridgeApplication::RegisterInterfaces(); - RegisterOnBridge(&application); + RegisterOnBridge(&mApplication); - registryClient = {AtspiDbusNameRegistry, AtspiDbusPathDec, AtspiDbusInterfaceDec, con}; - directReadingClient = DBus::DBusClient{DirectReadingDBusName, DirectReadingDBusPath, DirectReadingDBusInterface, con}; - directReadingClient.addSignal("ReadingStateChanged", [=](int32_t id, std::string readingState) { - auto it = directReadingCallbacks.find(id); - if(it != directReadingCallbacks.end()) + mRegistryClient = {AtspiDbusNameRegistry, AtspiDbusPathDec, AtspiDbusInterfaceDec, mConnectionPtr}; + mDirectReadingClient = DBus::DBusClient{DirectReadingDBusName, DirectReadingDBusPath, DirectReadingDBusInterface, mConnectionPtr}; + + mDirectReadingClient.addSignal("ReadingStateChanged", [=](int32_t id, std::string readingState) { + auto it = mDirectReadingCallbacks.find(id); + if(it != mDirectReadingCallbacks.end()) { it->second(readingState); if(readingState != "ReadingPaused" && readingState != "ReadingResumed" && readingState != "ReadingStarted") - directReadingCallbacks.erase(it); + { + mDirectReadingCallbacks.erase(it); + } } }); - auto proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, AtspiDbusInterfaceSocket, con}; + auto proxy = DBus::DBusClient{AtspiDbusNameRegistry, AtspiDbusPathRoot, AtspiDbusInterfaceSocket, mConnectionPtr}; Address root{"", "root"}; auto res = proxy.method("Embed").call(root); if(!res) @@ -271,87 +285,197 @@ public: LOG() << "Call to Embed failed: " << res.getError().message; } assert(res); - application.parent.SetAddress(std::move(std::get<0>(res))); - if(isShown) + + mApplication.mParent.SetAddress(std::move(std::get<0>(res))); + if(mIsShown) { EmitActivate(); } + + mEnabledSignal.Emit(); + return ForceUpResult::JUST_STARTED; } + /** + * @brief Sends a signal to dbus that the default window is activated. + * + * TODO : This is subject to change if/when we implement multi-window support. + * @see BridgeObject::Emit() + */ void EmitActivate() { - auto win = application.getActiveWindow(); + auto win = mApplication.GetActiveWindow(); if(win) { win->Emit(WindowEvent::ACTIVATE, 0); } } + /** + * @brief Sends a signal to dbus that the default window is deactivated. + * + * TODO : This is subject to change if/when we implement multi-window support. + * @see BridgeObject::Emit() + */ void EmitDeactivate() { - auto win = application.getActiveWindow(); + auto win = mApplication.GetActiveWindow(); if(win) { win->Emit(WindowEvent::DEACTIVATE, 0); } } + /** + * @copydoc Dali::Accessibility::Bridge::WindowHidden() + */ void WindowHidden() override { - if(isShown && IsUp()) + if(mIsShown && IsUp()) { EmitDeactivate(); } - isShown = false; + mIsShown = false; } + /** + * @copydoc Dali::Accessibility::Bridge::WindowShown() + */ void WindowShown() override { - if(!isShown && IsUp()) + if(!mIsShown && IsUp()) { EmitActivate(); } - isShown = true; + mIsShown = true; } - void Initialize() override + void ReadAndListenProperty() { - auto dbusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION}; - auto enabled = dbusClient.property("ScreenReaderEnabled").get(); + // read property + auto enabled = mAccessibilityStatusClient.property("ScreenReaderEnabled").get(); if(enabled) { - screenReaderEnabled = std::get<0>(enabled); + mIsScreenReaderEnabled = std::get<0>(enabled); } - enabled = dbusClient.property("IsEnabled").get(); + enabled = mAccessibilityStatusClient.property("IsEnabled").get(); if(enabled) { - isEnabled = std::get<0>(enabled); + mIsEnabled = std::get<0>(enabled); } - if(screenReaderEnabled || isEnabled) + if(mIsScreenReaderEnabled || mIsEnabled) { ForceUp(); } + + // listen property change + mAccessibilityStatusClient.addPropertyChangedEvent("ScreenReaderEnabled", [this](bool res) { + mIsScreenReaderEnabled = res; + if(mIsScreenReaderEnabled || mIsEnabled) + { + ForceUp(); + } + else + { + ForceDown(); + } + }); + + mAccessibilityStatusClient.addPropertyChangedEvent("IsEnabled", [this](bool res) { + mIsEnabled = res; + if(mIsScreenReaderEnabled || mIsEnabled) + { + ForceUp(); + } + else + { + ForceDown(); + } + }); + } + + bool InitializeAccessibilityStatusClient() + { + mAccessibilityStatusClient = DBus::DBusClient{A11yDbusName, A11yDbusPath, A11yDbusStatusInterface, DBus::ConnectionType::SESSION}; + + if (!mAccessibilityStatusClient) + { + DALI_LOG_ERROR("Accessibility Status DbusClient is not ready\n"); + return false; + } + + return true; + } + + bool OnIdleSignal() + { + if ( InitializeAccessibilityStatusClient() ) + { + ReadAndListenProperty(); + mIdleCallback = NULL; + return false; + } + + return true; } - bool GetScreenReaderEnabled() + /** + * @copydoc Dali::Accessibility::Bridge::Initialize() + */ + void Initialize() override { - return screenReaderEnabled; + if ( InitializeAccessibilityStatusClient() ) + { + ReadAndListenProperty(); + return; + } + + // Initialize failed. Try it again on Idle + if( Dali::Adaptor::IsAvailable() ) + { + Dali::Adaptor& adaptor = Dali::Adaptor::Get(); + if( NULL == mIdleCallback ) + { + mIdleCallback = MakeCallback( this, &BridgeImpl::OnIdleSignal ); + adaptor.AddIdle( mIdleCallback, true ); + } + } } - bool IsEnabled() + /** + * @copydoc Dali::Accessibility::Bridge::GetScreenReaderEnabled() + */ + bool GetScreenReaderEnabled() override { - return isEnabled; + return mIsScreenReaderEnabled; } -}; -static bool bridgeInitialized; + /** + * @copydoc Dali::Accessibility::Bridge::IsEnabled() + */ + bool IsEnabled() override + { + return mIsEnabled; + } +}; // BridgeImpl -static Bridge* CreateBridge() +namespace // unnamed namespace { - bridgeInitialized = true; + +bool INITIALIZED_BRIDGE = false; + +/** + * @brief Creates BridgeImpl instance. + * + * @return The BridgeImpl instance + * @note This method is to check environment variable first. If ATSPI is disable using env, it returns dummy bridge instance. + */ +Bridge* CreateBridge() +{ + INITIALIZED_BRIDGE = true; try { @@ -371,6 +495,10 @@ static Bridge* CreateBridge() } } +} // unnamed namespace + +// Dali::Accessibility::Bridge class implementation + Bridge* Bridge::GetCurrentBridge() { static Bridge* bridge; @@ -379,7 +507,7 @@ Bridge* Bridge::GetCurrentBridge() { return bridge; } - else if(autoInitState == AutoInitState::ENABLED) + else if(mAutoInitState == AutoInitState::ENABLED) { bridge = CreateBridge(); @@ -398,19 +526,19 @@ Bridge* Bridge::GetCurrentBridge() void Bridge::DisableAutoInit() { - if(bridgeInitialized) + if(INITIALIZED_BRIDGE) { DALI_LOG_ERROR("Bridge::DisableAutoInit() called after bridge auto-initialization"); } - autoInitState = AutoInitState::DISABLED; + mAutoInitState = AutoInitState::DISABLED; } void Bridge::EnableAutoInit() { - autoInitState = AutoInitState::ENABLED; + mAutoInitState = AutoInitState::ENABLED; - if(bridgeInitialized) + if(INITIALIZED_BRIDGE) { return; }