6ad9a1b2bf27d979515a40b42f97c634e66a2a90
[platform/core/uifw/dali-adaptor.git] / dali / dali-bridge / src / BridgeImpl.cpp
1 #include "BridgeImpl.hpp"
2 #include "BridgeAccessible.hpp"
3 #include "BridgeAction.hpp"
4 #include "BridgeCollection.hpp"
5 #include "BridgeComponent.hpp"
6 #include "BridgeObject.hpp"
7 #include "BridgeValue.hpp"
8 #include "DBus.hpp"
9 #include <iostream>
10
11 #include <dali/integration-api/debug.h>
12
13 using namespace Dali::Accessibility;
14
15 class BridgeImpl : public virtual BridgeBase, public BridgeAccessible, public BridgeObject, public BridgeComponent, public BridgeCollection, public BridgeAction, public BridgeValue
16 {
17   DBus::DBusClient listenOnAtspiEnabledSignalClient;
18   DBus::DBusClient registryClient;
19   Accessible* currentWindow = nullptr;
20   bool screenReaderEnabled = false, isEnabled = false;
21
22 public:
23   BridgeImpl()
24   {
25     DBus::setDebugPrinter( []( const char* buf, size_t len ) {
26       std::string s{buf, len};
27       Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s", s.c_str() );
28     } );
29   }
30
31   Consumed Emit( KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText ) override
32   {
33     unsigned int evType = 0;
34
35     switch( type )
36     {
37       case KeyEventType::KeyPressed:
38         evType = 0;
39         {
40           break;
41         }
42       case KeyEventType::KeyReleased:
43         evType = 1;
44         {
45           break;
46         }
47       default:
48       {
49         return Consumed::No;
50       }
51     }
52     auto m = registryClient.method< bool( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool > ) >( "NotifyListenersSync" );
53     auto result = m.call( std::tuple< uint32_t, int32_t, int32_t, int32_t, int32_t, std::string, bool >{evType, 0, static_cast< int32_t >( keyCode ), 0, static_cast< int32_t >( timeStamp ), keyName, isText ? 1 : 0} );
54     if( !result )
55     {
56       LOG() << result.getError().message;
57       return Consumed::No;
58     }
59     return std::get< 0 >( result ) ? Consumed::Yes : Consumed::No;
60   }
61
62   void ForceDown() override
63   {
64     ApplicationHidden();
65     BridgeAccessible::ForceDown();
66     registryClient = {};
67   }
68
69   ForceUpResult ForceUp() override
70   {
71     if( BridgeAccessible::ForceUp() == ForceUpResult::alreadyUp )
72       return ForceUpResult::alreadyUp;
73
74     BridgeObject::RegisterInterfaces();
75     BridgeAccessible::RegisterInterfaces();
76     BridgeComponent::RegisterInterfaces();
77     BridgeCollection::RegisterInterfaces();
78     BridgeAction::RegisterInterfaces();
79     BridgeValue::RegisterInterfaces();
80
81     RegisterOnBridge( &application );
82
83     registryClient = {ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_DEC, ATSPI_DBUS_INTERFACE_DEC, con};
84     auto proxy = DBus::DBusClient{ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_ROOT, ATSPI_DBUS_INTERFACE_SOCKET, con};
85     Address root{
86         data->busName, "root"};
87     auto res = proxy.method< Address( Address ) >( "Embed" ).call( root );
88     assert( res );
89     application.parent.SetAddress( std::move( std::get< 0 >( res ) ) );
90     ApplicationShown();
91     return ForceUpResult::justStarted;
92   }
93
94   void ApplicationHidden() override
95   {
96     if( currentWindow )
97     {
98       currentWindow->Emit( WindowEvent::Deactivate, 0 );
99       currentWindow = nullptr;
100     }
101   }
102   void ApplicationShown() override
103   {
104     auto win = application.getActiveWindow();
105     if( win && win != currentWindow )
106     {
107       currentWindow = win;
108       win->Emit( WindowEvent::Activate, 0 );
109     }
110   }
111   void Initialize() override
112   {
113     auto req = DBus::DBusClient{A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_STATUS_INTERFACE, DBus::ConnectionType::SESSION};
114     auto p = req.property< bool >( "ScreenReaderEnabled" ).get();
115     if( p )
116       screenReaderEnabled = std::get< 0 >( p );
117     p = req.property< bool >( "IsEnabled" ).get();
118     if( p )
119       isEnabled = std::get< 0 >( p );
120     if( screenReaderEnabled || isEnabled )
121       ForceUp();
122   }
123   static std::shared_ptr< Bridge > Create()
124   {
125     auto ptr = std::make_shared< BridgeImpl >();
126     ptr->MakePublic( Bridge::Visibility::allThreads );
127     ptr->listenOnAtspiEnabledSignalClient = DBus::DBusClient{A11Y_DBUS_NAME, A11Y_DBUS_PATH, A11Y_DBUS_STATUS_INTERFACE,
128                                                              DBus::ConnectionType::SESSION};
129     {
130       auto p = ptr.get();
131       ptr->listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "ScreenReaderEnabled", [p]( bool res ) {
132         p->screenReaderEnabled = res;
133         if( p->screenReaderEnabled || p->isEnabled )
134           p->ForceUp();
135         else
136           p->ForceDown();
137       } );
138       ptr->listenOnAtspiEnabledSignalClient.addPropertyChangedEvent< bool >( "IsEnabled", [p]( bool res ) {
139         p->isEnabled = res;
140         if( p->screenReaderEnabled || p->isEnabled )
141           p->ForceUp();
142         else
143           p->ForceDown();
144       } );
145     }
146     return ptr;
147   }
148 };
149
150 std::shared_ptr< Bridge > Dali::Accessibility::CreateBridge()
151 {
152   try
153   {
154     return BridgeImpl::Create();
155   }
156   catch( AccessibleError& e )
157   {
158     return {};
159   }
160 }