Merge "Redesigning render sync to handle reduced frequency" into tizen
[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
23 #include <dali/public-api/dali-core.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/integration-api/events/touch-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( !mActionClearFocusSignalV2.Empty() )
118     {
119       mActionClearFocusSignalV2.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 touchEvent(timeStamp);
140   touchEvent.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( !mActionScrollSignalV2.Empty() )
149     {
150       mActionScrollSignalV2.Emit( handle, touchEvent );
151     }
152   }
153
154   Integration::TouchEvent event;
155   if (mCombiner.GetNextTouchEvent(point, timeStamp, event))
156   {
157     // Process the touch event in accessibility gesture detector
158     if( mAccessibilityGestureDetector )
159     {
160       mAccessibilityGestureDetector->SendEvent(event);
161       ret = true;
162     }
163   }
164
165   return ret;
166 }
167
168 bool AccessibilityManager::HandleActionTouchEvent(const TouchPoint& point, unsigned long timeStamp)
169 {
170   bool ret = false;
171
172   Dali::TouchEvent touchEvent(timeStamp);
173   touchEvent.points.push_back(point);
174
175   if( mActionHandler )
176   {
177     ret = mActionHandler->AccessibilityActionTouch(touchEvent);
178   }
179   return ret;
180 }
181
182 bool AccessibilityManager::HandleActionBackEvent()
183 {
184   bool ret = false;
185
186   Dali::AccessibilityManager handle( this );
187
188   /*
189    * In order to application decide reading action first,
190    * emit ActionBack signal in first, AccessibilityActionBack for handler in next
191    */
192   if ( !mIndicatorFocused )
193   {
194     if( !mActionBackSignalV2.Empty() )
195     {
196       mActionBackSignalV2.Emit( handle );
197     }
198   }
199
200   if( mActionHandler )
201   {
202     ret = mActionHandler->AccessibilityActionBack();
203   }
204
205   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
206
207   return ret;
208 }
209
210 void AccessibilityManager::HandleActionEnableEvent()
211 {
212   EnableAccessibility();
213 }
214
215 void AccessibilityManager::HandleActionDisableEvent()
216 {
217   DisableAccessibility();
218 }
219
220 void AccessibilityManager::EnableAccessibility()
221 {
222   if(mIsEnabled == false)
223   {
224     mIsEnabled = true;
225
226     if( mActionHandler )
227     {
228       mActionHandler->ChangeAccessibilityStatus();
229     }
230
231     //emit status changed signal
232     Dali::AccessibilityManager handle( this );
233     mStatusChangedSignalV2.Emit( handle );
234   }
235 }
236
237 void AccessibilityManager::DisableAccessibility()
238 {
239   if(mIsEnabled == true)
240   {
241     mIsEnabled = false;
242
243     if( mActionHandler )
244     {
245       mActionHandler->ChangeAccessibilityStatus();
246     }
247
248     //emit status changed signal
249     Dali::AccessibilityManager handle( this );
250     mStatusChangedSignalV2.Emit( handle );
251
252     // Destroy the TtsPlayer if exists.
253     if ( Adaptor::IsAvailable() )
254     {
255       Dali::Adaptor& adaptor = Dali::Adaptor::Get();
256       Adaptor::GetImplementation( adaptor ).DestroyTtsPlayer( Dali::TtsPlayer::SCREEN_READER );
257     }
258   }
259 }
260
261 bool AccessibilityManager::IsEnabled() const
262 {
263   return mIsEnabled;
264 }
265
266 void AccessibilityManager::SetIndicator(Indicator* indicator)
267 {
268   mIndicator = indicator;
269 }
270
271 AccessibilityManager::AccessibilityManager()
272 : mIsEnabled(false),
273   mActionHandler(NULL),
274   mIndicator(NULL),
275   mIndicatorFocused(false)
276 {
277   int isEnabled = 0;
278   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, isEnabled?"ENABLED":"DISABLED");
279
280   if(isEnabled == 1)
281   {
282     mIsEnabled = true;
283   }
284   else
285   {
286     mIsEnabled = false;
287   }
288
289   mAccessibilityGestureDetector = new AccessibilityGestureDetector();
290 }
291
292 AccessibilityManager::~AccessibilityManager()
293 {
294 }
295
296 bool AccessibilityManager::HandleActionNextEvent(bool allowEndFeedback)
297 {
298   bool ret = false;
299   Dali::AccessibilityManager handle( this );
300
301   /*
302    * In order to application decide reading action first,
303    * emit ActionNext signal in first, AccessibilityActionNext for handler in next
304    */
305   if( !mIndicatorFocused )
306   {
307     if( !mActionNextSignalV2.Empty() )
308     {
309       mActionNextSignalV2.Emit( handle );
310     }
311   }
312
313   if( mActionHandler )
314   {
315     ret = mActionHandler->AccessibilityActionNext(allowEndFeedback);
316   }
317
318   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
319
320   return ret;
321 }
322
323 bool AccessibilityManager::HandleActionPreviousEvent(bool allowEndFeedback)
324 {
325   bool ret = false;
326
327   Dali::AccessibilityManager handle( this );
328
329    /*
330    * In order to application decide reading action first,
331    * emit ActionPrevious signal in first, AccessibilityActionPrevious for handler in next
332    */
333  if ( !mIndicatorFocused )
334   {
335     if( !mActionPreviousSignalV2.Empty() )
336     {
337       mActionPreviousSignalV2.Emit( handle );
338     }
339   }
340
341   if( mActionHandler )
342   {
343     ret = mActionHandler->AccessibilityActionPrevious(allowEndFeedback);
344   }
345
346   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
347
348   return ret;
349 }
350
351 bool AccessibilityManager::HandleActionActivateEvent()
352 {
353   bool ret = false;
354
355   Dali::AccessibilityManager handle( this );
356
357   /*
358    * In order to application decide reading action first,
359    * emit ActionActivate signal in first, AccessibilityActionActivate for handler in next
360    */
361   if ( !mIndicatorFocused )
362   {
363     if( !mActionActivateSignalV2.Empty() )
364     {
365       mActionActivateSignalV2.Emit( handle );
366     }
367   }
368
369   if( mActionHandler )
370   {
371     ret = mActionHandler->AccessibilityActionActivate();
372   }
373
374   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
375
376   return ret;
377 }
378
379 bool AccessibilityManager::HandleActionReadEvent(unsigned int x, unsigned int y, bool allowReadAgain)
380 {
381   bool ret = false;
382
383   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %d , %d\n", __FUNCTION__, __LINE__, x, y);
384
385   mReadPosition.x = x;
386   mReadPosition.y = y;
387
388   Dali::AccessibilityManager handle( this );
389
390   bool indicatorFocused = false;
391
392   // Check whether the Indicator is focused
393   if( mIndicator && mIndicator->IsConnected() )
394   {
395     // Check the position and size of Indicator actor
396     Dali::Actor indicatorActor = mIndicator->GetActor();
397     Vector3 position = Vector3(0.0f, 0.0f, 0.0f);
398     Vector3 size = indicatorActor.GetCurrentSize();
399
400     if(mReadPosition.x >= position.x &&
401        mReadPosition.x <= position.x + size.width &&
402        mReadPosition.y >= position.y &&
403        mReadPosition.y <= position.y + size.height)
404     {
405       indicatorFocused = true;
406       DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] Indicator area!!!!\n", __FUNCTION__, __LINE__);
407     }
408   }
409
410   if( mIndicator )
411   {
412     if( !mIndicatorFocused && indicatorFocused )
413     {
414       // If Indicator is focused, the focus should be cleared in Dali focus chain.
415       if( mActionHandler )
416       {
417         mActionHandler->ClearAccessibilityFocus();
418       }
419     }
420
421     mIndicatorFocused = indicatorFocused;
422
423     // Send accessibility READ action information to Indicator
424     if( mIndicatorFocused )
425     {
426       DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] Send READ message to indicator!!!!\n", __FUNCTION__, __LINE__);
427     }
428   }
429
430   if(allowReadAgain)
431   {
432     /*
433      * In order to application decide reading action first,
434      * emit ActionRead signal in first, AccessibilityActionRead for handler in next
435      */
436     if( !mIndicatorFocused )
437     {
438       if ( !mActionReadSignalV2.Empty() )
439       {
440         mActionReadSignalV2.Emit( handle );
441       }
442     }
443   }
444   else
445   {
446     /*
447      * In order to application decide reading action first,
448      * emit ActionRead signal in first, AccessibilityActionRead for handler in next
449      */
450     if( !mIndicatorFocused )
451     {
452       if ( !mActionOverSignalV2.Empty() )
453       {
454         mActionOverSignalV2.Emit( handle );
455       }
456     }
457   }
458
459   if( mActionHandler && !mIndicatorFocused)
460   {
461     // If Indicator is not focused, the accessibility actions should be handled by the registered
462     // accessibility action handler (e.g. focus manager)
463     ret = mActionHandler->AccessibilityActionRead(allowReadAgain);
464     DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
465   }
466
467   return ret;
468 }
469
470 bool AccessibilityManager::HandleActionReadNextEvent(bool allowEndFeedback)
471 {
472   bool ret = false;
473
474   Dali::AccessibilityManager handle( this );
475
476   /*
477    * In order to application decide reading action first,
478    * emit ActionReadNext signal in first, AccessibilityActionReadNext for handler in next
479    */
480   if ( !mIndicatorFocused )
481   {
482     if( !mActionReadNextSignalV2.Empty() )
483     {
484       mActionReadNextSignalV2.Emit( handle );
485     }
486   }
487
488   if( mActionHandler )
489   {
490     ret = mActionHandler->AccessibilityActionReadNext(allowEndFeedback);
491   }
492
493   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
494
495   return ret;
496 }
497
498 bool AccessibilityManager::HandleActionReadPreviousEvent(bool allowEndFeedback)
499 {
500   bool ret = false;
501
502   Dali::AccessibilityManager handle( this );
503
504   /*
505    * In order to application decide reading action first,
506    * emit ActionReadPrevious signal in first, AccessibilityActionReadPrevious for handler in next
507    */
508   if ( !mIndicatorFocused )
509   {
510     if( !mActionReadPreviousSignalV2.Empty() )
511     {
512       mActionReadPreviousSignalV2.Emit( handle );
513     }
514   }
515
516   if( mActionHandler )
517   {
518     ret = mActionHandler->AccessibilityActionReadPrevious(allowEndFeedback);
519   }
520
521   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
522
523   return ret;
524 }
525
526 bool AccessibilityManager::HandleActionUpEvent()
527 {
528   bool ret = false;
529
530   Dali::AccessibilityManager handle( this );
531
532   /*
533    * In order to application decide reading action first,
534    * emit ActionUp signal in first, AccessibilityActionUp for handler in next
535    */
536   if ( !mIndicatorFocused )
537   {
538     if( !mActionUpSignalV2.Empty() )
539     {
540       mActionUpSignalV2.Emit( handle );
541     }
542   }
543
544   if( mActionHandler )
545   {
546     ret = mActionHandler->AccessibilityActionUp();
547   }
548
549   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
550
551   return ret;
552 }
553
554 bool AccessibilityManager::HandleActionDownEvent()
555 {
556   bool ret = false;
557
558   Dali::AccessibilityManager handle( this );
559
560   /*
561    * In order to application decide reading action first,
562    * emit ActionDown signal in first, AccessibilityActionDown for handler in next
563    */
564   if ( !mIndicatorFocused )
565   {
566     if( !mActionDownSignalV2.Empty() )
567     {
568       mActionDownSignalV2.Emit( handle );
569     }
570   }
571
572   if( mActionHandler )
573   {
574     ret = mActionHandler->AccessibilityActionDown();
575   }
576
577   DALI_LOG_INFO(gAccessibilityManagerLogFilter, Debug::General, "[%s:%d] %s\n", __FUNCTION__, __LINE__, ret?"TRUE":"FALSE");
578
579   return ret;
580 }
581
582 } // namespace Adaptor
583
584 } // namespace Internal
585
586 } // namespace Dali