2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/adaptor/common/application-impl.h>
22 #include <dali/devel-api/common/singleton-service.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/trace.h>
25 #include <dali/public-api/object/object-registry.h>
28 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
29 #include <dali/devel-api/adaptor-framework/style-monitor.h>
30 #include <dali/devel-api/atspi-interfaces/accessible.h>
31 #include <dali/devel-api/text-abstraction/font-client.h>
32 #include <dali/internal/adaptor/common/adaptor-impl.h>
33 #include <dali/internal/adaptor/common/framework.h>
34 #include <dali/internal/adaptor/common/lifecycle-controller-impl.h>
35 #include <dali/internal/system/common/command-line-options.h>
36 #include <dali/internal/window-system/common/render-surface-factory.h>
37 #include <dali/internal/window-system/common/window-impl.h>
38 #include <dali/internal/window-system/common/window-render-surface.h>
39 #include <dali/internal/window-system/common/window-system.h>
41 // To disable a macro with the same name from one of OpenGL headers
46 namespace TizenPlatform
48 class TizenPlatformAbstraction;
60 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_APPLICATION, true);
62 ApplicationPtr Application::gPreInitializedApplication(NULL);
64 ApplicationPtr Application::New(
67 const std::string& stylesheet,
68 Dali::Application::WINDOW_MODE windowMode,
69 const PositionSize& positionSize,
70 Framework::Type applicationType,
73 ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType, type));
77 void Application::PreInitialize(int* argc, char** argv[])
79 if(!gPreInitializedApplication)
81 Dali::TextAbstraction::FontClientPreInitialize();
83 gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL);
84 gPreInitializedApplication->CreateWindow(); // Only create window
85 gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED;
89 Application::Application(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type)
96 mLanguageChangedSignal(),
97 mRegionChangedSignal(),
100 mCommandLineOptions(nullptr),
101 mAdaptorBuilder(nullptr),
104 mMainWindowMode(windowMode),
106 mStylesheet(stylesheet),
107 mEnvironmentOptions(),
108 mWindowPositionSize(positionSize),
109 mLaunchpadState(Launchpad::NONE),
110 mDefaultWindowType(type),
113 // Get mName from environment options
114 mMainWindowName = mEnvironmentOptions.GetWindowName();
115 if(mMainWindowName.empty() && argc && (*argc > 0))
117 // Set mName from command-line args if environment option not set
118 mMainWindowName = (*argv)[0];
121 mCommandLineOptions = new CommandLineOptions(argc, argv);
122 mFramework = new Framework(*this, argc, argv, applicationType);
123 mUseRemoteSurface = (applicationType == Framework::WATCH);
126 Application::~Application()
128 SingletonService service = SingletonService::Get();
129 // Note this can be false i.e. if Application has never created a Core instance
132 service.UnregisterAll();
137 delete mAdaptorBuilder;
138 delete mCommandLineOptions;
142 void Application::StoreWindowPositionSize(PositionSize positionSize)
144 mWindowPositionSize = positionSize;
147 void Application::ChangePreInitializedWindowSize()
149 int screenWidth, screenHeight;
150 Dali::Internal::Adaptor::WindowSystem::GetScreenSize(screenWidth, screenHeight);
152 if(mWindowPositionSize != PositionSize(0, 0, 0, 0))
154 Dali::DevelWindow::SetPositionSize(mMainWindow, mWindowPositionSize);
156 else if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
158 // Command line options override environment options and full screen
159 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
160 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
161 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
163 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
165 // Environment options override full screen functionality if command line arguments not provided
166 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
167 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
168 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
170 else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height)
172 //Some apps can receive screen size differently after launching by specifying size in manifest.
173 mWindowPositionSize.width = screenWidth;
174 mWindowPositionSize.height = screenHeight;
175 mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height));
179 void Application::CreateWindow()
181 if(mWindowPositionSize.width == 0 && mWindowPositionSize.height == 0)
183 if(mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
185 // Command line options override environment options and full screen
186 mWindowPositionSize.width = mCommandLineOptions->stageWidth;
187 mWindowPositionSize.height = mCommandLineOptions->stageHeight;
189 else if(mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight())
191 // Environment options override full screen functionality if command line arguments not provided
192 mWindowPositionSize.width = mEnvironmentOptions.GetWindowWidth();
193 mWindowPositionSize.height = mEnvironmentOptions.GetWindowHeight();
197 const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
199 Internal::Adaptor::Window* window = Internal::Adaptor::Window::New(mWindowPositionSize, mMainWindowName, windowClassName, mDefaultWindowType, mMainWindowMode == Dali::Application::TRANSPARENT);
200 mMainWindow = Dali::Window(window);
202 // Quit the application when the window is closed
203 GetImplementation(mMainWindow).DeleteRequestSignal().Connect(mSlotDelegate, &Application::Quit);
206 void Application::CreateAdaptor()
208 DALI_ASSERT_ALWAYS(mMainWindow && "Window required to create adaptor");
210 auto graphicsFactory = mAdaptorBuilder->GetGraphicsFactory();
212 Integration::SceneHolder sceneHolder = Integration::SceneHolder(&Dali::GetImplementation(mMainWindow));
214 mAdaptor = Adaptor::New(graphicsFactory, sceneHolder, &mEnvironmentOptions);
216 Adaptor::GetImplementation(*mAdaptor).SetUseRemoteSurface(mUseRemoteSurface);
219 void Application::CreateAdaptorBuilder()
221 mAdaptorBuilder = new AdaptorBuilder(mEnvironmentOptions);
224 void Application::MainLoop()
226 // Run the application
230 void Application::Lower()
232 // Lower the application without quitting it.
236 void Application::Quit()
238 // Actually quit the application.
239 // Force a call to Quit even if adaptor is not running.
240 Internal::Adaptor::Adaptor::GetImplementation(*mAdaptor).AddIdle(MakeCallback(this, &Application::QuitFromMainLoop), false, true);
243 void Application::QuitFromMainLoop()
245 Accessibility::Bridge::GetCurrentBridge()->Terminate();
250 // This will trigger OnTerminate(), below, after the main loop has completed.
253 void Application::OnInit()
255 mFramework->AddAbortCallback(MakeCallback(this, &Application::QuitFromMainLoop));
257 CreateAdaptorBuilder();
258 // If an application was pre-initialized, a window was made in advance
259 if(mLaunchpadState == Launchpad::NONE)
266 if(mLaunchpadState == Launchpad::PRE_INITIALIZED)
268 ChangePreInitializedWindowSize();
272 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_ADAPTOR_START");
274 DALI_TRACE_END(gTraceFilter, "DALI_APP_ADAPTOR_START");
275 Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
277 if(!mStylesheet.empty())
279 Dali::StyleMonitor::Get().SetTheme(mStylesheet);
282 // Wire up the LifecycleController
283 Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
285 InitSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnInit);
286 TerminateSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnTerminate);
287 PauseSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnPause);
288 ResumeSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnResume);
289 ResetSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnReset);
290 LanguageChangedSignal().Connect(&GetImplementation(lifecycleController), &LifecycleController::OnLanguageChanged);
292 Dali::Application application(this);
294 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
295 mInitSignal.Emit(application);
296 DALI_TRACE_END(gTraceFilter, "DALI_APP_EMIT_INIT_SIGNAL");
298 mAdaptor->NotifySceneCreated();
301 void Application::OnTerminate()
303 // We've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
304 // delete the window as ecore_x has been destroyed by AppCore
306 Dali::Application application(this);
307 mTerminateSignal.Emit(application);
311 // Ensure that the render-thread is not using the surface(window) after we delete it
315 mMainWindow.Reset(); // This only resets (clears) the default Window
318 void Application::OnPause()
320 // A DALi app should handle Pause/Resume events.
321 // DALi just delivers the framework Pause event to the application, but not actually pause DALi core.
322 // Pausing DALi core only occurs on the Window Hidden framework event
323 Dali::Application application(this);
324 mPauseSignal.Emit(application);
327 void Application::OnResume()
329 // Emit the signal first so the application can queue any messages before we do an update/render
330 // This ensures we do not just redraw the last frame before pausing if that's not required
331 Dali::Application application(this);
332 mResumeSignal.Emit(application);
334 // DALi just delivers the framework Resume event to the application.
335 // Resuming DALi core only occurs on the Window Show framework event
337 // Trigger processing of events queued up while paused
338 CoreEventInterface& coreEventInterface = Internal::Adaptor::Adaptor::GetImplementation(GetAdaptor());
339 coreEventInterface.ProcessCoreEvents();
342 void Application::OnReset()
345 * usually, reset callback was called when a caller request to launch this application via aul.
346 * because Application class already handled initialization in OnInit(), OnReset do nothing.
348 Dali::Application application(this);
349 mResetSignal.Emit(application);
352 void Application::OnAppControl(void* data)
354 Dali::Application application(this);
355 mAppControlSignal.Emit(application, data);
358 void Application::OnLanguageChanged()
360 mAdaptor->NotifyLanguageChanged();
361 Dali::Application application(this);
362 mLanguageChangedSignal.Emit(application);
365 void Application::OnRegionChanged()
367 Dali::Application application(this);
368 mRegionChangedSignal.Emit(application);
371 void Application::OnBatteryLow(Dali::DeviceStatus::Battery::Status status)
373 Dali::Application application(this);
374 mLowBatterySignal.Emit(status);
377 void Application::OnMemoryLow(Dali::DeviceStatus::Memory::Status status)
379 Dali::Application application(this);
380 mLowMemorySignal.Emit(status);
383 void Application::OnSurfaceCreated(Any newSurface)
385 void* newWindow = AnyCast<void*>(newSurface);
386 void* oldWindow = AnyCast<void*>(mMainWindow.GetNativeHandle());
387 if(oldWindow != newWindow)
389 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
390 std::unique_ptr<WindowRenderSurface> newSurfacePtr = renderSurfaceFactory->CreateWindowRenderSurface(PositionSize(), newSurface, true);
392 mAdaptor->ReplaceSurface(mMainWindow, *newSurfacePtr.release());
396 void Application::OnSurfaceDestroyed(Any surface)
400 bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue)
402 return mAdaptor->AddIdle(callback, hasReturnValue);
405 std::string Application::GetRegion() const
407 return mFramework->GetRegion();
410 std::string Application::GetLanguage() const
412 return mFramework->GetLanguage();
415 Dali::ObjectRegistry Application::GetObjectRegistry() const
417 Dali::ObjectRegistry objectRegistry;
420 objectRegistry = mAdaptor->GetObjectRegistry();
422 return objectRegistry;
425 Dali::Adaptor& Application::GetAdaptor()
430 Dali::Window Application::GetWindow()
435 std::string Application::GetResourcePath()
437 return Internal::Adaptor::Framework::GetResourcePath();
440 std::string Application::GetDataPath()
442 return Internal::Adaptor::Framework::GetDataPath();
445 void Application::SetStyleSheet(const std::string& stylesheet)
447 mStylesheet = stylesheet;
450 void Application::SetCommandLineOptions(int* argc, char** argv[])
452 delete mCommandLineOptions;
454 mCommandLineOptions = new CommandLineOptions(argc, argv);
456 mFramework->SetCommandLineOptions(argc, argv);
459 void Application::SetDefaultWindowType(WindowType type)
461 mDefaultWindowType = type;
462 mMainWindow.SetType(type);
465 ApplicationPtr Application::GetPreInitializedApplication()
467 // Reset the handle to decrease the reference count
468 ApplicationPtr application = gPreInitializedApplication;
469 gPreInitializedApplication.Reset();
474 } // namespace Adaptor
476 } // namespace Internal