From 809f16b877c358e8fd7a109ba3f0b2893a39afbb Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Fri, 1 Sep 2017 09:57:36 +0900 Subject: [PATCH] [Tizen] Create Widget Application Change-Id: I06925a3174c3a5797606e735cad3d793fc515a59 --- adaptors/common/adaptor-impl.cpp | 1 - adaptors/common/framework.h | 3 +- adaptors/tizen/framework-tizen.cpp | 656 ++++++++++++++++++++- adaptors/widget/file.list | 21 + .../widget/internal/widget-application-impl.cpp | 241 ++++++++ adaptors/widget/internal/widget-application-impl.h | 259 ++++++++ adaptors/widget/internal/widget-data-impl.cpp | 89 +++ adaptors/widget/internal/widget-data-impl.h | 156 +++++ adaptors/widget/internal/widget-impl.cpp | 457 ++++++++++++++ adaptors/widget/internal/widget-impl.h | 180 ++++++ adaptors/widget/widget-application.cpp | 113 ++++ adaptors/widget/widget-application.h | 157 +++++ adaptors/widget/widget-data.cpp | 97 +++ adaptors/widget/widget-data.h | 131 ++++ adaptors/widget/widget.cpp | 92 +++ adaptors/widget/widget.h | 164 ++++++ build/tizen/adaptor/Makefile.am | 47 +- build/tizen/adaptor/configure.ac | 5 + packaging/dali-adaptor.spec | 3 + 19 files changed, 2861 insertions(+), 11 deletions(-) create mode 100644 adaptors/widget/file.list create mode 100644 adaptors/widget/internal/widget-application-impl.cpp create mode 100644 adaptors/widget/internal/widget-application-impl.h create mode 100644 adaptors/widget/internal/widget-data-impl.cpp create mode 100644 adaptors/widget/internal/widget-data-impl.h create mode 100644 adaptors/widget/internal/widget-impl.cpp create mode 100644 adaptors/widget/internal/widget-impl.h create mode 100644 adaptors/widget/widget-application.cpp create mode 100644 adaptors/widget/widget-application.h create mode 100644 adaptors/widget/widget-data.cpp create mode 100644 adaptors/widget/widget-data.h create mode 100644 adaptors/widget/widget.cpp create mode 100644 adaptors/widget/widget.h diff --git a/adaptors/common/adaptor-impl.cpp b/adaptors/common/adaptor-impl.cpp index 08fe0e0..2eb5e82 100644 --- a/adaptors/common/adaptor-impl.cpp +++ b/adaptors/common/adaptor-impl.cpp @@ -85,7 +85,6 @@ Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Con Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions ) { Any winId = window.GetNativeHandle(); - Window& windowImpl = Dali::GetImplementation(window); Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions ); windowImpl.SetAdaptor(*adaptor); diff --git a/adaptors/common/framework.h b/adaptors/common/framework.h index 6037d57..36115f2 100644 --- a/adaptors/common/framework.h +++ b/adaptors/common/framework.h @@ -51,7 +51,8 @@ public: enum Type { NORMAL, ///< normal appFramework - WATCH ///< watch appFramework + WATCH, ///< watch appFramework + WIDGET ///< widget appFramework }; /** diff --git a/adaptors/tizen/framework-tizen.cpp b/adaptors/tizen/framework-tizen.cpp index f437a92..e9c3ac1 100644 --- a/adaptors/tizen/framework-tizen.cpp +++ b/adaptors/tizen/framework-tizen.cpp @@ -19,14 +19,26 @@ #include "framework.h" // EXTERNAL INCLUDES +#include +#include #include +#include #include #include #include +#include #include - +#include #include -#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#include +#pragma GCC diagnostic pop // CONDITIONAL INCLUDES #ifdef APPCORE_WATCH_AVAILABLE @@ -44,6 +56,9 @@ // INTERNAL INCLUDES #include +#include +#include +#include namespace Dali { @@ -54,13 +69,20 @@ namespace Internal namespace Adaptor { -#if defined(DEBUG_ENABLED) namespace { +#if defined(DEBUG_ENABLED) Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New( Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS" ); -} // anonymous namespace #endif +// TODO: remove these global variables +static bool gForegroundState; +static char* gAppId; +static char* gPackageId; +static char* gViewerEndpoint; + +} // anonymous namespace + namespace AppCore { @@ -159,6 +181,7 @@ struct Framework::Impl #endif { mFramework = static_cast(data); + gForegroundState = false; #ifndef APPCORE_WATCH_AVAILABLE if ( type == WATCH ) @@ -188,6 +211,10 @@ struct Framework::Impl { ret = AppNormalMain(); } + else if(mApplicationType == WIDGET) + { + ret = AppWidgetMain(); + } else { ret = AppWatchMain(); @@ -201,6 +228,10 @@ struct Framework::Impl { AppNormalExit(); } + else if(mApplicationType == WIDGET) + { + AppWidgetExit(); + } else { AppWatchExit(); @@ -215,6 +246,7 @@ struct Framework::Impl Framework* mFramework; AppCore::AppEventHandlerPtr handlers[5]; + #ifdef APPCORE_WATCH_AVAILABLE watch_app_lifecycle_callback_s mWatchCallback; app_event_handler_h watchHandlers[5]; @@ -424,6 +456,619 @@ struct Framework::Impl appcore_ui_base_exit(); } + void AppWidgetExit() + { + if( !IsWidgetFeatureEnabled() ) + { + DALI_LOG_ERROR("widget feature is not supported"); + return; + } + + appcore_multiwindow_base_exit(); + aul_widget_notify_exit(); + } + + int AppWidgetMain() + { + if( !IsWidgetFeatureEnabled() ) + { + DALI_LOG_ERROR("widget feature is not supported"); + return 0; + } + + AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework); + AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework); + AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework); + AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework); + AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework); + + appcore_multiwindow_base_ops ops = appcore_multiwindow_base_get_default_ops(); + + /* override methods */ + ops.base.create = WidgetAppCreate; + ops.base.control = WidgetAppControl; + ops.base.terminate = WidgetAppTerminate; + ops.base.receive = WidgetAppReceive; + ops.base.init = AppInit; + ops.base.finish = AppFinish; + ops.base.run = AppRun; + ops.base.exit = AppExit; + + bundle *bundleFromArgv = bundle_import_from_argv(*mFramework->mArgc, *mFramework->mArgv); + + char* viewerEndpoint = NULL; + + if (bundleFromArgv) + { + bundle_get_str(bundleFromArgv, "__WIDGET_ENDPOINT__", &viewerEndpoint); + if (viewerEndpoint) + { + gViewerEndpoint = strdup(viewerEndpoint); + } + else + { + DALI_LOG_ERROR("endpoint is missing"); + return 0; + } + + bundle_free(bundleFromArgv); + } + else + { + DALI_LOG_ERROR("failed to get launch argv"); + return 0; + } + + appcore_multiwindow_base_init(ops, *mFramework->mArgc, *mFramework->mArgv, mFramework); + appcore_multiwindow_base_fini(); + return TIZEN_ERROR_NONE; + } + + static void WidgetAppPoweroff(keynode_t *key, void *data) + { + int val; + + val = vconf_keynode_get_int(key); + switch (val) { + case VCONFKEY_SYSMAN_POWER_OFF_DIRECT: + case VCONFKEY_SYSMAN_POWER_OFF_RESTART: + { + static_cast(data)->AppWidgetExit(); + break; + } + case VCONFKEY_SYSMAN_POWER_OFF_NONE: + case VCONFKEY_SYSMAN_POWER_OFF_POPUP: + default: + break; + } + } + + static int WidgetAppCreate(void *data) + { + char pkgid[256] = {0, }; + + appcore_multiwindow_base_on_create(); + app_get_id(&gAppId); + + if(aul_app_get_pkgid_bypid(getpid(), pkgid, sizeof(pkgid)) == 0) + { + gPackageId = strdup(pkgid); + } + + if(!gPackageId || !gAppId) + { + DALI_LOG_ERROR("package_id is NULL"); + return -1; + } + + screen_connector_provider_init(); + vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, WidgetAppPoweroff, data); + + return static_cast( static_cast(data)->Create() ); + } + + static int WidgetAppTerminate(void *data) + { + Observer *observer = &static_cast(data)->mObserver; + + observer->OnTerminate(); + + vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, WidgetAppPoweroff); + screen_connector_provider_fini(); + + appcore_multiwindow_base_on_terminate(); + return 0; + } + + static void WidgetAppInstResume(const char* classId, const char* id, appcore_multiwindow_base_instance_h context, void* data) + { + WidgetInstanceResume(classId, id, static_cast(data)); + } + + static void WidgetInstanceResume(const char* classId, const char* id, bundle* bundleData) + { + appcore_multiwindow_base_instance_h context; + + context = appcore_multiwindow_base_instance_find(id); + + if(!context) + { + DALI_LOG_ERROR("context not found: %s", id); + return; + } + + appcore_multiwindow_base_instance_resume(context); + + SendUpdateStatus(classId, id, AUL_WIDGET_INSTANCE_EVENT_RESUME, NULL); + + if(!gForegroundState) + { + aul_send_app_status_change_signal( getpid(), gAppId, gPackageId, "fg", "widgetapp" ); + gForegroundState = true; + } + + return; + } + + static int SendUpdateStatus(const char* classId, const char* instanceId, int status, bundle* extra ) + { + bundle* bundleData; + int lifecycle = -1; + bundle_raw *raw = NULL; + int length; + + bundleData = bundle_create(); + if(!bundleData) + { + DALI_LOG_ERROR("out of memory"); + return -1; + } + + bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId); + bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId); + bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int)); + + if(extra) + { + bundle_encode(extra, &raw, &length); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + bundle_add_str(bundleData, "__WIDGET_CONTENT_INFO__", (const char*)raw); +#pragma GCC diagnostic pop + + aul_widget_instance_add(classId, instanceId); + } + + aul_app_com_send(gViewerEndpoint, bundleData); + + switch(status) + { + case AUL_WIDGET_INSTANCE_EVENT_CREATE: + lifecycle = Dali::Widget::WidgetLifecycleEventType::CREATE; + break; + case AUL_WIDGET_INSTANCE_EVENT_DESTROY: + lifecycle = Dali::Widget::WidgetLifecycleEventType::DESTROY; + break; + case AUL_WIDGET_INSTANCE_EVENT_PAUSE: + lifecycle = Dali::Widget::WidgetLifecycleEventType::PAUSE; + break; + case AUL_WIDGET_INSTANCE_EVENT_RESUME: + lifecycle = Dali::Widget::WidgetLifecycleEventType::RESUME; + break; + } + + if (lifecycle > -1) + SendLifecycleEvent(classId, instanceId, lifecycle); + + bundle_free(bundleData); + if (raw) + free(raw); + + return 0; + } + + static int SendLifecycleEvent(const char* classId, const char* instanceId, int status) + { + bundle* bundleData = bundle_create(); + int ret; + + if (bundleData == NULL) + { + DALI_LOG_ERROR("out of memory"); + return -1; + } + + bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId); + bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId); + bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int)); + bundle_add_str(bundleData, AUL_K_PKGID, gPackageId); + + ret = aul_app_com_send("widget.status", bundleData); + + if (ret < 0) + DALI_LOG_ERROR("send lifecycle error:%d", ret); + + bundle_free(bundleData); + + return ret; + } + + static int WidgetAppReceive(aul_type type, bundle *bundleData, void *data) + { + appcore_multiwindow_base_on_receive(type, bundleData); + + switch(type) + { + case AUL_RESUME: + { + appcore_multiwindow_base_instance_foreach_full(WidgetAppInstResume, bundleData); + break; + } + case AUL_TERMINATE: + { + static_cast(data)->AppWidgetExit(); + break; + } + case AUL_WIDGET_CONTENT: + { + GetContent(bundleData); + break; + } + default: + break; + } + return 0; + } + + static void GetContent( bundle* bundleData ) + { + char* instanceId = NULL; + appcore_multiwindow_base_instance_h context; + const appcore_multiwindow_base_class *cls; + Internal::Adaptor::Widget *widgetInstance; + + bundle_get_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, &instanceId); + if(!instanceId) + { + DALI_LOG_ERROR("instance id is NULL"); + return; + } + + context = static_cast(appcore_multiwindow_base_instance_find(instanceId)); + if(!context) + { + DALI_LOG_ERROR("could not find widget obj: %s", instanceId); + return; + } + + cls = appcore_multiwindow_base_instance_get_class(context); + if(!cls) + { + DALI_LOG_ERROR("widget class is NULL"); + return; + } + + widgetInstance = static_cast(cls->data); + if(!widgetInstance) + { + DALI_LOG_ERROR("widget instance is NULL"); + return; + } + + Dali::WidgetData *widgetData = widgetInstance->FindWidgetData( instanceId ); + if(!widgetData) + { + DALI_LOG_ERROR("widget extra is NULL"); + return; + } + + char* widgetContent = widgetData->GetContent(); + if(widgetContent) + { + bundle_add_str(bundleData, AUL_K_WIDGET_CONTENT_INFO, widgetContent); + } + else + { + bundle_add_str(bundleData, AUL_K_WIDGET_CONTENT_INFO, ""); + } + } + + /** + * Called by AppCore when the application is launched from another module (e.g. homescreen). + * @param[in] b the bundle data which the launcher module sent + */ + static int WidgetAppControl(bundle* bundleData, void *data) + { + char *classId = NULL; + char *id = NULL; + char *operation = NULL; + + appcore_multiwindow_base_on_control(bundleData); + + bundle_get_str(bundleData, AUL_K_WIDGET_ID, &classId); + bundle_get_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, &id); + bundle_get_str(bundleData, "__WIDGET_OP__", &operation); + + if(!operation) + { + DALI_LOG_ERROR("operation is NULL"); + return 0; + } + + if(strcmp(operation, "create") == 0) + { + InstanceCreate( classId, id, bundleData ); + } + else if (strcmp(operation, "resize") == 0) + { + InstanceResize( classId, id, bundleData ); + } + else if (strcmp(operation, "update") == 0) + { + InstanceUpdate( classId, id, bundleData ); + } + else if (strcmp(operation, "destroy") == 0) + { + InstanceDestroy( classId, id, bundleData, data ); + } + else if (strcmp(operation, "resume") == 0) + { + InstanceResume( classId, id, bundleData ); + } + else if (strcmp(operation, "pause") == 0) + { + InstancePause( classId, id, bundleData ); + } + else if (strcmp(operation, "terminate") == 0) + { + InstanceDestroy( classId, id, bundleData, data ); + } + + return 0; + } + + static void InstanceCreate(const char* classId, const char* id, bundle* bundleData) + { + appcore_multiwindow_base_instance_run(classId, id, bundle_dup(bundleData)); + } + + static void InstanceResize(const char *classId, const char *id, bundle *bundleData) + { + appcore_multiwindow_base_instance_h context; + Internal::Adaptor::Widget *widgetInstance; + const appcore_multiwindow_base_class *cls; + char *remain = NULL; + char *widthStr = NULL; + char *heightStr = NULL; + uint32_t width = 0; + uint32_t height = 0; + + context = appcore_multiwindow_base_instance_find(id); + + if(!context) + { + DALI_LOG_ERROR("context not found: %s", id); + return; + } + + cls = appcore_multiwindow_base_instance_get_class(context); + if(!cls) + { + DALI_LOG_ERROR("widget class is NULL"); + return; + } + + widgetInstance = static_cast(cls->data); + if(!widgetInstance) + { + DALI_LOG_ERROR("widget instance is NULL"); + return; + } + + bundle_get_str(bundleData, "__WIDGET_WIDTH__", &widthStr); + bundle_get_str(bundleData, "__WIDGET_HEIGHT__", &heightStr); + + if(widthStr) + width = static_cast(g_ascii_strtoll(widthStr, &remain, 10)); + + if(heightStr) + height = static_cast(g_ascii_strtoll(heightStr, &remain, 10)); + + widgetInstance->OnResize( context, Dali::Widget::WindowSize(width,height) ); + } + + static void InstanceUpdate(const char* classId, const char* id, bundle* bundleData) + { + appcore_multiwindow_base_instance_h context; + + if(!id) + { + appcore_multiwindow_base_instance_foreach(classId, UpdateCallback, bundleData); + return; + } + + context = appcore_multiwindow_base_instance_find(id); + + if(!context) + { + DALI_LOG_ERROR("context not found: %s", id); + return; + } + + UpdateCallback(classId, id, context, bundleData); + } + + static void UpdateCallback(const char* classId, const char* id, appcore_multiwindow_base_instance_h context, void* data) + { + Internal::Adaptor::Widget *widgetInstance; + const appcore_multiwindow_base_class *cls; + bundle* content = NULL; + char* contentRaw = NULL; + char* forceStr = NULL; + int force; + bundle* bundleData = static_cast(data); + + if(!bundleData) + { + DALI_LOG_ERROR("bundle is NULL"); + return; + } + + cls = appcore_multiwindow_base_instance_get_class(context); + if(!cls) + { + DALI_LOG_ERROR("class is NULL"); + return; + } + + widgetInstance = static_cast(cls->data); + if(!widgetInstance) + { + DALI_LOG_ERROR("widget instance is NULL"); + return; + } + + bundle_get_str(bundleData, "__WIDGET_FORCE__", &forceStr); + + if(forceStr && strcmp(forceStr, "true") == 0) + { + force = 1; + } + else + { + force = 0; + } + + bundle_get_str(bundleData, "__WIDGET_CONTENT_INFO__", &contentRaw); + + if(contentRaw) + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + content = bundle_decode((const bundle_raw *)contentRaw, strlen(contentRaw)); +#pragma GCC diagnostic pop + + } + + widgetInstance->OnUpdate(context, content, force); + + if(content) + { + bundle_free(content); + } + } + + static void InstanceDestroy(const char* classId, const char* id, bundle* bundleData, void* data) + { + appcore_multiwindow_base_instance_h context; + + Internal::Adaptor::Widget *widgetInstance; + const appcore_multiwindow_base_class *cls; + + context = appcore_multiwindow_base_instance_find(id); + + if(!context) + { + DALI_LOG_ERROR("could not find widget obj: %s, clear amd info", id); + aul_widget_instance_del(classId, id); + return; + } + + cls = appcore_multiwindow_base_instance_get_class(context); + if(!cls) + { + DALI_LOG_ERROR("widget class is NULL"); + return; + } + + widgetInstance = static_cast(cls->data); + if(!widgetInstance) + { + DALI_LOG_ERROR("widget instance is NULL"); + return; + } + + Dali::WidgetData *widgetData = widgetInstance->FindWidgetData(id); + + widgetData->SetArgs( bundleData ); + appcore_multiwindow_base_instance_exit(context); + CheckEmptyInstance(data); + } + + static void CheckEmptyInstance(void* data) + { + int cnt = appcore_multiwindow_base_instance_get_cnt(); + + if(cnt == 0) + { + static_cast(data)->AppWidgetExit(); + } + } + + static void InstanceResume(const char* classId, const char* id, bundle* bundleData) + { + appcore_multiwindow_base_instance_h context; + + context = appcore_multiwindow_base_instance_find(id); + + if(!context) + { + DALI_LOG_ERROR("context not found: %s", id); + return; + } + + appcore_multiwindow_base_instance_resume(context); + + SendUpdateStatus(classId, id, AUL_WIDGET_INSTANCE_EVENT_RESUME, NULL); + if(!gForegroundState) + { + aul_send_app_status_change_signal(getpid(), gAppId, gPackageId, "fg", "widgetapp" ); + gForegroundState = true; + } + } + + static void InstancePause(const char* classId, const char* id, bundle* bundleData) + { + appcore_multiwindow_base_instance_h context; + + context = appcore_multiwindow_base_instance_find(id); + + if(!context) + { + DALI_LOG_ERROR("context not found: %s", id); + return; + } + + appcore_multiwindow_base_instance_pause(context); + + if(gForegroundState) + { + aul_send_app_status_change_signal(getpid(), gAppId, gPackageId, "bg", "widgetapp" ); + gForegroundState = false; + } + } + + static bool IsWidgetFeatureEnabled() + { + static bool feature = false; + static bool retrieved = false; + int ret; + + if(retrieved == true) + return feature; + + ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature); + if(ret != SYSTEM_INFO_ERROR_NONE) + { + DALI_LOG_ERROR("failed to get system info"); /* LCOV_EXCL_LINE */ + return false; /* LCOV_EXCL_LINE */ + } + + retrieved = true; + return feature; + } + + #ifdef APPCORE_WATCH_AVAILABLE static bool WatchAppCreate(int width, int height, void *data) { @@ -514,7 +1159,6 @@ struct Framework::Impl observer->OnResume(); } - #endif int AppWatchMain() @@ -577,7 +1221,6 @@ Framework::Framework( Framework::Observer& observer, int *argc, char ***argv, Ty } #ifdef DALI_ELDBUS_AVAILABLE // Initialize ElDBus. - DALI_LOG_INFO( gDBusLogging, Debug::General, "Starting DBus Initialization\n" ); eldbus_init(); #endif InitThreads(); @@ -594,7 +1237,6 @@ Framework::~Framework() #ifdef DALI_ELDBUS_AVAILABLE // Shutdown ELDBus. - DALI_LOG_INFO( gDBusLogging, Debug::General, "Shutting down DBus\n" ); eldbus_shutdown(); #endif diff --git a/adaptors/widget/file.list b/adaptors/widget/file.list new file mode 100644 index 0000000..e78631d --- /dev/null +++ b/adaptors/widget/file.list @@ -0,0 +1,21 @@ +# widget files + +adaptor_internal_widget_src_files = \ + $(adaptor_widget_api_dir)/internal/widget-data-impl.cpp \ + $(adaptor_widget_api_dir)/internal/widget-impl.cpp \ + $(adaptor_widget_api_dir)/internal/widget-application-impl.cpp + +adaptor_widget_src_files = \ + $(adaptor_widget_api_dir)/widget-data.cpp \ + $(adaptor_widget_api_dir)/widget.cpp \ + $(adaptor_widget_api_dir)/widget-application.cpp + +adaptor_internal_widget_header_files = \ + $(adaptor_widget_api_dir)/internal/widget-data-impl.h \ + $(adaptor_widget_api_dir)/internal/widget-impl.h \ + $(adaptor_widget_api_dir)/internal/widget-application-impl.h + +adaptor_widget_header_files = \ + $(adaptor_widget_api_dir)/widget-data.h \ + $(adaptor_widget_api_dir)/widget.h \ + $(adaptor_widget_api_dir)/widget-application.h diff --git a/adaptors/widget/internal/widget-application-impl.cpp b/adaptors/widget/internal/widget-application-impl.cpp new file mode 100644 index 0000000..0619203 --- /dev/null +++ b/adaptors/widget/internal/widget-application-impl.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "widget-application-impl.h" + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +namespace Dali +{ + +namespace TizenPlatform +{ +class TizenPlatformAbstraction; +} + +namespace Integration +{ +class Core; +} + +namespace Internal +{ + +namespace Adaptor +{ + +WidgetApplicationPtr WidgetApplication::New( + int* argc, + char **argv[], + const std::string& stylesheet) +{ + WidgetApplicationPtr widgetApplication( new WidgetApplication (argc, argv, stylesheet ) ); + return widgetApplication; +} + +WidgetApplication::WidgetApplication( int* argc, char** argv[], const std::string& stylesheet ) +: mInitSignal(), + mTerminateSignal(), + mLanguageChangedSignal(), + mRegionChangedSignal(), + mBatteryLowSignal(), + mMemoryLowSignal(), + mFramework( NULL ), + mContextLossConfiguration( Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS ), + mCommandLineOptions( NULL ), + mSingletonService( SingletonService::New() ), + mAdaptor( NULL ), + mName(), + mStylesheet( stylesheet ), + mEnvironmentOptions(), + mSlotDelegate( 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, Framework::WIDGET ); +} + +WidgetApplication::~WidgetApplication() +{ + mSingletonService.UnregisterAll(); + + delete mAdaptor; + delete mCommandLineOptions; + delete mFramework; +} + +void WidgetApplication::CreateAdaptor() +{ + mAdaptor = Dali::Internal::Adaptor::Adaptor::New( mWindow, mContextLossConfiguration, &mEnvironmentOptions ); + + Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetUseRemoteSurface( true ); +} + +void WidgetApplication::MainLoop() +{ + // Run the application + mFramework->Run(); +} + +void WidgetApplication::Quit() +{ + // Actually quit the application. + AddIdle( MakeCallback( this, &WidgetApplication::QuitFromMainLoop ) ); +} + +void WidgetApplication::QuitFromMainLoop() +{ + mAdaptor->Stop(); + + mFramework->Quit(); + // This will trigger OnTerminate(), below, after the main loop has completed. +} + +void WidgetApplication::DoInit() +{ + mWindow = Dali::Window::New( PositionSize(), "", mEnvironmentOptions.GetWindowClassName(), 1 ); + // Quit the application when the window is closed + mWindow.ShowIndicator(Dali::Window::IndicatorVisibleMode::INVISIBLE); + GetImplementation( mWindow ).DeleteRequestSignal().Connect( mSlotDelegate, &WidgetApplication::Quit ); + + CreateAdaptor(); + // Run the adaptor + mAdaptor->Start(); + + // Check if user requires no vsyncing and set Adaptor + if (mCommandLineOptions->noVSyncOnRender) + { + mAdaptor->SetUseHardwareVSync(false); + } + + Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetStereoBase( mCommandLineOptions->stereoBase ); + + if( ! mStylesheet.empty() ) + { + Dali::StyleMonitor::Get().SetTheme( mStylesheet ); + } +} + +void WidgetApplication::DoStart() +{ + mAdaptor->NotifySceneCreated(); +} + +void WidgetApplication::DoTerminate() +{ + if( mAdaptor ) + { + // Ensure that the render-thread is not using the surface(window) after we delete it + mAdaptor->Stop(); + } + + mWindow.Reset(); +} + +void WidgetApplication::DoLanguageChange() +{ + mAdaptor->NotifyLanguageChanged(); +} + +void WidgetApplication::OnInit() +{ + mFramework->AddAbortCallback( MakeCallback( this, &WidgetApplication::QuitFromMainLoop ) ); + DoInit(); + + Dali::WidgetApplication widgetApplication(this); + mInitSignal.Emit( widgetApplication ); + + DoStart(); +} + +void WidgetApplication::OnTerminate() +{ + Dali::WidgetApplication widgetApplication(this); + mTerminateSignal.Emit( widgetApplication ); + + DoTerminate(); +} + +void WidgetApplication::OnLanguageChanged() +{ + DoLanguageChange(); + + Dali::WidgetApplication widgetApplication(this); + mLanguageChangedSignal.Emit( widgetApplication ); +} + +void WidgetApplication::OnRegionChanged() +{ + Dali::WidgetApplication widgetApplication(this); + mRegionChangedSignal.Emit( widgetApplication ); +} + +void WidgetApplication::OnBatteryLow() +{ + Dali::WidgetApplication widgetApplication(this); + mBatteryLowSignal.Emit( widgetApplication ); +} + +void WidgetApplication::OnMemoryLow() +{ + Dali::WidgetApplication widgetApplication(this); + mMemoryLowSignal.Emit( widgetApplication ); +} + +bool WidgetApplication::AddIdle( CallbackBase* callback ) +{ + return mAdaptor->AddIdle( callback ); +} + +Dali::Window WidgetApplication::GetWindow() +{ + return mWindow; +} + +Dali::Adaptor& WidgetApplication::GetAdaptor() +{ + return *mAdaptor; +} + +std::string WidgetApplication::GetResourcePath() +{ + return Internal::Adaptor::Framework::GetResourcePath(); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali diff --git a/adaptors/widget/internal/widget-application-impl.h b/adaptors/widget/internal/widget-application-impl.h new file mode 100644 index 0000000..360ae97 --- /dev/null +++ b/adaptors/widget/internal/widget-application-impl.h @@ -0,0 +1,259 @@ +#ifndef __DALI_INTERNAL_WIDGET_APPLICATION_H__ +#define __DALI_INTERNAL_WIDGET_APPLICATION_H__ + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include + +#include +#include +#include + +namespace Dali +{ +class Adaptor; + +namespace Internal +{ + +namespace Adaptor +{ +class CommandLineOptions; +class EventLoop; + +class WidgetApplication; +typedef IntrusivePtr WidgetApplicationPtr; + +/** + * Implementation of the WidgetApplication class. + */ +class WidgetApplication : public BaseObject, public Framework::Observer +{ +public: + typedef Dali::WidgetApplication::AppSignalType AppSignalType; + + /** + * Create a new widget application + * @param[in] argc A pointer to the number of arguments + * @param[in] argv A pointer to the argument list + * @param[in] stylesheet The path to user defined theme file + */ + static WidgetApplicationPtr New( int* argc, char **argv[], const std::string& stylesheet ); + +public: + + /** + * @copydoc Dali::WidgetApplication::MainLoop() + */ + void MainLoop(); + + /** + * @copydoc Dali::WidgetApplication::Quit() + */ + void Quit(); + + /** + * @copydoc Dali::WidgetApplication::GetWindow(); + */ + Dali::Window GetWindow(); + + /** + * @copydoc Dali::WidgetApplication::GetAdaptor(); + */ + Dali::Adaptor& GetAdaptor(); + + /** + * @copydoc Dali::WidgetApplication::GetResourcePath(); + */ + static std::string GetResourcePath(); + +public: // Lifecycle functionality + + /** + * Called when OnInit is called or the framework is initialised. + */ + void DoInit(); + + /** + * Called after OnInit is called or the framework is started. + */ + void DoStart(); + + /** + * Called when OnTerminate is called or the framework is terminated. + */ + void DoTerminate(); + + /** + * Called when OnLanguageChanged is called or the framework informs the application that the language of the device has changed. + */ + void DoLanguageChange(); + +public: // From Framework::Observer + + /** + * Called when the framework is initialised. + */ + virtual void OnInit(); + + /** + * Called when the framework is terminated. + */ + virtual void OnTerminate(); + + /** + * Called when the framework informs the application that the language of the device has changed. + */ + virtual void OnLanguageChanged(); + + /** + * Called when the framework informs the application that the region of the device has changed. + */ + virtual void OnRegionChanged(); + + /** + * Called when the framework informs the application that the battery level of the device is low. + */ + virtual void OnBatteryLow(); + + /** + * Called when the framework informs the application that the memory level of the device is low. + */ + virtual void OnMemoryLow(); + +public: // Signals + + /** + * @copydoc Dali::WidgetApplication::InitSignal() + */ + Dali::WidgetApplication::AppSignalType& InitSignal() { return mInitSignal; } + + /** + * @copydoc Dali::WidgetApplication::TerminateSignal() + */ + Dali::WidgetApplication::AppSignalType& TerminateSignal() { return mTerminateSignal; } + + /** + * @copydoc Dali::WidgetApplication::LanguageChangedSignal() + */ + Dali::WidgetApplication::AppSignalType& LanguageChangedSignal() { return mLanguageChangedSignal; } + + /** + * @copydoc Dali::WidgetApplication::RegionChangedSignal() + */ + Dali::WidgetApplication::AppSignalType& RegionChangedSignal() { return mRegionChangedSignal; } + + /** + * @copydoc Dali::WidgetApplication::BatteryLowSignal() + */ + Dali::WidgetApplication::AppSignalType& BatteryLowSignal() { return mBatteryLowSignal; } + + /** + * @copydoc Dali::WidgetApplication::MemoryLowSignal() + */ + Dali::WidgetApplication::AppSignalType& MemoryLowSignal() { return mMemoryLowSignal; } + +protected: + + /** + * Private Constructor + * @param[in] argc A pointer to the number of arguments + * @param[in] argv A pointer to the argument list + * @param[in] stylesheet The path to user defined theme file + */ + WidgetApplication( int* argc, char **argv[], const std::string& stylesheet ); + + /** + * Destructor + */ + virtual ~WidgetApplication(); + + // Undefined + WidgetApplication(const Application&); + WidgetApplication& operator=(Application&); + + /** + * Creates the adaptor + */ + void CreateAdaptor(); + + /** + * Quits from the main loop + */ + void QuitFromMainLoop(); + + /** + * Add idle + */ + bool AddIdle( CallbackBase* callback ); + +private: + + AppSignalType mInitSignal; + AppSignalType mTerminateSignal; + AppSignalType mLanguageChangedSignal; + AppSignalType mRegionChangedSignal; + AppSignalType mBatteryLowSignal; + AppSignalType mMemoryLowSignal; + + Framework* mFramework; + + Dali::Configuration::ContextLoss mContextLossConfiguration; + CommandLineOptions* mCommandLineOptions; + + Dali::SingletonService mSingletonService; + Dali::Adaptor* mAdaptor; + Dali::Window mWindow; + std::string mName; + std::string mStylesheet; + EnvironmentOptions mEnvironmentOptions; + + SlotDelegate< WidgetApplication > mSlotDelegate; +}; + +inline WidgetApplication& GetImplementation(Dali::WidgetApplication& widgetApplication) +{ + DALI_ASSERT_ALWAYS(widgetApplication && "widget application handle is empty"); + + BaseObject& handle = widgetApplication.GetBaseObject(); + + return static_cast(handle); +} + +inline const WidgetApplication& GetImplementation(const Dali::WidgetApplication& widgetApplication) +{ + DALI_ASSERT_ALWAYS(widgetApplication && "widget application handle is empty"); + + const BaseObject& handle = widgetApplication.GetBaseObject(); + + return static_cast(handle); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#endif // __DALI_INTERNAL_WIDGET_APPLICATION_H__ diff --git a/adaptors/widget/internal/widget-data-impl.cpp b/adaptors/widget/internal/widget-data-impl.cpp new file mode 100644 index 0000000..80d69b1 --- /dev/null +++ b/adaptors/widget/internal/widget-data-impl.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "widget-data-impl.h" + +// EXTERNAL INCLUDES + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +Dali::WidgetData WidgetData::New( const char* instanceId, bundle* args, char* content ) +{ + WidgetDataPtr widgetData ( new WidgetData( instanceId, args, content ) ); + Dali::WidgetData handle( widgetData.Get() ); + return handle; +} + +WidgetData::WidgetData( const char* instanceId, bundle* args, char* content ) +: mArgs(args), + mInstanceId(instanceId), + mContent(content) +{ +} + +WidgetData::~WidgetData() +{ +} + +const char* WidgetData::GetInstanceId() +{ + return mInstanceId; +} + +bundle* WidgetData::GetArgs() +{ + return mArgs; +} + +char* WidgetData::GetContent() +{ + return mContent; +} + +Dali::Window WidgetData::GetWindow() +{ + return mWindow; +} + +void WidgetData::SetArgs( bundle* args ) +{ + mArgs = args; +} + +void WidgetData::SetContent( char* content ) +{ + mContent = content; +} + +void WidgetData::SetWindow( Dali::Window window ) +{ + mWindow = window; +} + +} // Adaptor + +} // Internal + +} // Dali diff --git a/adaptors/widget/internal/widget-data-impl.h b/adaptors/widget/internal/widget-data-impl.h new file mode 100644 index 0000000..65e1ce1 --- /dev/null +++ b/adaptors/widget/internal/widget-data-impl.h @@ -0,0 +1,156 @@ +#ifndef __DALI_INTERNAL_WIDGET_DATA_H__ +#define __DALI_INTERNAL_WIDGET_DATA_H__ + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ +class WidgetData; +typedef IntrusivePtr WidgetDataPtr; + +/** + * Implementation of the Application class. + */ +class WidgetData : public BaseObject +{ +public: + + /** + * Create a new WidgetData + * @param[in] instanceId for widget instance + * @param[in] args for widget instance + * @param[in] content for widget instance + * @return A handle to the WidgetData + */ + static Dali::WidgetData New( const char* instanceId, bundle* args, char* content ); + + /** + * @brief Get widget instance id + * @SINCE_1_2.47 + * @return Id of widget instance + */ + const char* GetInstanceId(); + + /** + * @brief Get widget instance arguments + * @SINCE_1_2.47 + * @return Bundle which contains widget instance arguments + */ + bundle* GetArgs(); + + /** + * @brief Get widget instance content + * @SINCE_1_2.47 + * @return Content of widget instance + */ + char* GetContent(); + + /** + * @brief Get widget instance Window + * @SINCE_1_2.47 + * @return Window of widget instance + */ + Dali::Window GetWindow(); + + /** + * @brief Set widget instance arguments + * @SINCE_1_2.47 + * @param[in] args arguments of widget instance + */ + void SetArgs( bundle* args ); + + /** + * @brief Set widget instance arguments + * @SINCE_1_2.47 + * @param[in] content content of widget instance + */ + void SetContent( char* content ); + + /** + * @brief Set widget instance arguments + * @SINCE_1_2.47 + * @param[in] window Window of widget instance + */ + void SetWindow( Dali::Window window ); + +protected: + + /** + * Private Constructor + * @param[in] instanceId for widget instance + * @param[in] args for widget instance + * @param[in] content for widget instance + */ + WidgetData( const char* instanceId, bundle* args, char* content ); + + /** + * Destructor + */ + virtual ~WidgetData(); + + // Undefined + WidgetData(const WidgetData&); + WidgetData& operator=(WidgetData&); + +private: + + Dali::Window mWindow; + bundle* mArgs; + const char* mInstanceId; + char* mContent; + +}; + +inline WidgetData& GetImplementation(Dali::WidgetData& widgetData) +{ + DALI_ASSERT_ALWAYS(widgetData && "widget data handle is empty"); + + BaseObject& handle = widgetData.GetBaseObject(); + + return static_cast(handle); +} + +inline const WidgetData& GetImplementation(const Dali::WidgetData& widgetData) +{ + DALI_ASSERT_ALWAYS(widgetData && "widget data handle is empty"); + + const BaseObject& handle = widgetData.GetBaseObject(); + + return static_cast(handle); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#endif // __DALI_INTERNAL_WIDGET_DATA_H__ diff --git a/adaptors/widget/internal/widget-impl.cpp b/adaptors/widget/internal/widget-impl.cpp new file mode 100644 index 0000000..b16f1eb --- /dev/null +++ b/adaptors/widget/internal/widget-impl.cpp @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "widget-impl.h" + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#include +#pragma GCC diagnostic pop + +#include +#include + +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Internal +{ + +namespace Adaptor +{ + +namespace +{ + +static bool IsWidgetFeatureEnabled() +{ + static bool feature = false; + static bool retrieved = false; + int ret; + + if(retrieved == true) + return feature; + + ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature); + if(ret != SYSTEM_INFO_ERROR_NONE) + { + DALI_LOG_ERROR("failed to get system info\n"); /* LCOV_EXCL_LINE */ + return false; /* LCOV_EXCL_LINE */ + } + + retrieved = true; + + return feature; +} + +static int SendLifecycleEvent(const char* classId, const char* instanceId, int status) +{ + bundle* bundleData = bundle_create(); + int ret; + + if (bundleData == NULL) + { + DALI_LOG_ERROR("out of memory"); + return -1; + } + + bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId); + bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId); + bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int)); + + + char temp[256] = {0, }; + char *packageId = NULL; + if(aul_app_get_pkgid_bypid(getpid(), temp, sizeof(temp)) == 0) + { + packageId = strdup(temp); + } + + if(!packageId) + { + DALI_LOG_ERROR("package_id is NULL"); + return -1; + } + bundle_add_str(bundleData, AUL_K_PKGID, packageId); + + ret = aul_app_com_send("widget.status", bundleData); + + if (ret < 0) + DALI_LOG_ERROR("send lifecycle error:%d\n", ret); + + bundle_free(bundleData); + + return ret; +} + +static int SendUpdateStatus(const char* classId, const char* instanceId, int status, bundle* extra ) +{ + bundle* bundleData; + int lifecycle = -1; + bundle_raw *raw = NULL; + int length; + + bundleData = bundle_create(); + if(!bundleData) + { + DALI_LOG_ERROR("out of memory"); + return -1; + } + + bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId); + bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId); + bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int)); + + if(extra) + { + bundle_encode(extra, &raw, &length); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + bundle_add_str(bundleData, "__WIDGET_CONTENT_INFO__", (const char*)raw); +#pragma GCC diagnostic pop + aul_widget_instance_add(classId, instanceId); + } + + switch(status) + { + case AUL_WIDGET_INSTANCE_EVENT_CREATE: + lifecycle = Dali::Widget::WidgetLifecycleEventType::CREATE; + break; + case AUL_WIDGET_INSTANCE_EVENT_DESTROY: + lifecycle = Dali::Widget::WidgetLifecycleEventType::DESTROY; + break; + case AUL_WIDGET_INSTANCE_EVENT_PAUSE: + lifecycle = Dali::Widget::WidgetLifecycleEventType::PAUSE; + break; + case AUL_WIDGET_INSTANCE_EVENT_RESUME: + lifecycle = Dali::Widget::WidgetLifecycleEventType::RESUME; + break; + } + + if (lifecycle > -1) + SendLifecycleEvent(classId, instanceId, lifecycle); + + bundle_free(bundleData); + + if (raw) + free(raw); + + return 0; +} + +} // anonymous namespace + +Dali::Widget Widget::New( const std::string& id ) +{ + if(!IsWidgetFeatureEnabled()) + { + DALI_LOG_ERROR("not supported"); + Dali::Widget handle(NULL); + return handle; + } + + if( id.size() < 1 ) + { + DALI_LOG_ERROR("class id is NULL"); + Dali::Widget handle(NULL); + return handle; + } + + WidgetPtr widget ( new Widget( id ) ); + Dali::Widget handle( widget.Get() ); + return handle; +} + +void Widget::InsertWidgetData( const char* id, Dali::WidgetData widgetData ) +{ + mIdWidgetContainer.push_back( std::make_pair( id, widgetData ) ); +} + +Dali::WidgetData* Widget::FindWidgetData( const char* key ) +{ + for( IdWidgetDataContainer::iterator iter = mIdWidgetContainer.begin(), endIter = mIdWidgetContainer.end(); iter != endIter; ++iter ) + { + if( iter->first == key ) + { + return &iter->second; + } + } + return NULL; // Not found +} + +void Widget::DeleteWidgetData( const char* key ) +{ + for( IdWidgetDataContainer::iterator iter = mIdWidgetContainer.begin(), endIter = mIdWidgetContainer.end(); iter != endIter; ++iter ) + { + if( iter->first == key ) + { + iter = mIdWidgetContainer.erase(iter); + return; + } + } +} + +static void OnInit(appcore_multiwindow_base_instance_h context, void *data) +{ + Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data ); + bundle* bundleData; + bundle* contentData = NULL; + char* operation = NULL; + char* content = NULL; + char* widthStr = NULL; + char* heightStr = NULL; + char* remain = NULL; + uint32_t width = 0; + uint32_t height = 0; + + // currently, there is no implementaion in appcore; + appcore_multiwindow_base_class_on_create(context); + + const char* id = appcore_multiwindow_base_instance_get_id(context); + bundle* createBundle = static_cast(appcore_multiwindow_base_instance_get_extra(context)); + + Dali::WidgetData widgetData = Dali::WidgetData::New( id, createBundle, NULL ); + + char* createContent = NULL; + bundle_get_str(createBundle, "__WIDGET_CONTENT_INFO__", &createContent); + if(createContent) + { + widgetData.SetContent( const_cast(std::string(createContent).c_str()) ); + } + widget->InsertWidgetData( id, widgetData ); + + bundleData = widgetData.GetArgs(); + bundle_get_str(bundleData, "__WIDGET_OP__", &operation); + + if(!operation) + { + DALI_LOG_ERROR("no operation provided"); + return; + } + + bundle_get_str(bundleData, "__WIDGET_CONTENT_INFO__", &content); + bundle_get_str(bundleData, "__WIDGET_WIDTH__", &widthStr); + bundle_get_str(bundleData, "__WIDGET_HEIGHT__", &heightStr); + + if(widthStr) + width = static_cast(g_ascii_strtoll(widthStr, &remain, 10)); + + if(heightStr) + height = static_cast(g_ascii_strtoll(heightStr, &remain, 10)); + + if(content) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + contentData = bundle_decode((const bundle_raw*)content, strlen(content)); +#pragma GCC diagnostic pop + + Any nativeHandle = Dali::Adaptor::Get().GetNativeWindowHandle(); + Ecore_Wl_Window * wlWindow = AnyCast( nativeHandle ); + + struct wl_surface* surface = ecore_wl_window_surface_get(wlWindow); + + screen_connector_provider_remote_enable(id, surface); + ecore_wl_window_class_name_set(wlWindow, id); + appcore_multiwindow_base_window_bind( context, wlWindow ); + + if(!widget->mCreateSignal.Empty()) + { + widget->mCreateSignal.Emit(widgetData, contentData, Dali::Widget::WindowSize(width, height)); + } + + SendUpdateStatus(widget->mClassId.c_str(), const_cast(id), AUL_WIDGET_INSTANCE_EVENT_CREATE, NULL); + + aul_widget_instance_add(widget->mClassId.c_str(), const_cast(id)); + + if(contentData) + bundle_free(contentData); +} + +static void OnTerminate(appcore_multiwindow_base_instance_h context, void *data) +{ + bundle* bundleData; + char* operation = NULL; + bundle* contentData; + + Dali::Widget::WidgetTerminateType reason = Dali::Widget::WidgetTerminateType::TEMPORARY; + int event = AUL_WIDGET_INSTANCE_EVENT_TERMINATE; + const char* id; + + id = appcore_multiwindow_base_instance_get_id(context); + + Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data ); + + Dali::WidgetData* widgetData = widget->FindWidgetData(id); + + bundleData = widgetData->GetArgs(); + + if(bundleData) + { + bundle_get_str(bundleData, "__WIDGET_OP__", &operation); + if (operation && strcmp(operation, "destroy") == 0) + { + reason = Dali::Widget::WidgetTerminateType::PERMANENT; + } + } + + char* content = widgetData->GetContent(); + if( content ) + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + contentData = bundle_decode((const bundle_raw *)content, strlen(content)); +#pragma GCC diagnostic pop + } + else + { + contentData = bundle_create(); + } + + if(!widget->mTerminateSignal.Empty()) + { + widget->mTerminateSignal.Emit(*widgetData, contentData, reason ); + } + + if(reason == Dali::Widget::WidgetTerminateType::PERMANENT) + { + event = AUL_WIDGET_INSTANCE_EVENT_DESTROY; + aul_widget_instance_del(widget->mClassId.c_str(), id); + } + else + { + SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, contentData); + } + + if(contentData) + { + bundle_free(contentData); + } + + SendUpdateStatus(widget->mClassId.c_str(), id, event, NULL); + + // currently, there is no implementaion in appcore; + appcore_multiwindow_base_class_on_terminate(context); + widget->DeleteWidgetData(id); +} + +static void OnPause(appcore_multiwindow_base_instance_h context, void *data) +{ + // currently, there is no implementaion in appcore; + appcore_multiwindow_base_class_on_pause(context); + + const char *id = appcore_multiwindow_base_instance_get_id(context); + Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data ); + + Dali::WidgetData* widgetData = widget->FindWidgetData(id); + + if(!widget->mPauseSignal.Empty()) + { + widget->mPauseSignal.Emit(*widgetData); + } + + SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_PAUSE, NULL); +} + +static void OnResume(appcore_multiwindow_base_instance_h context, void *data) +{ + // currently, there is no implementaion in appcore; + appcore_multiwindow_base_class_on_resume(context); + + const char *id = appcore_multiwindow_base_instance_get_id(context); + Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data ); + + Dali::WidgetData* widgetData = widget->FindWidgetData(id); + + if(!widget->mResumeSignal.Empty()) + { + widget->mResumeSignal.Emit(*widgetData); + } + + SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_RESUME, NULL); +} + +void Widget::OnResize(appcore_multiwindow_base_instance_h context, Dali::Widget::WindowSize windowSize) +{ + const char *id = appcore_multiwindow_base_instance_get_id(context); + Dali::WidgetData *widgetData = FindWidgetData(id); + + if(!mResizeSignal.Empty()) + { + mResizeSignal.Emit(*widgetData, windowSize); + } + + SendUpdateStatus(mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL); +} + +void Widget::OnUpdate(appcore_multiwindow_base_instance_h context, bundle* content, int force) +{ + const char *id = appcore_multiwindow_base_instance_get_id(context); + Dali::WidgetData *widgetData = static_cast(appcore_multiwindow_base_instance_get_extra(context)); + + if(!mUpdateSignal.Empty()) + { + mUpdateSignal.Emit(*widgetData, content, force); + } + + SendUpdateStatus(mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_UPDATE, NULL); +} + +Widget::Widget( const std::string& id ) +: mCreateSignal(), + mTerminateSignal(), + mPauseSignal(), + mResumeSignal(), + mResizeSignal(), + mUpdateSignal(), + mClassId(id), + mSlotDelegate(this) +{ + appcore_multiwindow_base_class cls; + + cls.id = const_cast(mClassId.c_str()); + cls.data = this; + cls.create = OnInit; + cls.terminate = OnTerminate; + cls.pause = OnPause; + cls.resume = OnResume; + + appcore_multiwindow_base_class_add(cls); +} + +Widget::~Widget() +{ +} + +} // Adaptor + +} // Internal + +} // Dali diff --git a/adaptors/widget/internal/widget-impl.h b/adaptors/widget/internal/widget-impl.h new file mode 100644 index 0000000..490213d --- /dev/null +++ b/adaptors/widget/internal/widget-impl.h @@ -0,0 +1,180 @@ +#ifndef __DALI_INTERNAL_WIDGET_H__ +#define __DALI_INTERNAL_WIDGET_H__ + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ +class Widget; +typedef IntrusivePtr WidgetPtr; + +/** + * Implementation of the Application class. + */ +class Widget : public BaseObject +{ +public: + typedef Dali::Widget::WidgetInstanceCreateSignalType WidgetInstanceCreateSignalType; + typedef Dali::Widget::WidgetInstanceTerminateSignalType WidgetInstanceTerminateSignalType; + typedef Dali::Widget::WidgetInstancePauseSignalType WidgetInstancePauseSignalType; + typedef Dali::Widget::WidgetInstanceResumeSignalType WidgetInstanceResumeSignalType; + typedef Dali::Widget::WidgetInstanceResizeSignalType WidgetInstanceResizeSignalType; + typedef Dali::Widget::WidgetInstanceUpdateSignalType WidgetInstanceUpdateSignalType; + + + typedef std::pair< const char*, Dali::WidgetData > IdWidgetDataPair; + typedef std::vector< IdWidgetDataPair > IdWidgetDataContainer; + + /** + * Create a new Widget + * @param[in] id Id of widget instance + */ + static Dali::Widget New( const std::string& id ); + +public: // Signals + + /** + * @copydoc Dali::Widget::InitSignal() + */ + WidgetInstanceCreateSignalType& CreateSignal(){ return mCreateSignal; } + + /** + * @copydoc Dali::Widget::TerminateSignal() + */ + WidgetInstanceTerminateSignalType& TerminateSignal(){ return mTerminateSignal; } + + /** + * @copydoc Dali::Widget::PauseSignal() + */ + WidgetInstancePauseSignalType& PauseSignal(){ return mPauseSignal; } + + /** + * @copydoc Dali::Widget::ResumeSignal() + */ + WidgetInstanceResumeSignalType& ResumeSignal(){ return mResumeSignal; } + + /** + * @copydoc Dali::Widget::ResizeSignal() + */ + WidgetInstanceResizeSignalType& ResizeSignal(){ return mResizeSignal; } + + /** + * @copydoc Dali::Widget::UpdateSignal() + */ + WidgetInstanceUpdateSignalType& UpdateSignal(){ return mUpdateSignal; } + +public: + + /** + * Called when the widget is resized. + */ + void OnResize(appcore_multiwindow_base_instance_h, Dali::Widget::WindowSize windowSize); + + /** + * Called when the widget is updated. + */ + void OnUpdate(appcore_multiwindow_base_instance_h, bundle* content, int force); + + /** + * Called when Create Widget Instance. + */ + void InsertWidgetData( const char* id, Dali::WidgetData widgetData ); + + /** + * Called when finding widget data by instance id. + */ + Dali::WidgetData* FindWidgetData( const char* instanceId ); + + /** + * Called when deleting widget data by instance id. + */ + void DeleteWidgetData( const char* instanceId ); + +protected: + + /** + * Private Constructor + * @param[in] id Id for widget instance + */ + Widget( const std::string& id ); + + /** + * Destructor + */ + virtual ~Widget(); + + // Undefined + Widget(const Widget&); + Widget& operator=(Widget&); + +public: + + WidgetInstanceCreateSignalType mCreateSignal; + WidgetInstanceTerminateSignalType mTerminateSignal; + WidgetInstancePauseSignalType mPauseSignal; + WidgetInstanceResumeSignalType mResumeSignal; + WidgetInstanceResizeSignalType mResizeSignal; + WidgetInstanceUpdateSignalType mUpdateSignal; + const std::string mClassId; + +private: + SlotDelegate< Widget > mSlotDelegate; + IdWidgetDataContainer mIdWidgetContainer; +}; + +inline Widget& GetImplementation(Dali::Widget& widget) +{ + DALI_ASSERT_ALWAYS(widget && "widget handle is empty"); + + BaseObject& handle = widget.GetBaseObject(); + + return static_cast(handle); +} + +inline const Widget& GetImplementation(const Dali::Widget& widget) +{ + DALI_ASSERT_ALWAYS(widget && "widget handle is empty"); + + const BaseObject& handle = widget.GetBaseObject(); + + return static_cast(handle); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali +#endif // __DALI_INTERNAL_WIDGET_H__ diff --git a/adaptors/widget/widget-application.cpp b/adaptors/widget/widget-application.cpp new file mode 100644 index 0000000..1b7e00d --- /dev/null +++ b/adaptors/widget/widget-application.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "widget-application.h" + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +WidgetApplication WidgetApplication::New( int* argc, char **argv[], const std::string& stylesheet ) +{ + Internal::Adaptor::WidgetApplicationPtr internal = Internal::Adaptor::WidgetApplication::New( argc, argv, stylesheet); + return WidgetApplication(internal.Get()); +} + +WidgetApplication::~WidgetApplication() +{ +} + +WidgetApplication::WidgetApplication() +{ +} + +WidgetApplication::WidgetApplication(const WidgetApplication& widgetApplication) +: BaseHandle(widgetApplication) +{ +} + +WidgetApplication& WidgetApplication::operator=(const WidgetApplication& widgetApplication) +{ + if( *this != widgetApplication ) + { + BaseHandle::operator=( widgetApplication ); + } + return *this; +} + +void WidgetApplication::MainLoop() +{ + Internal::Adaptor::GetImplementation(*this).MainLoop(); +} + +void WidgetApplication::Quit() +{ + Internal::Adaptor::GetImplementation(*this).Quit(); +} + +Window WidgetApplication::GetWindow() +{ + return Internal::Adaptor::GetImplementation(*this).GetWindow(); +} + +std::string WidgetApplication::GetResourcePath() +{ + return Internal::Adaptor::WidgetApplication::GetResourcePath(); +} + +WidgetApplication::AppSignalType& WidgetApplication::InitSignal() +{ + return Internal::Adaptor::GetImplementation(*this).InitSignal(); +} + +WidgetApplication::AppSignalType& WidgetApplication::TerminateSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TerminateSignal(); +} + +WidgetApplication::AppSignalType& WidgetApplication::LanguageChangedSignal() +{ + return Internal::Adaptor::GetImplementation(*this).LanguageChangedSignal(); +} + +WidgetApplication::AppSignalType& WidgetApplication::RegionChangedSignal() +{ + return Internal::Adaptor::GetImplementation(*this).RegionChangedSignal(); +} + +WidgetApplication::AppSignalType& WidgetApplication::BatteryLowSignal() +{ + return Internal::Adaptor::GetImplementation(*this).BatteryLowSignal(); +} + +WidgetApplication::AppSignalType& WidgetApplication::MemoryLowSignal() +{ + return Internal::Adaptor::GetImplementation(*this).MemoryLowSignal(); +} + +WidgetApplication::WidgetApplication(Internal::Adaptor::WidgetApplication* widgetApplication) +: BaseHandle(widgetApplication) +{ +} + +} // namespace Dali diff --git a/adaptors/widget/widget-application.h b/adaptors/widget/widget-application.h new file mode 100644 index 0000000..c28381a --- /dev/null +++ b/adaptors/widget/widget-application.h @@ -0,0 +1,157 @@ +#ifndef __DALI_WIDGET_APPLICATION_H__ +#define __DALI_WIDGET_APPLICATION_H__ + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Internal DALI_INTERNAL +{ +namespace Adaptor +{ +class WidgetApplication; +} +} + +class Window; + +class DALI_IMPORT_API WidgetApplication : public BaseHandle +{ +public: + + typedef Signal< void (WidgetApplication&) > AppSignalType; ///< Application lifecycle signal and system signal callback type + +public: + + /** + * @brief This is the constructor for WidgetApplications with a name. + * + * @param[in,out] argc A pointer to the number of arguments + * @param[in,out] argv A pointer to the argument list + * @param[in] stylesheet The path to user defined theme file + * @return A handle to the WidgetApplication + * @note If the stylesheet is not specified, then the library's default stylesheet will not be overridden. + */ + static WidgetApplication New( int* argc, char **argv[], const std::string& stylesheet ); + + /** + * @brief The default constructor. + * + */ + WidgetApplication(); + + /** + * @brief Copy Constructor. + * @param[in] WidgetApplication Handle to an object + */ + WidgetApplication( const WidgetApplication& widgetApplication ); + + /** + * @brief Assignment operator. + * @param[in] WidgetApplication Handle to an object + * @return A reference to this + */ + WidgetApplication& operator=( const WidgetApplication& widgetApplication ); + + /** + * @brief Destructor + * + */ + ~WidgetApplication(); + + /** + * @brief This starts the application. + */ + void MainLoop(); + + /** + * @brief This quits the application. Tizen applications should use Lower to improve re-start performance unless they need to Quit completely. + */ + void Quit(); + + /** + * @brief Get window. + * @return the window for widget instance. + */ + Window GetWindow(); + + /** + * @brief Get path application resources are stored at + * @return the full path of the resources + */ + + static std::string GetResourcePath(); + +public: // Signals + + /** + * @brief The user should connect to this signal to determine when they should initialize + * their application. + * @return The signal to connect to + */ + AppSignalType& InitSignal(); + + /** + * @brief The user should connect to this signal to determine when they should terminate + * their application. + * @return The signal to connect to + */ + AppSignalType& TerminateSignal(); + + /** + * @brief This signal is emitted when the language is changed on the device. + * @return The signal to connect to + */ + AppSignalType& LanguageChangedSignal(); + + /** + * @brief This signal is emitted when the region of the device is changed. + * @return The signal to connect to + */ + AppSignalType& RegionChangedSignal(); + + /** + * @brief This signal is emitted when the battery level of the device is low. + * @return The signal to connect to + */ + AppSignalType& BatteryLowSignal(); + + /** + * @brief This signal is emitted when the memory level of the device is low. + * @return The signal to connect to + */ + AppSignalType& MemoryLowSignal(); + +public: // Not intended for application developers + /// @cond internal + /** + * @brief Internal constructor. + */ + explicit DALI_INTERNAL WidgetApplication(Internal::Adaptor::WidgetApplication* widgetApplication); + /// @endcond +}; + +} // namespace Dali + +#endif // ___DALI_WIDGET_APPLICATION_H__ diff --git a/adaptors/widget/widget-data.cpp b/adaptors/widget/widget-data.cpp new file mode 100644 index 0000000..9b8520a --- /dev/null +++ b/adaptors/widget/widget-data.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "widget-data.h" + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +WidgetData WidgetData::New( const char* instanceId, bundle* args, char* content ) +{ + return Internal::Adaptor::WidgetData::New( instanceId, args, content ); +} + +WidgetData::~WidgetData() +{ +} + +WidgetData::WidgetData() +{ +} + +WidgetData::WidgetData(const WidgetData& widgetData) +: BaseHandle(widgetData) +{ +} + +WidgetData& WidgetData::operator=(const WidgetData& widgetData) +{ + if( *this != widgetData ) + { + BaseHandle::operator=( widgetData ); + } + return *this; +} + +const char* WidgetData::GetInstanceId() +{ + return Internal::Adaptor::GetImplementation(*this).GetInstanceId(); +} + +bundle* WidgetData::GetArgs() +{ + return Internal::Adaptor::GetImplementation(*this).GetArgs(); +} + +char* WidgetData::GetContent() +{ + return Internal::Adaptor::GetImplementation(*this).GetContent(); +} + +Window WidgetData::GetWindow() +{ + return Internal::Adaptor::GetImplementation(*this).GetWindow(); +} + +void WidgetData::SetArgs( bundle* args ) +{ + Internal::Adaptor::GetImplementation(*this).SetArgs(args); +} + +void WidgetData::SetContent( char* content ) +{ + Internal::Adaptor::GetImplementation(*this).SetContent(content); +} + +void WidgetData::SetWindow( Window window ) +{ + Internal::Adaptor::GetImplementation(*this).SetWindow(window); +} + +WidgetData::WidgetData(Internal::Adaptor::WidgetData* widgetData) +: BaseHandle(widgetData) +{ +} + +} // namespace Dali diff --git a/adaptors/widget/widget-data.h b/adaptors/widget/widget-data.h new file mode 100644 index 0000000..339a151 --- /dev/null +++ b/adaptors/widget/widget-data.h @@ -0,0 +1,131 @@ +#ifndef __DALI_WIDGET_DATA_H__ +#define __DALI_WIDGET_DATA_H__ + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Internal DALI_INTERNAL +{ +namespace Adaptor +{ +class WidgetData; +} +} + +class Window; + +class DALI_IMPORT_API WidgetData : public BaseHandle +{ +public: + + /** + * @brief This is the constructor for WidgetApplications with a name. + * + * @param[in] instanceId for widget instance + * @param[in] args for widget instance + * @param[in] content for widget instance + * @param[in] window for widget instance + * @return A handle to the WidgetData + */ + static WidgetData New( const char* instanceId, bundle* args, char* content ); + + /** + * @brief The default constructor. + * + */ + WidgetData(); + + /** + * @brief Copy Constructor. + * @param[in] WidgetData Handle to an object + */ + WidgetData( const WidgetData& widgetData ); + + /** + * @brief Assignment operator. + * @param[in] WidgetData Handle to an object + * @return A reference to this + */ + WidgetData& operator=( const WidgetData& widgetData ); + + /** + * @brief Destructor + * + */ + ~WidgetData(); + + /** + * @brief Get widget instance id + * @return Id of widget instance + */ + const char* GetInstanceId(); + + /** + * @brief Get widget instance arguments + * @return Bundle which contains widget instance arguments + */ + bundle* GetArgs(); + + /** + * @brief Get widget instance content + * @return Content of widget instance + */ + char* GetContent(); + + /** + * @brief Get widget instance Window + * @return Window of widget instance + */ + Window GetWindow(); + + /** + * @brief Set widget instance arguments + * @param[in] args arguments of widget instance + */ + void SetArgs( bundle* args ); + + /** + * @brief Set widget instance arguments + * @param[in] content content of widget instance + */ + void SetContent( char* content ); + + /** + * @brief Set widget instance arguments + * @param[in] window Window of widget instance + */ + void SetWindow( Window window ); + +public: // Not intended for application developers + /// @cond internal + /** + * @brief Internal constructor. + */ + explicit DALI_INTERNAL WidgetData(Internal::Adaptor::WidgetData* widgetData); + /// @endcond +}; + +} // namespace Dali + +#endif // ___DALI_WIDGET_DATA_H__ diff --git a/adaptors/widget/widget.cpp b/adaptors/widget/widget.cpp new file mode 100644 index 0000000..d48029e --- /dev/null +++ b/adaptors/widget/widget.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include "widget.h" + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include "widget-impl.h" + +namespace Dali +{ + +Widget Widget::New(const std::string& id) +{ + return Internal::Adaptor::Widget::New(id); +} + +Widget::~Widget() +{ +} + +Widget::Widget() +{ +} + +Widget::Widget(const Widget& widget) +: BaseHandle(widget) +{ +} + +Widget& Widget::operator=(const Widget& widget) +{ + if( *this != widget ) + { + BaseHandle::operator=( widget ); + } + return *this; +} + +Widget::WidgetInstanceCreateSignalType& Widget::CreateSignal() +{ + return Internal::Adaptor::GetImplementation(*this).CreateSignal(); +} + +Widget::WidgetInstanceTerminateSignalType& Widget::TerminateSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TerminateSignal(); +} + +Widget::WidgetInstancePauseSignalType& Widget::PauseSignal() +{ + return Internal::Adaptor::GetImplementation(*this).PauseSignal(); +} + +Widget::WidgetInstanceResumeSignalType& Widget::ResumeSignal() +{ + return Internal::Adaptor::GetImplementation(*this).ResumeSignal(); +} + +Widget::WidgetInstanceResizeSignalType& Widget::ResizeSignal() +{ + return Internal::Adaptor::GetImplementation(*this).ResizeSignal(); +} + +Widget::WidgetInstanceUpdateSignalType& Widget::UpdateSignal() +{ + return Internal::Adaptor::GetImplementation(*this).UpdateSignal(); +} + +Widget::Widget(Internal::Adaptor::Widget* widget) +: BaseHandle(widget) +{ +} + +} // namespace Dali diff --git a/adaptors/widget/widget.h b/adaptors/widget/widget.h new file mode 100644 index 0000000..155ba0d --- /dev/null +++ b/adaptors/widget/widget.h @@ -0,0 +1,164 @@ +#ifndef __DALI_WIDGET_H__ +#define __DALI_WIDGET_H__ + +/* + * Copyright (c) 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include "widget-data.h" + +namespace Dali +{ + +namespace Internal DALI_INTERNAL +{ + +namespace Adaptor +{ +class Widget; +} + +} + +class WidgetData; + +/** + * @brief Widget object should be created by WidgetApplication. + */ + +class DALI_IMPORT_API Widget : public BaseHandle +{ +public: + + /** + * @brief Enumeration for terminate type of widget instance. + */ + typedef enum + { + PERMANENT, /**< User deleted this widget from the viewer */ + TEMPORARY, /**< Widget is deleted because of other reasons (e.g. widget process is terminated temporarily by the system) */ + } WidgetTerminateType; + + typedef enum + { + APP_DEAD = 0, + CREATE = 1, /**< The widget is created */ + DESTROY = 2, /**< The widget is destroyed */ + PAUSE = 3, /**< The widget is paused */ + RESUME = 4, /**< The widget is resumed */ + } WidgetLifecycleEventType; + + typedef Uint16Pair WindowSize; + + typedef Signal< void (WidgetData, bundle*, WindowSize) > WidgetInstanceCreateSignalType; ///< Widget instance lifecycle signal and system signal callback type + typedef Signal< void (WidgetData, bundle*, WidgetTerminateType) > WidgetInstanceTerminateSignalType; ///< Widget instance lifecycle signal and system signal callback type + typedef Signal< void (WidgetData) > WidgetInstancePauseSignalType; ///< Widget instance lifecycle signal and system signal callback type + typedef Signal< void (WidgetData) > WidgetInstanceResumeSignalType; ///< Widget instance lifecycle signal and system signal callback type + typedef Signal< void (WidgetData, WindowSize) > WidgetInstanceResizeSignalType; ///< Widget instance lifecycle signal and system signal callback type + typedef Signal< void (WidgetData, bundle*, int) > WidgetInstanceUpdateSignalType; ///< Widget instance lifecycle signal and system signal callback type + +public: + + /** + * @brief This is the constructor for Widget. + * @param[in] id for widget instance + * @return A handle to the Widget + */ + static Widget New( const std::string& id ); + + /** + * @brief The default constructor. + * + */ + Widget(); + + /** + * @brief Copy Constructor. + * @param[in] Widget Handle to an object + */ + Widget( const Widget& widget ); + + /** + * @brief Assignment operator. + * @param[in] Widget Handle to an object + * @return A reference to this + */ + Widget& operator=( const Widget& widget ); + + /** + * @brief Destructor + * + */ + ~Widget(); + +public: // Signals + + /** + * @brief The user should connect to this signal to determine when they create widget instance. + * @return The signal to connect to + */ + WidgetInstanceCreateSignalType& CreateSignal(); + + /** + * @brief The user should connect to this signal to determine when they terminate widget instance. + * @return The signal to connect to + */ + WidgetInstanceTerminateSignalType& TerminateSignal(); + + /** + * @brief This signal is emitted when the language is changed on the device. + * @return The signal to connect to + */ + WidgetInstancePauseSignalType& PauseSignal(); + + /** + * @brief This signal is emitted when the region of the device is changed. + * @return The signal to connect to + */ + WidgetInstanceResumeSignalType& ResumeSignal(); + + /** + * @brief This signal is emitted when the battery level of the device is low. + * @return The signal to connect to + */ + WidgetInstanceResizeSignalType& ResizeSignal(); + + /** + * @brief This signal is emitted when the memory level of the device is low. + * @return The signal to connect to + */ + WidgetInstanceUpdateSignalType& UpdateSignal(); + +public: // Not intended for application developers + /// @cond internal + /** + * @brief Internal constructor. + */ + explicit DALI_INTERNAL Widget(Internal::Adaptor::Widget* widget); + /// @endcond +}; + +} // namespace Dali + +#endif // ___DALI_WIDGET_H__ diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index 496a96f..16343f0 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -90,6 +90,9 @@ include ../../../adaptors/public-api/file.list adaptor_devel_api_dir = ../../../adaptors/devel-api include ../../../adaptors/devel-api/file.list +# Widget API +adaptor_widget_api_dir = ../../../adaptors/widget +include ../../../adaptors/widget/file.list # Static libraries static_libraries_libunibreak_src_dir = ../../../text/dali/internal/libunibreak @@ -257,6 +260,13 @@ endif # WAYLAND endif # IVI_PROFILE +if USE_APPFW +if USE_APPFW_EFL_BASE +else # over Tizen 3.0 +adaptor_internal_src_files += $(adaptor_internal_widget_src_files) +endif +endif + main_loop_integration_src_files = $(adaptor_common_internal_ecore_src_files) input_event_handler_src_files = $(adaptor_ecore_x_event_handler_internal_src_files) @@ -287,6 +297,14 @@ libdali_adaptor_la_SOURCES += \ $(base_adaptor_networking_src_files) endif +if USE_APPFW +if USE_APPFW_EFL_BASE +else # over Tizen 3.0 +libdali_adaptor_la_SOURCES += \ + $(adaptor_widget_src_files) +endif +endif + libdali_adaptor_la_DEPENDENCIES = # List include directories with more platform-specific (tizen) before portable root: @@ -337,6 +355,15 @@ libdali_adaptor_la_includes += \ -I../../../adaptors/tizen endif +if USE_APPFW +if USE_APPFW_EFL_BASE +else # over Tizen 3.0 +libdali_adaptor_la_includes += \ + -I../../../adaptors/widget \ + -I../../../adaptors/widget/internal +endif +endif + daliDefaultThemeDir = ${dataReadWriteDir}/theme/ daliShaderbinCacheDir = ${dataReadOnlyDir}/core/shaderbin/ @@ -435,13 +462,21 @@ libdali_adaptor_la_CXXFLAGS += $(ELEMENTARY_CFLAGS) libdali_adaptor_la_LIBADD += $(ELEMENTARY_LIBS) else -libdali_adaptor_la_CXXFLAGS += $(CAPI_APPFW_COMMON_CFLAGS) \ +libdali_adaptor_la_CXXFLAGS += $(BUNDLE_CFLAGS) \ + $(CAPI_AUL_CFLAGS) \ + $(CAPI_APPFW_COMMON_CFLAGS) \ + $(CAPI_APPFW_WIDGET_APPLICATION_CFLAGS) \ $(CAPI_APPFW_CONTROL_CFLAGS) \ + $(CAPI_SCREEN_CONNECTOR_PROVIDER_CFLAGS) \ $(ECORE_IMF_CFLAGS) \ $(FRIBIDI_CFLAGS) -libdali_adaptor_la_LIBADD += $(CAPI_APPFW_COMMON_LIBS) \ +libdali_adaptor_la_LIBADD += $(BUNDLE_LIBS) \ + $(CAPI_AUL_LIBS) \ + $(CAPI_APPFW_COMMON_LIBS) \ + $(CAPI_APPFW_WIDGET_APPLICATION_LIBS) \ $(CAPI_APPFW_CONTROL_LIBS) \ + $(CAPI_SCREEN_CONNECTOR_PROVIDER_LIBS) \ $(ECORE_IMF_LIBS) \ $(FRIBIDI_LIBS) endif @@ -566,6 +601,14 @@ tizenadaptorpublicapi_HEADERS += $(adaptor_dali_wearable_header_file) tizenwatchpublicapidir = $(tizenadaptorpublicapidir)/watch tizenwatchpublicapi_HEADERS = $(public_dali_watch_header_files) +if USE_APPFW +if USE_APPFW_EFL_BASE +else # over Tizen 3.0 +tizenwidgetdevelapidir = $(tizenadaptordevelapidir)/widget +tizenwidgetdevelapi_HEADERS = $(adaptor_widget_header_files) +endif +endif + install-data-local: $(MKDIR_P) ${DESTDIR}/${daliUserFontCacheDir} ${DESTDIR}/${daliShaderbinCacheDir} diff --git a/build/tizen/adaptor/configure.ac b/build/tizen/adaptor/configure.ac index 2e5000c..d678c8c 100644 --- a/build/tizen/adaptor/configure.ac +++ b/build/tizen/adaptor/configure.ac @@ -245,14 +245,19 @@ fi fi # ubuntu profile test if test "x$enable_appfw" = "xyes"; then +DALI_ADAPTOR_CFLAGS="$DALI_ADAPTOR_CFLAGS -DWIDGET_AVAILABLE" PKG_CHECK_MODULES(CAPI_SYSTEM_SYSTEM_SETTINGS, capi-system-system-settings) if test "x$enable_tizen_major_version" = "x3"; then PKG_CHECK_MODULES(CAPI_APPFW_APPLICATION, capi-appfw-application) PKG_CHECK_MODULES(ELEMENTARY, elementary) else +PKG_CHECK_MODULES(CAPI_AUL, aul) PKG_CHECK_MODULES(CAPI_APPFW_APPLICATION, appcore-ui) +PKG_CHECK_MODULES(CAPI_APPFW_WIDGET_APPLICATION, appcore-multiwindow) +PKG_CHECK_MODULES(BUNDLE, bundle) PKG_CHECK_MODULES(CAPI_APPFW_COMMON, capi-appfw-app-common) PKG_CHECK_MODULES(CAPI_APPFW_CONTROL, capi-appfw-app-control) +PKG_CHECK_MODULES(CAPI_SCREEN_CONNECTOR_PROVIDER, screen_connector_provider) fi else PKG_CHECK_MODULES(ELEMENTARY, elementary) diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index ffba679..2cf0dae 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -109,9 +109,12 @@ BuildRequires: pkgconfig(evas) BuildRequires: pkgconfig(capi-appfw-application) BuildRequires: pkgconfig(elementary) %else +BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(appcore-ui) +BuildRequires: pkgconfig(appcore-multiwindow) BuildRequires: pkgconfig(capi-appfw-app-common) BuildRequires: pkgconfig(capi-appfw-app-control) +BuildRequires: pkgconfig(screen_connector_provider) BuildRequires: pkgconfig(ecore-imf) %endif BuildRequires: pkgconfig(capi-system-system-settings) -- 2.7.4