Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-adaptor.git] / adaptors / ubuntu / accessibility-manager-impl-ubuntu.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "accessibility-manager-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/events/touch-event-integ.h>
25 #include <dali/integration-api/events/hover-event-integ.h>
26 #include <dali/integration-api/events/gesture-requests.h>
27
28 // INTERNAL INCLUDES
29 #include <singleton-service-impl.h>
30 #include "system-settings.h"
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace Adaptor
39 {
40
41 namespace
42 {
43 #if defined(DEBUG_ENABLED)
44 Debug::Filter* gAccessibilityManagerLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ACCESSIBILITY_MANAGER");
45 #endif
46
47 BaseHandle Create()
48 {
49   BaseHandle handle( AccessibilityManager::Get() );
50
51   if ( !handle )
52   {
53     Dali::SingletonService service( SingletonService::Get() );
54     if ( service )
55     {
56       Dali::AccessibilityManager manager = Dali::AccessibilityManager( new AccessibilityManager() );
57       service.Register( typeid( manager ), manager );
58       handle = manager;
59     }
60   }
61
62   return handle;
63 }
64 TypeRegistration ACCESSIBILITY_MANAGER_TYPE( typeid(Dali::AccessibilityManager), typeid(Dali::BaseHandle), Create, true /* Create Instance At Startup */ );
65
66 } // unnamed namespace
67
68 Dali::AccessibilityManager AccessibilityManager::Get()
69 {
70   Dali::AccessibilityManager manager;
71
72   Dali::SingletonService service( SingletonService::Get() );
73   if ( service )
74   {
75     // Check whether the singleton is already created
76     Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::AccessibilityManager ) );
77     if(handle)
78     {
79       // If so, downcast the handle
80       manager = Dali::AccessibilityManager( dynamic_cast< AccessibilityManager* >( handle.GetObjectPtr() ) );
81     }
82   }
83
84   return manager;
85 }
86
87 Vector2 AccessibilityManager::GetReadPosition() const
88 {
89   return mReadPosition;
90 }
91
92 void AccessibilityManager::SetActionHandler(AccessibilityActionHandler& handler)
93 {
94   mActionHandler = &handler;
95 }
96
97 void AccessibilityManager::SetGestureHandler(AccessibilityGestureHandler& handler)
98 {
99   if( mAccessibilityGestureDetector )
100   {
101     mAccessibilityGestureDetector->SetGestureHandler(handler);
102   }
103 }
104
105 bool AccessibilityManager::HandleActionClearFocusEvent()
106 {
107   bool ret = false;
108
109   Dali::AccessibilityManager handle( this );
110
111   /*
112    * In order to application decide reading action first,
113    * emit ActionClearFocus signal in first, ClearAccessibilityFocus for handler in next
114    */
115   if ( !mIndicatorFocused )
116   {
117     if( !mActionClearFocusSignal.Empty() )
118     {
119       mActionClearFocusSignal.Emit( handle );
120     }
121   }
122
123   if( mActionHandler )
124   {
125     ret = mActionHandler->ClearAccessibilityFocus();
126   }
127
128   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
129
130   return ret;
131 }
132
133 bool AccessibilityManager::HandleActionScrollEvent(const TouchPoint& point, unsigned long timeStamp)
134 {
135   bool ret = false;
136
137   Dali::AccessibilityManager handle( this );
138
139   Dali::TouchEvent event(timeStamp);
140   event.points.push_back(point);
141
142   /*
143    * In order to application decide touch action first,
144    * emit ActionScroll signal in first, AccessibilityActionScroll  for handler in next
145    */
146   if ( !mIndicatorFocused )
147   {
148     if( !mActionScrollSignal.Empty() )
149     {
150       mActionScrollSignal.Emit( handle, event );
151     }
152   }
153
154   Integration::TouchEvent touchEvent;
155   Integration::HoverEvent hoverEvent;
156   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
157   if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth) // hover event is ignored
158   {
159     // Process the touch event in accessibility gesture detector
160     if( mAccessibilityGestureDetector )
161     {
162       mAccessibilityGestureDetector->SendEvent(touchEvent);
163       ret = true;
164     }
165   }
166
167   return ret;
168 }
169
170 bool AccessibilityManager::HandleActionTouchEvent(const TouchPoint& point, unsigned long timeStamp)
171 {
172   bool ret = false;
173
174   Dali::TouchEvent touchEvent(timeStamp);
175   touchEvent.points.push_back(point);
176
177   if( mActionHandler )
178   {
179     ret = mActionHandler->AccessibilityActionTouch(touchEvent);
180   }
181   return ret;
182 }
183
184 bool AccessibilityManager::HandleActionBackEvent()
185 {
186   bool ret = false;
187
188   Dali::AccessibilityManager handle( this );
189
190   /*
191    * In order to application decide reading action first,
192    * emit ActionBack signal in first, AccessibilityActionBack for handler in next
193    */
194   if ( !mIndicatorFocused )
195   {
196     if( !mActionBackSignal.Empty() )
197     {
198       mActionBackSignal.Emit( handle );
199     }
200   }
201
202   if( mActionHandler )
203   {
204     ret = mActionHandler->AccessibilityActionBack();
205   }
206
207   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
208
209   return ret;
210 }
211
212 void AccessibilityManager::HandleActionEnableEvent()
213 {
214   EnableAccessibility();
215 }
216
217 void AccessibilityManager::HandleActionDisableEvent()
218 {
219   DisableAccessibility();
220 }
221
222 void AccessibilityManager::EnableAccessibility()
223 {
224   if(mIsEnabled == false)
225   {
226     mIsEnabled = true;
227
228     if( mActionHandler )
229     {
230       mActionHandler->ChangeAccessibilityStatus();
231     }
232
233     //emit status changed signal
234     Dali::AccessibilityManager handle( this );
235     mStatusChangedSignal.Emit( handle );
236   }
237 }
238
239 void AccessibilityManager::DisableAccessibility()
240 {
241   if(mIsEnabled == true)
242   {
243     mIsEnabled = false;
244
245     if( mActionHandler )
246     {
247       mActionHandler->ChangeAccessibilityStatus();
248     }
249
250     //emit status changed signal
251     Dali::AccessibilityManager handle( this );
252     mStatusChangedSignal.Emit( handle );
253
254     // Destroy the TtsPlayer if exists.
255     if ( Adaptor::IsAvailable() )
256     {
257       Dali::Adaptor& adaptor = Dali::Adaptor::Get();
258       Adaptor::GetImplementation( adaptor ).DestroyTtsPlayer( Dali::TtsPlayer::SCREEN_READER );
259     }
260   }
261 }
262
263 bool AccessibilityManager::IsEnabled() const
264 {
265   return mIsEnabled;
266 }
267
268 void AccessibilityManager::SetIndicator(Indicator* indicator)
269 {
270   mIndicator = indicator;
271 }
272
273 AccessibilityManager::AccessibilityManager()
274 : mIsEnabled(false),
275   mActionHandler(NULL),
276   mIndicator(NULL),
277   mIndicatorFocused(false)
278 {
279   int isEnabled = 0;
280   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled?"ENABLED":"DISABLED");
281
282   if(isEnabled == 1)
283   {
284     mIsEnabled = true;
285   }
286   else
287   {
288     mIsEnabled = false;
289   }
290
291   mAccessibilityGestureDetector = new AccessibilityGestureDetector();
292 }
293
294 AccessibilityManager::~AccessibilityManager()
295 {
296 }
297
298 bool AccessibilityManager::HandleActionNextEvent(bool allowEndFeedback)
299 {
300   bool ret = false;
301   Dali::AccessibilityManager handle( this );
302
303   /*
304    * In order to application decide reading action first,
305    * emit ActionNext signal in first, AccessibilityActionNext for handler in next
306    */
307   if( !mIndicatorFocused )
308   {
309     if( !mActionNextSignal.Empty() )
310     {
311       mActionNextSignal.Emit( handle );
312     }
313   }
314
315   if( mActionHandler )
316   {
317     ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
318   }
319
320   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
321
322   return ret;
323 }
324
325 bool AccessibilityManager::HandleActionPreviousEvent(bool allowEndFeedback)
326 {
327   bool ret = false;
328
329   Dali::AccessibilityManager handle( this );
330
331    /*
332    * In order to application decide reading action first,
333    * emit ActionPrevious signal in first, AccessibilityActionPrevious for handler in next
334    */
335  if ( !mIndicatorFocused )
336   {
337     if( !mActionPreviousSignal.Empty() )
338     {
339       mActionPreviousSignal.Emit( handle );
340     }
341   }
342
343   if( mActionHandler )
344   {
345     ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
346   }
347
348   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
349
350   return ret;
351 }
352
353 bool AccessibilityManager::HandleActionActivateEvent()
354 {
355   bool ret = false;
356
357   Dali::AccessibilityManager handle( this );
358
359   /*
360    * In order to application decide reading action first,
361    * emit ActionActivate signal in first, AccessibilityActionActivate for handler in next
362    */
363   if ( !mIndicatorFocused )
364   {
365     if( !mActionActivateSignal.Empty() )
366     {
367       mActionActivateSignal.Emit( handle );
368     }
369   }
370
371   if( mActionHandler )
372   {
373     ret = mActionHandler->AccessibilityActionActivate();
374   }
375
376   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
377
378   return ret;
379 }
380
381 bool AccessibilityManager::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
382 {
383   bool ret = false;
384
385   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
386
387   mReadPosition.x = x;
388   mReadPosition.y = y;
389
390   Dali::AccessibilityManager handle( this );
391
392   bool indicatorFocused = false;
393
394   // Check whether the Indicator is focused
395   if( mIndicator && mIndicator->IsConnected() )
396   {
397     // Check the position and size of Indicator actor
398     Dali::Actor indicatorActor = mIndicator->GetActor();
399     Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
400     Vector3 size = indicatorActor.GetCurrentSize();
401
402     if(mReadPosition.x >= position.x &&
403        mReadPosition.x <= position.x + size.width &&
404        mReadPosition.y >= position.y &&
405        mReadPosition.y <= position.y + size.height)
406     {
407       indicatorFocused = true;
408       DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] Indicator area!!!!\n", __FUNCTION__, __LINE__);
409     }
410   }
411
412   if( mIndicator )
413   {
414     if( !mIndicatorFocused && indicatorFocused )
415     {
416       // If Indicator is focused, the focus should be cleared in Dali focus chain.
417       if( mActionHandler )
418       {
419         mActionHandler->ClearAccessibilityFocus();
420       }
421     }
422
423     mIndicatorFocused = indicatorFocused;
424
425     // Send accessibility READ action information to Indicator
426     if( mIndicatorFocused )
427     {
428       DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] Send READ message to indicator!!!!\n", __FUNCTION__, __LINE__);
429     }
430   }
431
432   if(allowReadAgain)
433   {
434     /*
435      * In order to application decide reading action first,
436      * emit ActionRead signal in first, AccessibilityActionRead for handler in next
437      */
438     if( !mIndicatorFocused )
439     {
440       if ( !mActionReadSignal.Empty() )
441       {
442         mActionReadSignal.Emit( handle );
443       }
444     }
445   }
446   else
447   {
448     /*
449      * In order to application decide reading action first,
450      * emit ActionRead signal in first, AccessibilityActionRead for handler in next
451      */
452     if( !mIndicatorFocused )
453     {
454       if ( !mActionOverSignal.Empty() )
455       {
456         mActionOverSignal.Emit( handle );
457       }
458     }
459   }
460
461   if( mActionHandler && !mIndicatorFocused)
462   {
463     // If Indicator is not focused, the accessibility actions should be handled by the registered
464     // accessibility action handler (e.g. focus manager)
465     ret = mActionHandler->AccessibilityActionRead(allowReadAgain);
466     DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
467   }
468
469   return ret;
470 }
471
472 bool AccessibilityManager::HandleActionReadNextEvent(bool allowEndFeedback)
473 {
474   bool ret = false;
475
476   Dali::AccessibilityManager handle( this );
477
478   /*
479    * In order to application decide reading action first,
480    * emit ActionReadNext signal in first, AccessibilityActionReadNext for handler in next
481    */
482   if ( !mIndicatorFocused )
483   {
484     if( !mActionReadNextSignal.Empty() )
485     {
486       mActionReadNextSignal.Emit( handle );
487     }
488   }
489
490   if( mActionHandler )
491   {
492     ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
493   }
494
495   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
496
497   return ret;
498 }
499
500 bool AccessibilityManager::HandleActionReadPreviousEvent(bool allowEndFeedback)
501 {
502   bool ret = false;
503
504   Dali::AccessibilityManager handle( this );
505
506   /*
507    * In order to application decide reading action first,
508    * emit ActionReadPrevious signal in first, AccessibilityActionReadPrevious for handler in next
509    */
510   if ( !mIndicatorFocused )
511   {
512     if( !mActionReadPreviousSignal.Empty() )
513     {
514       mActionReadPreviousSignal.Emit( handle );
515     }
516   }
517
518   if( mActionHandler )
519   {
520     ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
521   }
522
523   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
524
525   return ret;
526 }
527
528 bool AccessibilityManager::HandleActionUpEvent()
529 {
530   bool ret = false;
531
532   Dali::AccessibilityManager handle( this );
533
534   /*
535    * In order to application decide reading action first,
536    * emit ActionUp signal in first, AccessibilityActionUp for handler in next
537    */
538   if ( !mIndicatorFocused )
539   {
540     if( !mActionUpSignal.Empty() )
541     {
542       mActionUpSignal.Emit( handle );
543     }
544   }
545
546   if( mActionHandler )
547   {
548     ret = mActionHandler->AccessibilityActionUp();
549   }
550
551   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
552
553   return ret;
554 }
555
556 bool AccessibilityManager::HandleActionDownEvent()
557 {
558   bool ret = false;
559
560   Dali::AccessibilityManager handle( this );
561
562   /*
563    * In order to application decide reading action first,
564    * emit ActionDown signal in first, AccessibilityActionDown for handler in next
565    */
566   if ( !mIndicatorFocused )
567   {
568     if( !mActionDownSignal.Empty() )
569     {
570       mActionDownSignal.Emit( handle );
571     }
572   }
573
574   if( mActionHandler )
575   {
576     ret = mActionHandler->AccessibilityActionDown();
577   }
578
579   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
580
581   return ret;
582 }
583
584 } // namespace Adaptor
585
586 } // namespace Internal
587
588 } // namespace Dali