Merge "[Tizen]Add KeyEventGeneratedSignal for Get KeyEvent normally" into tizen
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2019 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 <dali/internal/adaptor/common/adaptor-impl.h>
20 #include <dali/internal/adaptor/common/adaptor-builder-impl.h>
21
22 // EXTERNAL INCLUDES
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/object/any.h>
26 #include <dali/devel-api/actors/actor-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/context-notifier.h>
30 #include <dali/integration-api/profiling.h>
31 #include <dali/integration-api/input-options.h>
32 #include <dali/integration-api/events/key-event-integ.h>
33 #include <dali/integration-api/events/touch-event-integ.h>
34 #include <dali/integration-api/events/wheel-event-integ.h>
35 #include <dali/integration-api/processor-interface.h>
36
37 // INTERNAL INCLUDES
38 #include <dali/public-api/dali-adaptor-common.h>
39 #include <dali/internal/system/common/thread-controller.h>
40 #include <dali/internal/system/common/performance-interface-factory.h>
41 #include <dali/internal/adaptor/common/lifecycle-observer.h>
42
43 #include <dali/internal/graphics/gles/egl-graphics-factory.h>
44 #include <dali/internal/graphics/gles/egl-graphics.h> // Temporary until Core is abstracted
45
46 #include <dali/devel-api/text-abstraction/font-client.h>
47
48 #include <dali/internal/system/common/callback-manager.h>
49 #include <dali/internal/accessibility/common/tts-player-impl.h>
50 #include <dali/internal/accessibility/common/accessibility-adaptor-impl.h>
51 #include <dali/internal/window-system/common/event-handler.h>
52 #include <dali/internal/graphics/gles/gl-proxy-implementation.h>
53 #include <dali/internal/graphics/gles/gl-implementation.h>
54 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
55 #include <dali/internal/graphics/common/egl-image-extensions.h>
56 #include <dali/internal/clipboard/common/clipboard-impl.h>
57 #include <dali/internal/graphics/common/vsync-monitor.h>
58 #include <dali/internal/system/common/object-profiler.h>
59 #include <dali/internal/window-system/common/display-connection.h>
60 #include <dali/internal/window-system/common/window-impl.h>
61 #include <dali/internal/window-system/common/window-render-surface.h>
62
63 #include <dali/internal/system/common/logging.h>
64
65 #include <dali/internal/system/common/locale-utils.h>
66 #include <dali/internal/imaging/common/image-loader-plugin-proxy.h>
67 #include <dali/internal/imaging/common/image-loader.h>
68
69
70 using Dali::TextAbstraction::FontClient;
71
72 namespace Dali
73 {
74
75 namespace Internal
76 {
77
78 namespace Adaptor
79 {
80
81 namespace
82 {
83 thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
84 } // unnamed namespace
85
86 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
87 {
88   Dali::Adaptor* adaptor = new Dali::Adaptor;
89   Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions );
90   adaptor->mImpl = impl;
91
92   Dali::Internal::Adaptor::AdaptorBuilder* mAdaptorBuilder = new AdaptorBuilder();
93   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
94
95   impl->Initialize( graphicsFactory, configuration );
96   delete mAdaptorBuilder; // Not needed anymore as the graphics interface has now been created
97
98   return adaptor;
99 }
100
101 Dali::Adaptor* Adaptor::New( Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
102 {
103   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
104   Dali::Adaptor* adaptor = New( window, windowImpl.GetSurface(), configuration, environmentOptions );
105   windowImpl.SetAdaptor( *adaptor );
106   return adaptor;
107 }
108
109 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
110 {
111   Dali::Adaptor* adaptor = new Dali::Adaptor; // Public adaptor
112   Adaptor* impl = new Adaptor( window, *adaptor, surface, environmentOptions ); // Impl adaptor
113   adaptor->mImpl = impl;
114
115   impl->Initialize( graphicsFactory, configuration );
116
117   return adaptor;
118 } // Called second
119
120 Dali::Adaptor* Adaptor::New( GraphicsFactory& graphicsFactory, Dali::Integration::SceneHolder window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
121 {
122   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( window );
123   Dali::Adaptor* adaptor = New( graphicsFactory, window, windowImpl.GetSurface(), configuration, environmentOptions );
124   windowImpl.SetAdaptor( *adaptor );
125   return adaptor;
126 } // Called first
127
128 void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration::ContextLoss configuration )
129 {
130   // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
131   Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
132   mEnvironmentOptions->SetLogFunction( logFunction );
133   mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
134
135   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
136
137   std::string path;
138   GetDataStoragePath( path );
139   mPlatformAbstraction->SetDataStoragePath( path );
140
141   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
142   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
143   {
144     dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
145   }
146
147   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from files automatically.
148
149   if( mEnvironmentOptions->PerformanceServerRequired() )
150   {
151     mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
152   }
153
154   mEnvironmentOptions->CreateTraceManager( mPerformanceInterface );
155   mEnvironmentOptions->InstallTraceFunction(); // install tracing for main thread
156
157   mCallbackManager = CallbackManager::New();
158
159   SceneHolderPtr defaultWindow = mWindows.front();
160
161   DALI_ASSERT_DEBUG( defaultWindow->GetSurface() && "Surface not initialized" );
162
163   mGraphics = &( graphicsFactory.Create() );
164   mGraphics->Initialize( mEnvironmentOptions );
165
166   auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
167
168   // This will only be created once
169   eglGraphics->Create();
170
171   GlImplementation& mGLES = eglGraphics->GetGlesInterface();
172   EglSyncImplementation& eglSyncImpl = eglGraphics->GetSyncImplementation();
173
174   mCore = Integration::Core::New( *this,
175                                   *mPlatformAbstraction,
176                                   mGLES,
177                                   eglSyncImpl,
178                                   dataRetentionPolicy ,
179                                   ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE,
180                                   mGraphics->GetDepthBufferRequired(),
181                                   mGraphics->GetStencilBufferRequired() );
182
183   defaultWindow->SetAdaptor( Get() );
184
185   const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
186   if( 0u < timeInterval )
187   {
188     mObjectProfiler = new ObjectProfiler( timeInterval );
189   }
190
191   mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
192
193   mVSyncMonitor = new VSyncMonitor;
194
195   mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
196
197   mThreadController = new ThreadController( *this, *mEnvironmentOptions );
198
199   // Should be called after Core creation
200   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
201   {
202     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
203   }
204   if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
205   {
206     Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
207   }
208   if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
209   {
210     Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
211   }
212   if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
213   {
214     Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
215   }
216   if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
217   {
218     Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
219   }
220   if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
221   {
222     Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
223   }
224   if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
225   {
226     Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
227   }
228   if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
229   {
230     Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
231   }
232   if( mEnvironmentOptions->GetPanGestureUseActualTimes() >= 0 )
233   {
234     Integration::SetPanGestureUseActualTimes( mEnvironmentOptions->GetPanGestureUseActualTimes() == 0 ? true : false );
235   }
236   if( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() >= 0 )
237   {
238     Integration::SetPanGestureInterpolationTimeRange( mEnvironmentOptions->GetPanGestureInterpolationTimeRange() );
239   }
240   if( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() >= 0 )
241   {
242     Integration::SetPanGestureScalarOnlyPredictionEnabled( mEnvironmentOptions->GetPanGestureScalarOnlyPredictionEnabled() == 0 ? true : false  );
243   }
244   if( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() >= 0 )
245   {
246     Integration::SetPanGestureTwoPointPredictionEnabled( mEnvironmentOptions->GetPanGestureTwoPointPredictionEnabled() == 0 ? true : false  );
247   }
248   if( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() >= 0 )
249   {
250     Integration::SetPanGestureTwoPointInterpolatePastTime( mEnvironmentOptions->GetPanGestureTwoPointInterpolatePastTime() );
251   }
252   if( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() >= 0.0f )
253   {
254     Integration::SetPanGestureTwoPointVelocityBias( mEnvironmentOptions->GetPanGestureTwoPointVelocityBias() );
255   }
256   if( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() >= 0.0f )
257   {
258     Integration::SetPanGestureTwoPointAccelerationBias( mEnvironmentOptions->GetPanGestureTwoPointAccelerationBias() );
259   }
260   if( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() >= 0 )
261   {
262     Integration::SetPanGestureMultitapSmoothingRange( mEnvironmentOptions->GetPanGestureMultitapSmoothingRange() );
263   }
264   if( mEnvironmentOptions->GetMinimumPanDistance() >= 0 )
265   {
266     Integration::SetPanGestureMinimumDistance( mEnvironmentOptions->GetMinimumPanDistance() );
267   }
268   if( mEnvironmentOptions->GetMinimumPanEvents() >= 0 )
269   {
270     Integration::SetPanGestureMinimumPanEvents( mEnvironmentOptions->GetMinimumPanEvents() );
271   }
272   if( mEnvironmentOptions->GetMinimumPinchDistance() >= 0 )
273   {
274     Integration::SetPinchGestureMinimumDistance( mEnvironmentOptions->GetMinimumPinchDistance() );
275   }
276
277   // Set max texture size
278   if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
279   {
280     Dali::TizenPlatform::ImageLoader::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
281   }
282 }
283
284 Adaptor::~Adaptor()
285 {
286   // Ensure stop status
287   Stop();
288
289   // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
290   gThreadLocalAdaptor = NULL;
291
292   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
293   {
294     (*iter)->OnDestroy();
295   }
296
297   // Clear out all the handles to Windows
298   mWindows.clear();
299
300   delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
301   delete mVSyncMonitor;
302   delete mObjectProfiler;
303
304   delete mCore;
305
306   delete mDisplayConnection;
307   delete mPlatformAbstraction;
308   delete mCallbackManager;
309   delete mPerformanceInterface;
310
311   mGraphics->Destroy();
312
313   // uninstall it on this thread (main actor thread)
314   Dali::Integration::Log::UninstallLogFunction();
315
316   // Delete environment options if we own it
317   if( mEnvironmentOptionsOwned )
318   {
319     delete mEnvironmentOptions;
320   }
321 }
322
323 void Adaptor::Start()
324 {
325   // It doesn't support restart after stop at this moment to support restarting, need more testing
326   if( READY != mState )
327   {
328     return;
329   }
330
331   mCore->Initialize();
332
333   SetupSystemInformation();
334
335   // Start the callback manager
336   mCallbackManager->Start();
337
338   SceneHolderPtr defaultWindow = mWindows.front();
339
340   unsigned int dpiHor, dpiVer;
341   dpiHor = dpiVer = 0;
342
343   defaultWindow->GetSurface()->GetDpi( dpiHor, dpiVer );
344
345   // set the DPI value for font rendering
346   FontClient fontClient = FontClient::Get();
347   fontClient.SetDpi( dpiHor, dpiVer );
348
349   // Tell the core the size of the surface just before we start the render-thread
350   mCore->SurfaceResized( defaultWindow->GetSurface() );
351
352   // Initialize the thread controller
353   mThreadController->Initialize();
354
355   ProcessCoreEvents(); // Ensure any startup messages are processed.
356
357   // Initialize the image loader plugin
358   Internal::Adaptor::ImageLoaderPluginProxy::Initialize();
359
360   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
361   {
362     (*iter)->OnStart();
363   }
364 }
365
366 // Dali::Internal::Adaptor::Adaptor::Pause
367 void Adaptor::Pause()
368 {
369   // Only pause the adaptor if we're actually running.
370   if( RUNNING == mState )
371   {
372     // Inform observers that we are about to be paused.
373     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
374     {
375       (*iter)->OnPause();
376     }
377
378     // Pause all windows event handlers when adaptor paused
379     for( SceneHolderPtr window : mWindows )
380     {
381       window->Pause();
382     }
383
384     mThreadController->Pause();
385     mState = PAUSED;
386
387     // Ensure any messages queued during pause callbacks are processed by doing another update.
388     RequestUpdateOnce();
389
390     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Paused\n" );
391   }
392   else
393   {
394     DALI_LOG_RELEASE_INFO( "Adaptor::Pause: Not paused [%d]\n", mState );
395   }
396 }
397
398 // Dali::Internal::Adaptor::Adaptor::Resume
399 void Adaptor::Resume()
400 {
401   // Only resume the adaptor if we are in the suspended state.
402   if( PAUSED == mState )
403   {
404     mState = RUNNING;
405
406     // Reset the event handlers when adaptor resumed
407     for( SceneHolderPtr window : mWindows )
408     {
409       window->Resume();
410     }
411
412     // Inform observers that we have resumed.
413     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
414     {
415       (*iter)->OnResume();
416     }
417
418     // Trigger processing of events queued up while paused
419     mCore->ProcessEvents();
420
421     // Do at end to ensure our first update/render after resumption includes the processed messages as well
422     mThreadController->Resume();
423
424     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Resumed\n");
425   }
426   else
427   {
428     DALI_LOG_RELEASE_INFO( "Adaptor::Resume: Not resumed [%d]\n", mState );
429   }
430 }
431
432 void Adaptor::Stop()
433 {
434   if( RUNNING == mState ||
435       PAUSED  == mState ||
436       PAUSED_WHILE_HIDDEN == mState )
437   {
438     for( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
439     {
440       (*iter)->OnStop();
441     }
442
443     mThreadController->Stop();
444
445     // Delete the TTS player
446     for( int i =0; i < Dali::TtsPlayer::MODE_NUM; i++ )
447     {
448       if( mTtsPlayers[i] )
449       {
450         mTtsPlayers[i].Reset();
451       }
452     }
453
454     // Destroy the image loader plugin
455     Internal::Adaptor::ImageLoaderPluginProxy::Destroy();
456
457     delete mNotificationTrigger;
458     mNotificationTrigger = NULL;
459
460     mCallbackManager->Stop();
461
462     mState = STOPPED;
463
464     DALI_LOG_RELEASE_INFO( "Adaptor::Stop\n" );
465   }
466 }
467
468 void Adaptor::ContextLost()
469 {
470   mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
471 }
472
473 void Adaptor::ContextRegained()
474 {
475   // Inform core, so that texture resources can be reloaded
476   mCore->RecoverFromContextLoss();
477
478   mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
479 }
480
481 void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
482 {
483   Integration::Point convertedPoint( point );
484   mWindows.front()->FeedTouchPoint( convertedPoint, timeStamp );
485 }
486
487 void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
488 {
489   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
490   mWindows.front()->FeedWheelEvent( event );
491 }
492
493 void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
494 {
495   Integration::KeyEvent convertedEvent( keyEvent );
496   mWindows.front()->FeedKeyEvent( convertedEvent );
497 }
498
499 void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::RenderSurfaceInterface& newSurface )
500 {
501   Internal::Adaptor::SceneHolder* windowImpl = &Dali::GetImplementation( window );
502   for( SceneHolderPtr windowPtr : mWindows )
503   {
504     if( windowPtr.Get() == windowImpl ) // the window is not deleted
505     {
506       // Let the core know the surface size has changed
507       mCore->SurfaceResized( &newSurface );
508
509       mResizedSignal.Emit( mAdaptor );
510
511       windowImpl->SetSurface( &newSurface );
512
513       // Flush the event queue to give the update-render thread chance
514       // to start processing messages for new camera setup etc as soon as possible
515       ProcessCoreEvents();
516
517       // This method blocks until the render thread has completed the replace.
518       mThreadController->ReplaceSurface( &newSurface );
519       break;
520     }
521   }
522 }
523
524 Dali::RenderSurfaceInterface& Adaptor::GetSurface() const
525 {
526   return *mWindows.front()->GetSurface();
527 }
528
529 void Adaptor::ReleaseSurfaceLock()
530 {
531   mWindows.front()->GetSurface()->ReleaseLock();
532 }
533
534 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
535 {
536   if( !mTtsPlayers[mode] )
537   {
538     // Create the TTS player when it needed, because it can reduce launching time.
539     mTtsPlayers[mode] = TtsPlayer::New(mode);
540   }
541
542   return mTtsPlayers[mode];
543 }
544
545 bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue, bool forceAdd )
546 {
547   bool idleAdded(false);
548
549   // Only add an idle if the Adaptor is actually running
550   if( RUNNING == mState || READY == mState || forceAdd )
551   {
552     idleAdded = mCallbackManager->AddIdleCallback( callback, hasReturnValue );
553   }
554
555   return idleAdded;
556 }
557
558 void Adaptor::RemoveIdle( CallbackBase* callback )
559 {
560   mCallbackManager->RemoveIdleCallback( callback );
561 }
562
563 void Adaptor::SetPreRenderCallback( CallbackBase* callback )
564 {
565   mThreadController->SetPreRenderCallback( callback );
566 }
567
568 bool Adaptor::AddWindow( Dali::Integration::SceneHolder* childWindow, const std::string& childWindowName, const std::string& childWindowClassName, const bool& childWindowMode )
569 {
570   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
571   windowImpl.SetAdaptor( Get() );
572
573   // Add the new Window to the container - the order is not important
574   mWindows.push_back( SceneHolderPtr( &windowImpl ) );
575   return true;
576 }
577
578 bool Adaptor::RemoveWindow( Dali::Integration::SceneHolder* childWindow )
579 {
580   Internal::Adaptor::SceneHolder& windowImpl = Dali::GetImplementation( *childWindow );
581   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
582   {
583     if( *iter == &windowImpl )
584     {
585       mWindows.erase( iter );
586       return true;
587     }
588   }
589
590   return false;
591 }
592
593 bool Adaptor::RemoveWindow( std::string childWindowName )
594 {
595   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
596   {
597     if( ( *iter )->GetName() == childWindowName )
598     {
599       mWindows.erase( iter );
600       return true;
601     }
602   }
603
604   return false;
605 }
606
607 bool Adaptor::RemoveWindow( Internal::Adaptor::SceneHolder* childWindow )
608 {
609   for ( WindowContainer::iterator iter = mWindows.begin(); iter != mWindows.end(); ++iter )
610   {
611     if( ( *iter )->GetId() == childWindow->GetId() )
612     {
613       mWindows.erase( iter );
614       return true;
615     }
616   }
617
618   return false;
619 }
620
621 Dali::Adaptor& Adaptor::Get()
622 {
623   DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
624   return gThreadLocalAdaptor->mAdaptor;
625 }
626
627 bool Adaptor::IsAvailable()
628 {
629   return gThreadLocalAdaptor != NULL;
630 }
631
632 void Adaptor::SceneCreated()
633 {
634   mCore->SceneCreated();
635 }
636
637 Dali::Integration::Core& Adaptor::GetCore()
638 {
639   return *mCore;
640 }
641
642 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
643 {
644   mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
645 }
646
647 void Adaptor::SetUseHardwareVSync( bool useHardware )
648 {
649   mVSyncMonitor->SetUseHardwareVSync( useHardware );
650 }
651
652 Dali::DisplayConnection& Adaptor::GetDisplayConnectionInterface()
653 {
654   DALI_ASSERT_DEBUG( mDisplayConnection && "Display connection not created" );
655   return *mDisplayConnection;
656 }
657
658 GraphicsInterface& Adaptor::GetGraphicsInterface()
659 {
660   DALI_ASSERT_DEBUG( mGraphics && "Graphics interface not created" );
661   return *mGraphics;
662 }
663
664 Dali::Integration::PlatformAbstraction& Adaptor::GetPlatformAbstractionInterface()
665 {
666   return *mPlatformAbstraction;
667 }
668
669 TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
670 {
671   return *mNotificationTrigger;
672 }
673
674 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
675 {
676   return mTriggerEventFactory;
677 }
678
679 SocketFactoryInterface& Adaptor::GetSocketFactoryInterface()
680 {
681   return mSocketFactory;
682 }
683
684 Dali::RenderSurfaceInterface* Adaptor::GetRenderSurfaceInterface()
685 {
686   if( !mWindows.empty() )
687   {
688     return mWindows.front()->GetSurface();
689   }
690
691   return nullptr;
692 }
693
694 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
695 {
696   return mVSyncMonitor;
697 }
698
699 TraceInterface& Adaptor::GetKernelTraceInterface()
700 {
701   return mKernelTracer;
702 }
703
704 TraceInterface& Adaptor::GetSystemTraceInterface()
705 {
706   return mSystemTracer;
707 }
708
709 PerformanceInterface* Adaptor::GetPerformanceInterface()
710 {
711   return mPerformanceInterface;
712 }
713
714 Integration::PlatformAbstraction& Adaptor::GetPlatformAbstraction() const
715 {
716   DALI_ASSERT_DEBUG( mPlatformAbstraction && "PlatformAbstraction not created" );
717   return *mPlatformAbstraction;
718 }
719
720 void Adaptor::DestroyTtsPlayer(Dali::TtsPlayer::Mode mode)
721 {
722   if( mTtsPlayers[mode] )
723   {
724     mTtsPlayers[mode].Reset();
725   }
726 }
727
728 Any Adaptor::GetNativeWindowHandle()
729 {
730   return mWindows.front()->GetNativeHandle();
731 }
732
733 Any Adaptor::GetGraphicsDisplay()
734 {
735   Any display;
736
737   if (mGraphics)
738   {
739     auto eglGraphics = static_cast<EglGraphics *>( mGraphics ); // This interface is temporary until Core has been updated to match
740
741     EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
742     display = eglImpl.GetDisplay();
743   }
744
745   return display;
746 }
747
748 void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
749 {
750   mUseRemoteSurface = useRemoteSurface;
751 }
752
753 void Adaptor::AddObserver( LifeCycleObserver& observer )
754 {
755   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
756
757   if ( match == mObservers.end() )
758   {
759     mObservers.push_back( &observer );
760   }
761 }
762
763 void Adaptor::RemoveObserver( LifeCycleObserver& observer )
764 {
765   ObserverContainer::iterator match ( find(mObservers.begin(), mObservers.end(), &observer) );
766
767   if ( match != mObservers.end() )
768   {
769     mObservers.erase( match );
770   }
771 }
772
773 void Adaptor::QueueCoreEvent(const Dali::Integration::Event& event)
774 {
775   if( mCore )
776   {
777     mCore->QueueEvent(event);
778   }
779 }
780
781 void Adaptor::ProcessCoreEvents()
782 {
783   if( mCore )
784   {
785     if( mPerformanceInterface )
786     {
787       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_START );
788     }
789
790     mCore->ProcessEvents();
791
792     if( mPerformanceInterface )
793     {
794       mPerformanceInterface->AddMarker( PerformanceInterface::PROCESS_EVENTS_END );
795     }
796   }
797 }
798
799 void Adaptor::RequestUpdate( bool forceUpdate )
800 {
801   switch( mState )
802   {
803     case RUNNING:
804     {
805       mThreadController->RequestUpdate();
806       break;
807     }
808     case PAUSED:
809     case PAUSED_WHILE_HIDDEN:
810     {
811       // When Dali applications are partially visible behind the lock-screen,
812       // the indicator must be updated (therefore allow updates in the PAUSED state)
813       if( forceUpdate )
814       {
815         mThreadController->RequestUpdateOnce();
816       }
817       break;
818     }
819     default:
820     {
821       // Do nothing
822       break;
823     }
824   }
825 }
826
827 void Adaptor::RequestProcessEventsOnIdle( bool forceProcess )
828 {
829   // Only request a notification if the Adaptor is actually running
830   // and we haven't installed the idle notification
831   if( ( ! mNotificationOnIdleInstalled ) && ( RUNNING == mState || READY == mState || forceProcess ) )
832   {
833     mNotificationOnIdleInstalled = AddIdleEnterer( MakeCallback( this, &Adaptor::ProcessCoreEventsFromIdle ), forceProcess );
834   }
835 }
836
837 void Adaptor::OnWindowShown()
838 {
839   if( PAUSED_WHILE_HIDDEN == mState )
840   {
841     // Adaptor can now be resumed
842     mState = PAUSED;
843
844     Resume();
845
846     // Force a render task
847     RequestUpdateOnce();
848   }
849   else
850   {
851     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState );
852   }
853 }
854
855 void Adaptor::OnWindowHidden()
856 {
857   if( RUNNING == mState || READY == mState )
858   {
859     bool allWindowsHidden = true;
860
861     for( SceneHolderPtr window : mWindows )
862     {
863       if ( window->IsVisible() )
864       {
865         allWindowsHidden = false;
866         break;
867       }
868     }
869
870     // Only pause the adaptor when all the windows are hidden
871     if( allWindowsHidden )
872     {
873       if( mState == RUNNING )
874       {
875         Pause();
876
877         // Adaptor cannot be resumed until any window is shown
878         mState = PAUSED_WHILE_HIDDEN;
879       }
880       else  // mState is READY
881       {
882         // Pause the adaptor after the state gets RUNNING
883         mState = PAUSED_WHILE_INITIALIZING;
884       }
885     }
886     else
887     {
888       DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n" );
889     }
890   }
891   else
892   {
893     DALI_LOG_RELEASE_INFO( "Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState );
894   }
895 }
896
897 // Dali::Internal::Adaptor::Adaptor::OnDamaged
898 void Adaptor::OnDamaged( const DamageArea& area )
899 {
900   // This is needed for the case where Dali window is partially obscured
901   RequestUpdate( false );
902 }
903
904 void Adaptor::SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
905 {
906   // Let the core know the surface size has changed
907   mCore->SurfaceResized( surface );
908
909   mResizedSignal.Emit( mAdaptor );
910 }
911
912 void Adaptor::SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize )
913 {
914   // Flush the event queue to give the update-render thread chance
915   // to start processing messages for new camera setup etc as soon as possible
916   ProcessCoreEvents();
917
918   mThreadController->ResizeSurface();
919 }
920
921 void Adaptor::NotifySceneCreated()
922 {
923   GetCore().SceneCreated();
924
925   // Flush the event queue to give the update-render thread chance
926   // to start processing messages for new camera setup etc as soon as possible
927   ProcessCoreEvents();
928
929   // Start thread controller after the scene has been created
930   mThreadController->Start();
931
932   // Process after surface is created (registering to remote surface provider if required)
933   SurfaceInitialized();
934
935   if( mState != PAUSED_WHILE_INITIALIZING )
936   {
937     mState = RUNNING;
938
939     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is running\n" );
940   }
941   else
942   {
943     mState = RUNNING;
944
945     Pause();
946
947     mState = PAUSED_WHILE_HIDDEN;
948
949     DALI_LOG_RELEASE_INFO( "Adaptor::NotifySceneCreated: Adaptor is paused\n" );
950   }
951 }
952
953 void Adaptor::NotifyLanguageChanged()
954 {
955   mLanguageChangedSignal.Emit( mAdaptor );
956 }
957
958 void Adaptor::RenderOnce()
959 {
960   RequestUpdateOnce();
961 }
962
963 const LogFactoryInterface& Adaptor::GetLogFactory()
964 {
965   return *mEnvironmentOptions;
966 }
967
968 void Adaptor::RegisterProcessor( Integration::Processor& processor )
969 {
970   GetCore().RegisterProcessor(processor);
971 }
972
973 void Adaptor::UnregisterProcessor( Integration::Processor& processor )
974 {
975   GetCore().UnregisterProcessor(processor);
976 }
977
978 void Adaptor::RequestUpdateOnce()
979 {
980   if( mThreadController )
981   {
982     mThreadController->RequestUpdateOnce();
983   }
984 }
985
986 bool Adaptor::ProcessCoreEventsFromIdle()
987 {
988   ProcessCoreEvents();
989
990   // the idle handle automatically un-installs itself
991   mNotificationOnIdleInstalled = false;
992
993   return false;
994 }
995
996 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow( Dali::Actor& actor )
997 {
998   Dali::Integration::Scene scene = Dali::Integration::Scene::Get( actor );
999
1000   for( auto window : mWindows )
1001   {
1002     if ( scene == window->GetScene() )
1003     {
1004       return window.Get();
1005     }
1006   }
1007
1008   return nullptr;
1009 }
1010
1011 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions)
1012 : mResizedSignal(),
1013   mLanguageChangedSignal(),
1014   mAdaptor( adaptor ),
1015   mState( READY ),
1016   mCore( nullptr ),
1017   mThreadController( nullptr ),
1018   mVSyncMonitor( nullptr ),
1019   mGraphics( nullptr ),
1020   mDisplayConnection( nullptr ),
1021   mWindows(),
1022   mPlatformAbstraction( nullptr ),
1023   mCallbackManager( nullptr ),
1024   mNotificationOnIdleInstalled( false ),
1025   mNotificationTrigger( nullptr ),
1026   mDaliFeedbackPlugin(),
1027   mFeedbackController( nullptr ),
1028   mTtsPlayers(),
1029   mObservers(),
1030   mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1031   mPerformanceInterface( nullptr ),
1032   mKernelTracer(),
1033   mSystemTracer(),
1034   mTriggerEventFactory(),
1035   mObjectProfiler( nullptr ),
1036   mSocketFactory(),
1037   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
1038   mUseRemoteSurface( false )
1039 {
1040   DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
1041   mWindows.insert( mWindows.begin(), SceneHolderPtr( &Dali::GetImplementation( window ) ) );
1042
1043   gThreadLocalAdaptor = this;
1044 }
1045
1046 void Adaptor::SetRootLayoutDirection( std::string locale )
1047 {
1048   Dali::Stage stage = Dali::Stage::GetCurrent();
1049
1050   stage.GetRootLayer().SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION,
1051                                     static_cast< LayoutDirection::Type >( Internal::Adaptor::Locale::GetDirection( std::string( locale ) ) ) );
1052 }
1053
1054 bool Adaptor::AddIdleEnterer( CallbackBase* callback, bool forceAdd )
1055 {
1056   bool idleAdded( false );
1057
1058   // Only add an idle if the Adaptor is actually running
1059   if( RUNNING == mState || READY == mState || forceAdd )
1060   {
1061     idleAdded = mCallbackManager->AddIdleEntererCallback( callback );
1062   }
1063
1064   return idleAdded;
1065 }
1066
1067 void Adaptor::RemoveIdleEnterer( CallbackBase* callback )
1068 {
1069   mCallbackManager->RemoveIdleEntererCallback( callback );
1070 }
1071
1072 } // namespace Adaptor
1073
1074 } // namespace Internal
1075
1076 } // namespace Dali