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