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