Merge "Add an API for getting web view when request is intercepted." into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / adaptor-impl.cpp
1 /*
2  * Copyright (c) 2022 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-bridge.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 #if !defined(DALI_PROFILE_UBUNTU) && !defined(DALI_PROFILE_LIBUV_X11)
917     DALI_LOG_RELEASE_INFO("Start ProcessEvents\n");
918 #endif
919
920     mCore->ProcessEvents();
921
922 #if !defined(DALI_PROFILE_UBUNTU) && !defined(DALI_PROFILE_LIBUV_X11)
923     DALI_LOG_RELEASE_INFO("End ProcessEvents\n");
924 #endif
925
926     if(mPerformanceInterface)
927     {
928       mPerformanceInterface->AddMarker(PerformanceInterface::PROCESS_EVENTS_END);
929     }
930   }
931 }
932
933 void Adaptor::RequestUpdate(bool forceUpdate)
934 {
935   switch(mState)
936   {
937     case RUNNING:
938     {
939       mThreadController->RequestUpdate();
940       break;
941     }
942     case PAUSED:
943     case PAUSED_WHILE_HIDDEN:
944     {
945       if(forceUpdate)
946       {
947         // Update (and resource upload) without rendering
948         mThreadController->RequestUpdateOnce(UpdateMode::SKIP_RENDER);
949       }
950       break;
951     }
952     default:
953     {
954       // Do nothing
955       break;
956     }
957   }
958 }
959
960 void Adaptor::RequestProcessEventsOnIdle(bool forceProcess)
961 {
962   // Only request a notification if the Adaptor is actually running
963   // and we haven't installed the idle notification
964   if((!mNotificationOnIdleInstalled) && (RUNNING == mState || READY == mState || forceProcess))
965   {
966     mNotificationOnIdleInstalled = AddIdleEnterer(MakeCallback(this, &Adaptor::ProcessCoreEventsFromIdle), forceProcess);
967   }
968 }
969
970 void Adaptor::OnWindowShown()
971 {
972   if(PAUSED_WHILE_HIDDEN == mState)
973   {
974     // Adaptor can now be resumed
975     mState = PAUSED;
976
977     Resume();
978
979     // Force a render task
980     RequestUpdateOnce();
981   }
982   else if(RUNNING == mState)
983   {
984     // Force a render task
985     RequestUpdateOnce();
986
987     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Update requested.\n");
988   }
989   else if(PAUSED_WHILE_INITIALIZING == mState)
990   {
991     // Change the state to READY again. It will be changed to RUNNING after the adaptor is started.
992     mState = READY;
993   }
994   else
995   {
996     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowShown: Adaptor is not paused state.[%d]\n", mState);
997   }
998 }
999
1000 void Adaptor::OnWindowHidden()
1001 {
1002   if(RUNNING == mState || READY == mState)
1003   {
1004     bool allWindowsHidden = true;
1005
1006     for(auto window : mWindows)
1007     {
1008       if(window->IsVisible())
1009       {
1010         allWindowsHidden = false;
1011         break;
1012       }
1013     }
1014
1015     // Only pause the adaptor when all the windows are hidden
1016     if(allWindowsHidden)
1017     {
1018       if(mState == RUNNING)
1019       {
1020         Pause();
1021
1022         // Adaptor cannot be resumed until any window is shown
1023         mState = PAUSED_WHILE_HIDDEN;
1024       }
1025       else // mState is READY
1026       {
1027         // Pause the adaptor after the state gets RUNNING
1028         mState = PAUSED_WHILE_INITIALIZING;
1029       }
1030     }
1031     else
1032     {
1033       DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Some windows are shown. Don't pause adaptor.\n");
1034     }
1035   }
1036   else
1037   {
1038     DALI_LOG_RELEASE_INFO("Adaptor::OnWindowHidden: Adaptor is not running state.[%d]\n", mState);
1039   }
1040 }
1041
1042 // Dali::Internal::Adaptor::Adaptor::OnDamaged
1043 void Adaptor::OnDamaged(const DamageArea& area)
1044 {
1045   // This is needed for the case where Dali window is partially obscured
1046   RequestUpdate(false);
1047 }
1048
1049 void Adaptor::SurfaceResizePrepare(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1050 {
1051   mResizedSignal.Emit(mAdaptor);
1052 }
1053
1054 void Adaptor::SurfaceResizeComplete(Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize)
1055 {
1056   // Nofify surface resizing before flushing event queue
1057   mThreadController->ResizeSurface();
1058
1059   // Flush the event queue to give the update-render thread chance
1060   // to start processing messages for new camera setup etc as soon as possible
1061   ProcessCoreEvents();
1062 }
1063
1064 void Adaptor::NotifySceneCreated()
1065 {
1066   GetCore().SceneCreated();
1067
1068   // Flush the event queue to give the update-render thread chance
1069   // to start processing messages for new camera setup etc as soon as possible
1070   ProcessCoreEvents();
1071
1072   // Start thread controller after the scene has been created
1073   mThreadController->Start();
1074
1075   // Process after surface is created (registering to remote surface provider if required)
1076   SurfaceInitialized();
1077
1078   if(mState != PAUSED_WHILE_INITIALIZING)
1079   {
1080     mState = RUNNING;
1081
1082     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is running\n");
1083   }
1084   else
1085   {
1086     mState = RUNNING;
1087
1088     Pause();
1089
1090     mState = PAUSED_WHILE_HIDDEN;
1091
1092     DALI_LOG_RELEASE_INFO("Adaptor::NotifySceneCreated: Adaptor is paused\n");
1093   }
1094 }
1095
1096 void Adaptor::NotifyLanguageChanged()
1097 {
1098   mLanguageChangedSignal.Emit(mAdaptor);
1099 }
1100
1101 void Adaptor::RenderOnce()
1102 {
1103   if(mThreadController)
1104   {
1105     UpdateMode updateMode;
1106     if(mThreadMode == ThreadMode::NORMAL)
1107     {
1108       updateMode = UpdateMode::NORMAL;
1109     }
1110     else
1111     {
1112       updateMode = UpdateMode::FORCE_RENDER;
1113
1114       ProcessCoreEvents();
1115     }
1116     mThreadController->RequestUpdateOnce(updateMode);
1117   }
1118 }
1119
1120 const LogFactoryInterface& Adaptor::GetLogFactory()
1121 {
1122   return *mEnvironmentOptions;
1123 }
1124
1125 void Adaptor::RegisterProcessor(Integration::Processor& processor, bool postProcessor)
1126 {
1127   GetCore().RegisterProcessor(processor, postProcessor);
1128 }
1129
1130 void Adaptor::UnregisterProcessor(Integration::Processor& processor, bool postProcessor)
1131 {
1132   GetCore().UnregisterProcessor(processor, postProcessor);
1133 }
1134
1135 bool Adaptor::IsMultipleWindowSupported() const
1136 {
1137   return mConfigurationManager->IsMultipleWindowSupported();
1138 }
1139
1140 void Adaptor::RequestUpdateOnce()
1141 {
1142   if(mThreadController)
1143   {
1144     mThreadController->RequestUpdateOnce(UpdateMode::NORMAL);
1145   }
1146 }
1147
1148 bool Adaptor::ProcessCoreEventsFromIdle()
1149 {
1150   ProcessCoreEvents();
1151
1152   // the idle handle automatically un-installs itself
1153   mNotificationOnIdleInstalled = false;
1154
1155   return false;
1156 }
1157
1158 Dali::Internal::Adaptor::SceneHolder* Adaptor::GetWindow(Dali::Actor& actor)
1159 {
1160   Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
1161
1162   for(auto window : mWindows)
1163   {
1164     if(scene == window->GetScene())
1165     {
1166       return window;
1167     }
1168   }
1169
1170   return nullptr;
1171 }
1172
1173 Dali::WindowContainer Adaptor::GetWindows() const
1174 {
1175   Dali::WindowContainer windows;
1176
1177   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1178   {
1179     // Downcast to Dali::Window
1180     Dali::Window window(dynamic_cast<Dali::Internal::Adaptor::Window*>(*iter));
1181     if(window)
1182     {
1183       windows.push_back(window);
1184     }
1185   }
1186
1187   return windows;
1188 }
1189
1190 Dali::SceneHolderList Adaptor::GetSceneHolders() const
1191 {
1192   Dali::SceneHolderList sceneHolderList;
1193
1194   for(auto iter = mWindows.begin(); iter != mWindows.end(); ++iter)
1195   {
1196     sceneHolderList.push_back(Dali::Integration::SceneHolder(*iter));
1197   }
1198
1199   return sceneHolderList;
1200 }
1201
1202 Dali::ObjectRegistry Adaptor::GetObjectRegistry() const
1203 {
1204   Dali::ObjectRegistry registry;
1205   if(mCore)
1206   {
1207     registry = mCore->GetObjectRegistry();
1208   }
1209   return registry;
1210 }
1211
1212 Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor, Dali::RenderSurfaceInterface* surface, EnvironmentOptions* environmentOptions, ThreadMode threadMode)
1213 : mResizedSignal(),
1214   mLanguageChangedSignal(),
1215   mWindowCreatedSignal(),
1216   mAdaptor(adaptor),
1217   mState(READY),
1218   mCore(nullptr),
1219   mThreadController(nullptr),
1220   mGraphics(nullptr),
1221   mDisplayConnection(nullptr),
1222   mWindows(),
1223   mConfigurationManager(nullptr),
1224   mPlatformAbstraction(nullptr),
1225   mCallbackManager(nullptr),
1226   mNotificationOnIdleInstalled(false),
1227   mNotificationTrigger(nullptr),
1228   mDaliFeedbackPlugin(),
1229   mFeedbackController(nullptr),
1230   mTtsPlayers(),
1231   mObservers(),
1232   mEnvironmentOptions(environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
1233   mPerformanceInterface(nullptr),
1234   mKernelTracer(),
1235   mSystemTracer(),
1236   mObjectProfiler(nullptr),
1237   mSocketFactory(),
1238   mMutex(),
1239   mThreadMode(threadMode),
1240   mEnvironmentOptionsOwned(environmentOptions ? false : true /* If not provided then we own the object */),
1241   mUseRemoteSurface(false),
1242   mRootLayoutDirection(Dali::LayoutDirection::LEFT_TO_RIGHT)
1243 {
1244   DALI_ASSERT_ALWAYS(!IsAvailable() && "Cannot create more than one Adaptor per thread");
1245   mWindows.insert(mWindows.begin(), &Dali::GetImplementation(window));
1246
1247   gThreadLocalAdaptor = this;
1248 }
1249
1250 void Adaptor::SetRootLayoutDirection(std::string locale)
1251 {
1252   mRootLayoutDirection = static_cast<LayoutDirection::Type>(Internal::Adaptor::Locale::GetDirection(std::string(locale)));
1253   for(auto& window : mWindows)
1254   {
1255     Dali::Actor root = window->GetRootLayer();
1256     root.SetProperty(Dali::Actor::Property::LAYOUT_DIRECTION, mRootLayoutDirection);
1257   }
1258 }
1259
1260 bool Adaptor::AddIdleEnterer(CallbackBase* callback, bool forceAdd)
1261 {
1262   bool idleAdded(false);
1263
1264   // Only add an idle if the Adaptor is actually running
1265   if(RUNNING == mState || READY == mState || forceAdd)
1266   {
1267     idleAdded = mCallbackManager->AddIdleEntererCallback(callback);
1268   }
1269
1270   if(!idleAdded)
1271   {
1272     // Delete callback
1273     delete callback;
1274   }
1275
1276   return idleAdded;
1277 }
1278
1279 void Adaptor::RemoveIdleEnterer(CallbackBase* callback)
1280 {
1281   mCallbackManager->RemoveIdleEntererCallback(callback);
1282 }
1283
1284 } // namespace Adaptor
1285
1286 } // namespace Internal
1287
1288 } // namespace Dali