2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/accessibility/bridge/bridge-base.h>
27 #include <dali/public-api/adaptor-framework/timer.h>
29 using namespace Dali::Accessibility;
31 static Dali::Timer tickTimer;
33 BridgeBase::~BridgeBase()
37 BridgeBase::BridgeBase()
41 void BridgeBase::addFilteredEvent(FilteredEvents kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor)
45 auto it = filteredEvents.insert({ { kind, obj }, { static_cast<unsigned int>(delay * 10), {} } });
49 it.first->second.second = std::move(functor);
51 tickTimer = Dali::Timer::New(100);
52 tickTimer.TickSignal().Connect(this, &BridgeBase::tickFilteredEvents);
56 bool BridgeBase::tickFilteredEvents()
58 for(auto it = filteredEvents.begin(); it != filteredEvents.end(); ) {
59 if (it->second.first) {
63 if (it->second.second) {
65 it->second.second = {};
68 it = filteredEvents.erase(it);
74 return !filteredEvents.empty();
77 BridgeBase::ForceUpResult BridgeBase::ForceUp()
79 if( Bridge::ForceUp() == ForceUpResult::ALREADY_UP )
80 return ForceUpResult::ALREADY_UP;
81 auto proxy = DBus::DBusClient{dbusLocators::atspi::BUS, dbusLocators::atspi::OBJ_PATH,
82 dbusLocators::atspi::BUS_INTERFACE, DBus::ConnectionType::SESSION};
83 auto addr = proxy.method< std::string() >( dbusLocators::atspi::GET_ADDRESS ).call();
86 throw std::domain_error{std::string( "failed at call '" ) + dbusLocators::atspi::GET_ADDRESS +
87 "': " + addr.getError().message};
89 con = DBusWrapper::Installed()->eldbus_address_connection_get_impl( std::get< 0 >( addr ) );
90 data->busName = DBus::getConnectionName( con );
94 DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Cache"};
95 AddFunctionToInterface( desc, "GetItems", &BridgeBase::GetItems );
96 dbusServer.addInterface( "/org/a11y/atspi/cache", desc );
99 DBus::DBusInterfaceDescription desc{"org.a11y.atspi.Application"};
100 AddGetSetPropertyToInterface( desc, "Id", &BridgeBase::IdGet, &BridgeBase::IdSet );
101 dbusServer.addInterface( AtspiPath, desc );
103 return ForceUpResult::JUST_STARTED;
106 void BridgeBase::ForceDown()
113 const std::string& BridgeBase::GetBusName() const
115 static std::string empty;
116 return data ? data->busName : empty;
119 Accessible* BridgeBase::FindByPath( const std::string& name ) const
125 catch( std::domain_error )
131 void BridgeBase::AddPopup( Accessible* obj )
133 if( std::find( popups.begin(), popups.end(), obj ) != popups.end() ) return;
134 popups.push_back( obj );
137 obj->Emit( WindowEvent::ACTIVATE, 0 );
141 void BridgeBase::RemovePopup( Accessible* obj )
143 auto it = std::find( popups.begin(), popups.end(), obj );
144 if( it == popups.end() ) return;
148 obj->Emit( WindowEvent::DEACTIVATE, 0 );
151 application.children.back()->Emit( WindowEvent::ACTIVATE, 0 );
155 popups.back()->Emit( WindowEvent::ACTIVATE, 0 );
161 void BridgeBase::AddTopLevelWindow( Accessible* root )
163 application.children.push_back( root );
164 SetIsOnRootLevel( root );
167 void BridgeBase::RemoveTopLevelWindow( Accessible* root )
169 for(auto i = 0u; i < application.children.size(); ++i) {
170 if( application.children[i] == root )
172 application.children.erase(application.children.begin() + i);
178 // Accessible *BridgeBase::getApplicationRoot() const
180 // return rootElement;
183 std::string BridgeBase::StripPrefix( const std::string& path )
185 auto size = strlen( AtspiPath );
186 return path.substr( size + 1 );
189 Accessible* BridgeBase::Find( const std::string& path ) const
194 std::istringstream tmp{ path };
196 throw std::domain_error{"invalid path '" + path + "'"};
197 auto it = data->knownObjects.find( static_cast<Accessible*>( p ) );
198 if( it == data->knownObjects.end() )
199 throw std::domain_error{"unknown object '" + path + "'"};
200 return static_cast<Accessible*>( p );
203 Accessible* BridgeBase::Find( const Address& ptr ) const
205 assert( ptr.GetBus() == data->busName );
206 return Find( ptr.GetPath() );
209 Accessible* BridgeBase::FindSelf() const
211 auto pth = DBus::DBusServer::getCurrentObjectPath();
212 auto size = strlen( AtspiPath );
213 if( pth.size() <= size )
214 throw std::domain_error{"invalid path '" + pth + "'"};
215 if( pth.substr( 0, size ) != AtspiPath )
216 throw std::domain_error{"invalid path '" + pth + "'"};
217 if( pth[size] != '/' )
218 throw std::domain_error{"invalid path '" + pth + "'"};
219 return Find( StripPrefix( pth ) );
222 void BridgeBase::IdSet( int id )
226 int BridgeBase::IdGet()
231 auto BridgeBase::GetItems() -> DBus::ValueOrError< std::vector< CacheElementType > >
233 auto root = &application;
235 std::vector< CacheElementType > res;
237 std::function< void(Accessible*) > proc = [&]( Accessible* item ) {
238 res.emplace_back( std::move( CreateCacheElement( root ) ) );
240 for( auto i = 0u; i < item->GetChildCount(); ++i )
242 proc( item->GetChildAtIndex( i ) );
249 auto BridgeBase::CreateCacheElement( Accessible* item ) -> CacheElementType
254 auto root = &application;
255 auto parent = item->GetParent();
257 std::vector< Address > children;
258 for( auto i = 0u; i < item->GetChildCount(); ++i )
260 children.emplace_back( item->GetChildAtIndex( i )->GetAddress() );
263 return std::make_tuple(
266 parent ? parent->GetAddress() : Address{},
268 item->GetInterfaces(),
271 item->GetDescription(),
272 item->GetStates().GetRawData() );