/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
-#include <style-monitor.h>
// INTERNAL INCLUDES
+#include <style-monitor.h>
#include <command-line-options.h>
#include <common/adaptor-impl.h>
+#include <singleton-service-impl.h>
+#include <lifecycle-controller-impl.h>
+
+// CONDITIONAL INCLUDES
+#ifdef DALI_ELDBUS_AVAILABLE
+#include <Eldbus.h>
+#endif // DALI_ELDBUS_AVAILABLE
namespace Dali
{
-namespace SlpPlatform
+namespace TizenPlatform
{
-class SlpPlatformAbstraction;
+class TizenPlatformAbstraction;
}
namespace Integration
namespace Adaptor
{
+#if defined(DEBUG_ENABLED)
namespace
{
-// Defaults taken from H2 device
-const unsigned int DEFAULT_WINDOW_WIDTH = 480;
-const unsigned int DEFAULT_WINDOW_HEIGHT = 800;
-const float DEFAULT_HORIZONTAL_DPI = 220;
-const float DEFAULT_VERTICAL_DPI = 217;
-
-boost::thread_specific_ptr<Application> gThreadLocalApplication;
-}
+Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New( Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS" );
+} // anonymous namespace
+#endif
ApplicationPtr Application::New(
int* argc,
char **argv[],
- const std::string& name,
- const DeviceLayout& baseLayout,
- Dali::Application::WINDOW_MODE windowMode)
+ const std::string& stylesheet,
+ Dali::Application::WINDOW_MODE windowMode,
+ Framework::Type applicationType)
{
- ApplicationPtr application ( new Application (argc, argv, name, baseLayout, windowMode ) );
+ ApplicationPtr application ( new Application (argc, argv, stylesheet, windowMode, applicationType ) );
return application;
}
-Application::Application(
- int* argc,
- char** argv[],
- const std::string& name,
- const DeviceLayout& baseLayout,
- Dali::Application::WINDOW_MODE windowMode)
-: mFramework(NULL),
- mCommandLineOptions(NULL),
- mAdaptor(NULL),
+Application::Application( int* argc, char** argv[], const std::string& stylesheet,
+ Dali::Application::WINDOW_MODE windowMode, Framework::Type applicationType )
+: mInitSignal(),
+ mTerminateSignal(),
+ mPauseSignal(),
+ mResumeSignal(),
+ mResetSignal(),
+ mResizeSignal(),
+ mAppControlSignal(),
+ mLanguageChangedSignal(),
+ mRegionChangedSignal(),
+ mBatteryLowSignal(),
+ mMemoryLowSignal(),
+ mEventLoop( NULL ),
+ mFramework( NULL ),
+ mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ),
+ mCommandLineOptions( NULL ),
+ mSingletonService( SingletonService::New() ),
+ mAdaptor( NULL ),
mWindow(),
mWindowMode( windowMode ),
- mName(name),
- mInitialized(false),
- mBaseLayout(baseLayout),
+ mName(),
+ mStylesheet( stylesheet ),
+ mEnvironmentOptions(),
mSlotDelegate( this )
{
- // make sure we don't create the local thread application instance twice
- DALI_ASSERT_ALWAYS(gThreadLocalApplication.get() == NULL && "Cannot create more than one Application per thread" );
-
- // reset is used to store a new value associated with this thread
- gThreadLocalApplication.reset(this);
+ // Get mName from environment options
+ mName = mEnvironmentOptions.GetWindowName();
+ if( mName.empty() && argc && ( *argc > 0 ) )
+ {
+ // Set mName from command-line args if environment option not set
+ mName = (*argv)[0];
+ }
mCommandLineOptions = new CommandLineOptions(argc, argv);
-
- mFramework = new Framework(*this, argc, argv, name);
+ mFramework = new Framework( *this, argc, argv, applicationType );
+ mUseRemoteSurface = (applicationType == Framework::WATCH);
}
Application::~Application()
{
+ mSingletonService.UnregisterAll();
+
delete mFramework;
delete mCommandLineOptions;
delete mAdaptor;
+
+#ifdef DALI_ELDBUS_AVAILABLE
+ // Shutdown ELDBus.
+ DALI_LOG_INFO( gDBusLogging, Debug::General, "Shutting down DBus\n" );
+ eldbus_shutdown();
+#endif
+
mWindow.Reset();
- gThreadLocalApplication.release();
}
void Application::CreateWindow()
{
-#ifndef __arm__
- PositionSize windowPosition(0, 0, DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT);
-#else
- PositionSize windowPosition(0, 0, 0, 0); // this will use full screen
-#endif
- if (mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0)
+ PositionSize windowPosition(0, 0, 0, 0); // this will use full screen
+
+ if( mCommandLineOptions->stageWidth > 0 && mCommandLineOptions->stageHeight > 0 )
{
- // let the command line options over ride
- windowPosition = PositionSize(0,0,mCommandLineOptions->stageWidth,mCommandLineOptions->stageHeight);
+ // Command line options override environment options and full screen
+ windowPosition = PositionSize( 0, 0, mCommandLineOptions->stageWidth, mCommandLineOptions->stageHeight );
}
+ else if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
+ {
+ // Environment options override full screen functionality if command line arguments not provided
+ windowPosition = PositionSize( 0, 0, mEnvironmentOptions.GetWindowWidth(), mEnvironmentOptions.GetWindowHeight() );
+ }
+
+ const std::string& windowClassName = mEnvironmentOptions.GetWindowClassName();
+ mWindow = Dali::Window::New( windowPosition, mName, windowClassName, mWindowMode == Dali::Application::TRANSPARENT );
- mWindow = Dali::Window::New( windowPosition, mName, mWindowMode == Dali::Application::TRANSPARENT );
+ // Quit the application when the window is closed
+ GetImplementation( mWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &Application::Quit );
}
void Application::CreateAdaptor()
{
DALI_ASSERT_ALWAYS( mWindow && "Window required to create adaptor" );
- mAdaptor = &Dali::Adaptor::New( mWindow, mBaseLayout);
-
- // Allow DPI to be overridden from command line.
- unsigned int hDPI=DEFAULT_HORIZONTAL_DPI;
- unsigned int vDPI=DEFAULT_VERTICAL_DPI;
-
- std::string dpiStr = mCommandLineOptions->stageDPI;
- if(!dpiStr.empty())
- {
- sscanf(dpiStr.c_str(), "%ux%u", &hDPI, &vDPI);
- }
- Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetDpi(hDPI, vDPI);
+ mAdaptor = Dali::Internal::Adaptor::Adaptor::New( mWindow, mContextLossConfiguration, &mEnvironmentOptions );
mAdaptor->ResizedSignal().Connect( mSlotDelegate, &Application::OnResize );
+
+ Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( mUseRemoteSurface );
}
-void Application::MainLoop()
+void Application::MainLoop(Dali::Configuration::ContextLoss configuration)
{
+ mContextLossConfiguration = configuration;
+
// Run the application
mFramework->Run();
}
void Application::Quit()
{
// Actually quit the application.
- AddIdle(boost::bind(&Application::QuitFromMainLoop, this));
+ AddIdle( MakeCallback( this, &Application::QuitFromMainLoop ) );
}
void Application::QuitFromMainLoop()
{
mAdaptor->Stop();
- Dali::Application application(this);
- mTerminateSignalV2.Emit( application );
-
mFramework->Quit();
// This will trigger OnTerminate(), below, after the main loop has completed.
- mInitialized = false;
}
void Application::OnInit()
{
- mFramework->AddAbortCallback(boost::bind(&Application::QuitFromMainLoop, this));
+ mFramework->AddAbortCallback( MakeCallback( this, &Application::QuitFromMainLoop ) );
CreateWindow();
- CreateAdaptor();
- // Run the adaptor
+#ifdef DALI_ELDBUS_AVAILABLE
+ // Initialize ElDBus.
+ DALI_LOG_INFO( gDBusLogging, Debug::General, "Starting DBus Initialization\n" );
+ eldbus_init();
+#endif
+
+ // Start the adaptor
+ CreateAdaptor();
mAdaptor->Start();
// Check if user requires no vsyncing and set on X11 Adaptor
if (mCommandLineOptions->noVSyncOnRender)
{
- Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).DisableVSync();
+ mAdaptor->SetUseHardwareVSync(false);
}
Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetStereoBase( mCommandLineOptions->stereoBase );
Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetViewMode( viewMode );
}
- mInitialized = true;
+ if( ! mStylesheet.empty() )
+ {
+ Dali::StyleMonitor::Get().SetTheme( mStylesheet );
+ }
+
+ // Wire up the LifecycleController
+ Dali::LifecycleController lifecycleController = Dali::LifecycleController::Get();
- // in default, auto hide indicator mode
- mWindow.ShowIndicator(Dali::Window::AUTO);
+ InitSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnInit );
+ TerminateSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnTerminate );
+ PauseSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnPause );
+ ResumeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResume );
+ ResetSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnReset );
+ ResizeSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnResize );
+ LanguageChangedSignal().Connect( &GetImplementation( lifecycleController ), &LifecycleController::OnLanguageChanged );
Dali::Application application(this);
- mInitSignalV2.Emit( application );
+ mInitSignal.Emit( application );
+
+ mAdaptor->NotifySceneCreated();
}
void Application::OnTerminate()
// we've been told to quit by AppCore, ecore_x_destroy has been called, need to quit synchronously
// delete the window as ecore_x has been destroyed by AppCore
+ Dali::Application application(this);
+ mTerminateSignal.Emit( application );
+
+ if( mAdaptor )
+ {
+ // Ensure that the render-thread is not using the surface(window) after we delete it
+ mAdaptor->Stop();
+ }
+
mWindow.Reset();
- mInitialized = false;
}
void Application::OnPause()
{
mAdaptor->Pause();
Dali::Application application(this);
- mPauseSignalV2.Emit( application );
+ mPauseSignal.Emit( application );
}
void Application::OnResume()
{
- mAdaptor->Resume();
+ // Emit the signal first so the application can queue any messages before we do an update/render
+ // This ensures we do not just redraw the last frame before pausing if that's not required
Dali::Application application(this);
- mResumeSignalV2.Emit( application );
+ mResumeSignal.Emit( application );
+ mAdaptor->Resume();
}
void Application::OnReset()
* because Application class already handled initialization in OnInit(), OnReset do nothing.
*/
Dali::Application application(this);
- mResetSignalV2.Emit( application );
+ mResetSignal.Emit( application );
+}
- mWindow.Raise();
+void Application::OnAppControl(void *data)
+{
+ Dali::Application application(this);
+ mAppControlSignal.Emit( application , data );
}
void Application::OnLanguageChanged()
{
mAdaptor->NotifyLanguageChanged();
+ Dali::Application application(this);
+ mLanguageChangedSignal.Emit( application );
}
-void Application::OnResize(Dali::Adaptor& adaptor)
+void Application::OnRegionChanged()
{
Dali::Application application(this);
- mResizeSignalV2.Emit( application );
+ mRegionChangedSignal.Emit( application );
}
-bool Application::AddIdle(boost::function<void(void)> callBack)
+void Application::OnBatteryLow()
{
- return mAdaptor->AddIdle(callBack);
+ Dali::Application application(this);
+ mBatteryLowSignal.Emit( application );
}
-Dali::Adaptor& Application::GetAdaptor()
+void Application::OnMemoryLow()
{
- return *mAdaptor;
+ Dali::Application application(this);
+ mMemoryLowSignal.Emit( application );
}
-Dali::Window Application::GetWindow()
+void Application::OnResize(Dali::Adaptor& adaptor)
{
- return mWindow;
+ Dali::Application application(this);
+ mResizeSignal.Emit( application );
}
-Dali::Application Application::Get()
+bool Application::AddIdle( CallbackBase* callback )
{
- DALI_ASSERT_ALWAYS( gThreadLocalApplication.get() != NULL && "Application not instantiated" );
-
- Dali::Application application(gThreadLocalApplication.get());
-
- return application;
+ return mAdaptor->AddIdle( callback );
}
-const std::string& Application::GetTheme()
+Dali::Adaptor& Application::GetAdaptor()
{
- return Dali::StyleMonitor::Get().GetTheme();
+ return *mAdaptor;
}
-void Application::SetTheme(const std::string& themeFilePath)
+Dali::Window Application::GetWindow()
{
- return Dali::StyleMonitor::Get().SetTheme(themeFilePath);
+ return mWindow;
}
// Stereoscopy
return Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).GetStereoBase();
}
+
+void Application::ReplaceWindow(PositionSize windowPosition, const std::string& name)
+{
+ Dali::Window newWindow = Dali::Window::New( windowPosition, name, mWindowMode == Dali::Application::TRANSPARENT );
+ Window& windowImpl = GetImplementation(newWindow);
+ windowImpl.SetAdaptor(*mAdaptor);
+ newWindow.ShowIndicator(Dali::Window::INVISIBLE);
+ Dali::RenderSurface* renderSurface = windowImpl.GetSurface();
+
+ Any nativeWindow = newWindow.GetNativeHandle();
+ Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SurfaceSizeChanged( windowPosition );
+ Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).ReplaceSurface(nativeWindow, *renderSurface);
+ mWindow = newWindow;
+}
+
} // namespace Adaptor
} // namespace Internal