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