Merge "Remove non-touch related deprecated APIs" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / application-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/application-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/devel-api/common/singleton-service.h>
24
25 // INTERNAL INCLUDES
26 #include <dali/devel-api/adaptor-framework/style-monitor.h>
27 #include <dali/devel-api/text-abstraction/font-client.h>
28 #include <dali/internal/adaptor/common/adaptor-impl.h>
29 #include <dali/internal/system/common/command-line-options.h>
30 #include <dali/internal/adaptor/common/framework.h>
31 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
32 #include <dali/internal/window-system/common/window-impl.h>
33 #include <dali/internal/window-system/common/window-render-surface.h>
34 #include <dali/internal/window-system/common/render-surface-factory.h>
35
36 // To disable a macro with the same name from one of OpenGL headers
37 #undef Status
38
39 namespace Dali
40 {
41
42 namespace TizenPlatform
43 {
44 class TizenPlatformAbstraction;
45 }
46
47 namespace Integration
48 {
49 class Core;
50 }
51
52 namespace Internal
53 {
54
55 namespace Adaptor
56 {
57
58 ApplicationPtr Application::gPreInitializedApplication( NULL );
59
60 ApplicationPtr Application::New(
61   int* argc,
62   char **argv[],
63   const std::string& stylesheet,
64   Dali::Application::WINDOW_MODE windowMode,
65   const PositionSize& positionSize,
66   Framework::Type applicationType)
67 {
68   ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, positionSize, applicationType ) );
69   return application;
70 }
71
72 void Application::PreInitialize( int* argc, char** argv[] )
73 {
74   if( !gPreInitializedApplication )
75   {
76     Dali::TextAbstraction::FontClientPreInitialize();
77
78     gPreInitializedApplication = new Application ( argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL );
79     gPreInitializedApplication->CreateWindow();    // Only create window
80     gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
81   }
82 }
83
84 Application::Application( int* argc, char** argv[], const std::string& stylesheet,
85   Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType )
86 : mInitSignal(),
87   mTerminateSignal(),
88   mPauseSignal(),
89   mResumeSignal(),
90   mResetSignal(),
91   mAppControlSignal(),
92   mLanguageChangedSignal(),
93   mRegionChangedSignal(),
94   mEventLoop( nullptr ),
95   mFramework( nullptr ),
96   mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
97   mCommandLineOptions( nullptr ),
98   mAdaptorBuilder( nullptr ),
99   mAdaptor( nullptr ),
100   mMainWindow(),
101   mMainWindowMode( windowMode ),
102   mMainWindowName(),
103   mStylesheet( stylesheet ),
104   mEnvironmentOptions(),
105   mWindowPositionSize( positionSize ),
106   mLaunchpadState( Launchpad::NONE ),
107   mSlotDelegate( this )
108 {
109   // Get mName from environment options
110   mMainWindowName = mEnvironmentOptions.GetWindowName();
111   if( mMainWindowName.empty() && argc && ( *argc > 0 ) )
112   {
113     // Set mName from command-line args if environment option not set
114     mMainWindowName = (*argv)[0];
115   }
116
117   mCommandLineOptions = new CommandLineOptions(argc, argv);
118   mFramework = new Framework( *this, argc, argv, applicationType );
119   mUseRemoteSurface = (applicationType == Framework::WATCH);
120 }
121
122 Application::~Application()
123 {
124   SingletonService service = SingletonService::Get();
125   // Note this can be false i.e. if Application has never created a Core instance
126   if( service )
127   {
128     service.UnregisterAll();
129   }
130
131   mMainWindow.Reset();
132   delete mAdaptor;
133   delete mAdaptorBuilder;
134   delete mCommandLineOptions;
135   delete mFramework;
136 }
137
138 void Application::CreateWindow()
139 {
140   if( mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0 )
141   {
142     if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
143     {
144       // Command line options override environment options and full screen
145       mWindowPositionSize.width = mCommandLineOptions->stageWidth;
146       mWindowPositionSize.height = mCommandLineOptions->stageHeight;
147     }
148     else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
149     {
150       // Environment options override full screen functionality if command line arguments not provided
151       mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
152       mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
153     }
154   }
155
156   const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
157
158   Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mMainWindowMode == Dali::Application::TRANSPARENT);
159   mMainWindow = Dali::Window( window );
160
161   // Quit the application when the window is closed
162   GetImplementation( mMainWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
163 }
164
165 void Application::CreateAdaptor()
166 {
167   DALI_ASSERT_ALWAYS( mMainWindow && "Window required to create adaptor" );
168
169   auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
170
171   Integration::SceneHolder sceneHolder = Integration::SceneHolder( &Dali::GetImplementation( mMainWindow ) );
172
173   mAdaptor = Adaptor::New( graphicsFactory, sceneHolder, mContextLossConfiguration, &mEnvironmentOptions );
174
175   Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
176 }
177
178 void Application::CreateAdaptorBuilder()
179 {
180   mAdaptorBuilder = new AdaptorBuilder();
181 }
182
183 void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
184 {
185   mContextLossConfiguration = configuration;
186
187   // Run the application
188   mFramework->Run();
189 }
190
191 void Application::Lower()
192 {
193   // Lower the application without quitting it.
194   mMainWindow.Lower();
195 }
196
197 void Application::Quit()
198 {
199   // Actually quit the application.
200   // Force a call to Quit even if adaptor is not running.
201   Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ), false, true );
202 }
203
204 void Application::QuitFromMainLoop()
205 {
206   mAdaptor->Stop();
207
208   mFramework->Quit();
209   // This will trigger OnTerminate(), below, after the main loop has completed.
210 }
211
212 void Application::OnInit()
213 {
214   mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
215
216   CreateAdaptorBuilder();
217   // If an application was pre-initialized, a window was made in advance
218   if( mLaunchpadState == Launchpad::NONE )
219   {
220     CreateWindow();
221   }
222
223   CreateAdaptor();
224
225   // Run the adaptor
226   mAdaptor->Start();
227
228   if( ! mStylesheet.empty() )
229   {
230     Dali::StyleMonitor::Get().SetTheme( mStylesheet );
231   }
232
233   // Wire up the LifecycleController
234   Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
235
236   InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
237   TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
238   PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
239   ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
240   ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
241   LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
242
243   Dali::Application application(this);
244   mInitSignal.Emit( application );
245
246   mAdaptor->NotifySceneCreated();
247 }
248
249 void Application::OnTerminate()
250 {
251   // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
252   // delete the window as ecore_x has been destroyed by AppCore
253
254   Dali::Application application(this);
255   mTerminateSignal.Emit( application );
256
257   if( mAdaptor )
258   {
259     // Ensure that the render-thread is not using the surface(window) after we delete it
260     mAdaptor->Stop();
261   }
262
263   mMainWindow.Reset(); // This only resets (clears) the default Window
264 }
265
266 void Application::OnPause()
267 {
268   // A DALi app should handle Pause/Resume events.
269   // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
270   // Pausing DALi core only occurs on the Window Hidden framework event
271   Dali::Application application(this);
272   mPauseSignal.Emit( application );
273 }
274
275 void Application::OnResume()
276 {
277   // Emit the signal first so the application can queue any messages before we do an update/render
278   // This ensures we do not just redraw the last frame before pausing if that's not required
279   Dali::Application application(this);
280   mResumeSignal.Emit( application );
281
282   // DALi just delivers the framework Resume event to the application.
283   // Resuming DALi core only occurs on the Window Show framework event
284
285   // Trigger processing of events queued up while paused
286   CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
287   coreEventInterface.ProcessCoreEvents();
288 }
289
290 void Application::OnReset()
291 {
292   /*
293    * usually, reset callback was called when a caller request to launch this application via aul.
294    * because Application class already handled initialization in OnInit(), OnReset do nothing.
295    */
296   Dali::Application application(this);
297   mResetSignal.Emit( application );
298 }
299
300 void Application::OnAppControl(void *data)
301 {
302   Dali::Application application(this);
303   mAppControlSignal.Emit( application , data );
304 }
305
306 void Application::OnLanguageChanged()
307 {
308   mAdaptor->NotifyLanguageChanged();
309   Dali::Application application(this);
310   mLanguageChangedSignal.Emit( application );
311 }
312
313 void Application::OnRegionChanged()
314 {
315   Dali::Application application(this);
316   mRegionChangedSignal.Emit( application );
317 }
318
319 void Application::OnBatteryLow( Dali::DeviceStatus::Battery::Status status )
320 {
321   Dali::Application application(this);
322   mLowBatterySignal.Emit( status );
323 }
324
325 void Application::OnMemoryLow( Dali::DeviceStatus::Memory::Status status )
326 {
327   Dali::Application application(this);
328   mLowMemorySignal.Emit( status );
329 }
330
331 void Application::OnSurfaceCreated( Any newSurface )
332 {
333   void* newWindow = AnyCast< void* >( newSurface );
334   void* oldWindow = AnyCast< void* >( mMainWindow.GetNativeHandle() );
335   if( oldWindow != newWindow )
336   {
337     auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
338     std::unique_ptr< WindowRenderSurface > newSurfacePtr
339       = renderSurfaceFactory->CreateWindowRenderSurface( PositionSize(), newSurface, true );
340
341     mAdaptor->ReplaceSurface( mMainWindow, *newSurfacePtr.release() );
342   }
343 }
344
345 void Application::OnSurfaceDestroyed( Any surface )
346 {
347 }
348
349 bool Application::AddIdle( CallbackBase* callback, bool hasReturnValue )
350 {
351   return mAdaptor->AddIdle( callback, hasReturnValue );
352 }
353
354 std::string Application::GetRegion() const
355 {
356   return mFramework->GetRegion();
357 }
358
359 std::string Application::GetLanguage() const
360 {
361   return mFramework->GetLanguage();
362 }
363
364 Dali::Adaptor& Application::GetAdaptor()
365 {
366   return *mAdaptor;
367 }
368
369 Dali::Window Application::GetWindow()
370 {
371   return mMainWindow;
372 }
373
374 std::string Application::GetResourcePath()
375 {
376   return Internal::Adaptor::Framework::GetResourcePath();
377 }
378
379 std::string Application::GetDataPath()
380 {
381   return Internal::Adaptor::Framework::GetDataPath();
382 }
383
384 void Application::SetStyleSheet( const std::string& stylesheet )
385 {
386   mStylesheet = stylesheet;
387 }
388
389 void Application::SetCommandLineOptions( int* argc, char **argv[] )
390 {
391   delete mCommandLineOptions;
392
393   mCommandLineOptions = new CommandLineOptions( argc, argv );
394
395   mFramework->SetCommandLineOptions( argc, argv );
396 }
397
398 ApplicationPtr Application::GetPreInitializedApplication()
399 {
400   return gPreInitializedApplication;
401 }
402
403 } // namespace Adaptor
404
405 } // namespace Internal
406
407 } // namespace Dali