X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Faccessibility%2Fbridge%2Fbridge-base.cpp;h=9b920d8d3608d727163fc416d1df2bc9b6db46f6;hb=74834c6a17f4fa7e01610a33107e8591d1586836;hp=a3b9ec4a34c9e77ae5670e6471e6b373ed70f527;hpb=d9335fa0ba5472d558fa40ad20af58db76bfbd7a;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/accessibility/bridge/bridge-base.cpp b/dali/internal/accessibility/bridge/bridge-base.cpp index a3b9ec4..9b920d8 100644 --- a/dali/internal/accessibility/bridge/bridge-base.cpp +++ b/dali/internal/accessibility/bridge/bridge-base.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -19,6 +19,7 @@ #include // EXTERNAL INCLUDES +#include #include #include #include @@ -30,23 +31,24 @@ using namespace Dali::Accessibility; static Dali::Timer tickTimer; -BridgeBase::~BridgeBase() +BridgeBase::BridgeBase() { } -BridgeBase::BridgeBase() +BridgeBase::~BridgeBase() { + mApplication.mChildren.clear(); } -void BridgeBase::addFilteredEvent( FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function functor ) +void BridgeBase::AddFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function functor) { - if( delay < 0 ) + if(delay < 0) { delay = 0; } - auto it = filteredEvents.insert({ { kind, obj }, { static_cast(delay * 10), {} } }); - if (it.second) + auto it = mFilteredEvents.insert({{kind, obj}, {static_cast(delay * 10), {}}}); + if(it.second) { functor(); } @@ -55,243 +57,282 @@ void BridgeBase::addFilteredEvent( FilteredEvents kind, Dali::Accessibility::Acc it.first->second.second = std::move(functor); } - if (!tickTimer) + if(!tickTimer) { tickTimer = Dali::Timer::New(100); - tickTimer.TickSignal().Connect(this, &BridgeBase::tickFilteredEvents); + tickTimer.TickSignal().Connect(this, &BridgeBase::TickFilteredEvents); } } -bool BridgeBase::tickFilteredEvents() +bool BridgeBase::TickFilteredEvents() { - for(auto it = filteredEvents.begin(); it != filteredEvents.end(); ) + for(auto it = mFilteredEvents.begin(); it != mFilteredEvents.end();) { - if (it->second.first) + if(it->second.first) { --it->second.first; } else { - if (it->second.second) + if(it->second.second) { it->second.second(); it->second.second = {}; } else { - it = filteredEvents.erase(it); + it = mFilteredEvents.erase(it); continue; } } ++it; } - return !filteredEvents.empty(); + return !mFilteredEvents.empty(); +} + +void BridgeBase::UpdateRegisteredEvents() +{ + using ReturnType = std::vector>; + mRegistry.method()>("GetRegisteredEvents").asyncCall([this](DBus::ValueOrError msg) { + if(!msg) + { + LOG() << "Get registered events failed"; + return; + } + + IsBoundsChangedEventAllowed = false; + + ReturnType values = std::get(msg.getValues()); + for(long unsigned int i = 0; i < values.size(); i++) + { + if(!std::get<1>(values[i]).compare("Object:BoundsChanged")) + { + IsBoundsChangedEventAllowed = true; + } + } + }); } BridgeBase::ForceUpResult BridgeBase::ForceUp() { - if( Bridge::ForceUp() == ForceUpResult::ALREADY_UP ) + //TODO: checking mBusName is enough? or a new variable to check bridge state? + if(Bridge::ForceUp() == ForceUpResult::ALREADY_UP && !GetBusName().empty()) { return ForceUpResult::ALREADY_UP; } auto proxy = DBus::DBusClient{dbusLocators::atspi::BUS, dbusLocators::atspi::OBJ_PATH, dbusLocators::atspi::BUS_INTERFACE, DBus::ConnectionType::SESSION}; - auto addr = proxy.method< std::string() >( dbusLocators::atspi::GET_ADDRESS ).call(); + auto addr = proxy.method(dbusLocators::atspi::GET_ADDRESS).call(); - if( !addr ) + if(!addr) { - throw std::domain_error{std::string( "failed at call '" ) + dbusLocators::atspi::GET_ADDRESS + "': " + addr.getError().message}; + DALI_LOG_ERROR("failed at call '%s': %s\n", dbusLocators::atspi::GET_ADDRESS, addr.getError().message.c_str()); + return ForceUpResult::FAILED; } - con = DBusWrapper::Installed()->eldbus_address_connection_get_impl( std::get< 0 >( addr ) ); - data->busName = DBus::getConnectionName( con ); - dbusServer = { con }; + mConnectionPtr = DBusWrapper::Installed()->eldbus_address_connection_get_impl(std::get<0>(addr)); + mData->mBusName = DBus::getConnectionName(mConnectionPtr); + mDbusServer = {mConnectionPtr}; { - DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Cache"}; - AddFunctionToInterface( desc, "GetItems", &BridgeBase::GetItems ); - dbusServer.addInterface( "/org/a11y/atspi/cache", desc ); + DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::CACHE)}; + AddFunctionToInterface(desc, "GetItems", &BridgeBase::GetItems); + mDbusServer.addInterface(AtspiDbusPathCache, desc); } { - DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Application"}; - AddGetSetPropertyToInterface( desc, "Id", &BridgeBase::IdGet, &BridgeBase::IdSet ); - dbusServer.addInterface( AtspiPath, desc ); + DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::APPLICATION)}; + AddGetSetPropertyToInterface(desc, "Id", &BridgeBase::GetId, &BridgeBase::SetId); + mDbusServer.addInterface(AtspiPath, desc); } + mRegistry = {AtspiDbusNameRegistry, AtspiDbusPathRegistry, Accessible::GetInterfaceName(AtspiInterface::REGISTRY), mConnectionPtr}; + + UpdateRegisteredEvents(); + + mRegistry.addSignal("EventListenerRegistered", [this](void) { + UpdateRegisteredEvents(); + }); + + mRegistry.addSignal("EventListenerDeregistered", [this](void) { + UpdateRegisteredEvents(); + }); + return ForceUpResult::JUST_STARTED; } void BridgeBase::ForceDown() { Bridge::ForceDown(); - dbusServer = {}; - con = {}; + mRegistry = {}; + mDbusServer = {}; + mConnectionPtr = {}; } const std::string& BridgeBase::GetBusName() const { static std::string empty; - return data ? data->busName : empty; + return mData ? mData->mBusName : empty; } -Accessible* BridgeBase::FindByPath( const std::string& name ) const +Accessible* BridgeBase::FindByPath(const std::string& name) const { try { - return Find( name ); + return Find(name); } - catch( std::domain_error& ) + catch(std::domain_error&) { return nullptr; } } -void BridgeBase::AddPopup( Accessible* obj ) +void BridgeBase::AddTopLevelWindow(Accessible* windowAccessible) { - if( std::find( popups.begin(), popups.end(), obj ) != popups.end() ) + if(windowAccessible->GetInternalActor() == nullptr) { return; } - popups.push_back( obj ); - if (IsUp()) + + // Prevent adding the default window twice. + if(!mApplication.mChildren.empty() && + mApplication.mChildren[0]->GetInternalActor() == windowAccessible->GetInternalActor()) { - obj->Emit( WindowEvent::ACTIVATE, 0 ); + return; } + + // Adds Window to a list of Windows. + mApplication.mChildren.push_back(windowAccessible); + SetIsOnRootLevel(windowAccessible); + + RegisterDefaultLabel(windowAccessible); } -void BridgeBase::RemovePopup( Accessible* obj ) +void BridgeBase::RemoveTopLevelWindow(Accessible* windowAccessible) { - auto it = std::find( popups.begin(), popups.end(), obj ); - if( it == popups.end() ) - { - return; - } - popups.erase( it ); - if (IsUp()) + UnregisterDefaultLabel(windowAccessible); + + for(auto i = 0u; i < mApplication.mChildren.size(); ++i) { - obj->Emit( WindowEvent::DEACTIVATE, 0 ); - if( popups.empty() ) + if(mApplication.mChildren[i] == windowAccessible) { - application.children.back()->Emit( WindowEvent::ACTIVATE, 0 ); - } - else - { - popups.back()->Emit( WindowEvent::ACTIVATE, 0 ); + mApplication.mChildren.erase(mApplication.mChildren.begin() + i); + break; } } } -void BridgeBase::AddTopLevelWindow( Accessible* root ) +void BridgeBase::RegisterDefaultLabel(Accessible* object) { - application.children.push_back( root ); - SetIsOnRootLevel( root ); + if(std::find(mDefaultLabels.begin(), mDefaultLabels.end(), object) == mDefaultLabels.end()) + { + mDefaultLabels.push_back(object); + } } -void BridgeBase::RemoveTopLevelWindow( Accessible* root ) +void BridgeBase::UnregisterDefaultLabel(Accessible* object) { - for(auto i = 0u; i < application.children.size(); ++i) + auto it = std::find(mDefaultLabels.begin(), mDefaultLabels.end(), object); + if(it != mDefaultLabels.end()) { - if( application.children[i] == root ) - { - application.children.erase(application.children.begin() + i); - break; - } + mDefaultLabels.erase(it); } } -std::string BridgeBase::StripPrefix( const std::string& path ) +std::string BridgeBase::StripPrefix(const std::string& path) { - auto size = strlen( AtspiPath ); - return path.substr( size + 1 ); + auto size = strlen(AtspiPath); + return path.substr(size + 1); } -Accessible* BridgeBase::Find( const std::string& path ) const +Accessible* BridgeBase::Find(const std::string& path) const { - if( path == "root" ) + if(path == "root") { - return &application; + return &mApplication; } - void* p; - std::istringstream tmp{ path }; - if (! ( tmp >> p) ) + + void* accessible; + std::istringstream tmp{path}; + if(!(tmp >> accessible)) { throw std::domain_error{"invalid path '" + path + "'"}; } - auto it = data->knownObjects.find( static_cast( p ) ); - if( it == data->knownObjects.end() || (*it)->GetStates()[State::DEFUNCT] ) + + auto it = mData->mKnownObjects.find(static_cast(accessible)); + if(it == mData->mKnownObjects.end() || (*it)->IsHidden()) { throw std::domain_error{"unknown object '" + path + "'"}; } - return static_cast( p ); + + return static_cast(accessible); } -Accessible* BridgeBase::Find( const Address& ptr ) const +Accessible* BridgeBase::Find(const Address& ptr) const { - assert( ptr.GetBus() == data->busName ); - return Find( ptr.GetPath() ); + assert(ptr.GetBus() == mData->mBusName); + return Find(ptr.GetPath()); } -Accessible* BridgeBase::FindSelf() const +Accessible* BridgeBase::FindCurrentObject() const { - auto pth = DBus::DBusServer::getCurrentObjectPath(); - auto size = strlen( AtspiPath ); - if( pth.size() <= size ) + auto path = DBus::DBusServer::getCurrentObjectPath(); + auto size = strlen(AtspiPath); + if(path.size() <= size) { - throw std::domain_error{"invalid path '" + pth + "'"}; + throw std::domain_error{"invalid path '" + path + "'"}; } - if( pth.substr( 0, size ) != AtspiPath ) + if(path.substr(0, size) != AtspiPath) { - throw std::domain_error{"invalid path '" + pth + "'"}; + throw std::domain_error{"invalid path '" + path + "'"}; } - if( pth[size] != '/' ) + if(path[size] != '/') { - throw std::domain_error{"invalid path '" + pth + "'"}; + throw std::domain_error{"invalid path '" + path + "'"}; } - return Find( StripPrefix( pth ) ); + return Find(StripPrefix(path)); } -void BridgeBase::IdSet( int id ) +void BridgeBase::SetId(int id) { - this->id = id; + this->mId = id; } -int BridgeBase::IdGet() +int BridgeBase::GetId() { - return this->id; + return this->mId; } -auto BridgeBase::GetItems() -> DBus::ValueOrError< std::vector< CacheElementType > > +auto BridgeBase::GetItems() -> DBus::ValueOrError> { - auto root = &application; + auto root = &mApplication; - std::vector< CacheElementType > res; + std::vector res; - std::function< void(Accessible*) > proc = - [&]( Accessible* item ) - { - res.emplace_back( std::move( CreateCacheElement( root ) ) ); - for( auto i = 0u; i < item->GetChildCount(); ++i ) + std::function proc = + [&](Accessible* item) { + res.emplace_back(std::move(CreateCacheElement(root))); + for(auto i = 0u; i < item->GetChildCount(); ++i) { - proc( item->GetChildAtIndex( i ) ); + proc(item->GetChildAtIndex(i)); } }; return res; } -auto BridgeBase::CreateCacheElement( Accessible* item ) -> CacheElementType +auto BridgeBase::CreateCacheElement(Accessible* item) -> CacheElementType { - if( !item ) + if(!item) { return {}; } - auto root = &application; + auto root = &mApplication; auto parent = item->GetParent(); - std::vector< Address > children; - for( auto i = 0u; i < item->GetChildCount(); ++i ) + std::vector
children; + for(auto i = 0u; i < item->GetChildCount(); ++i) { - children.emplace_back( item->GetChildAtIndex( i )->GetAddress() ); + children.emplace_back(item->GetChildAtIndex(i)->GetAddress()); } return std::make_tuple( @@ -299,11 +340,9 @@ auto BridgeBase::CreateCacheElement( Accessible* item ) -> CacheElementType root->GetAddress(), parent ? parent->GetAddress() : Address{}, children, - item->GetInterfaces(), + item->GetInterfacesAsStrings(), item->GetName(), item->GetRole(), item->GetDescription(), - item->GetStates().GetRawData() - ); + item->GetStates().GetRawData()); } -