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