2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "widget-impl.h"
23 #include <aul_app_com.h>
24 #include <appcore_multiwindow_base.h>
26 #include <screen_connector_provider.h>
28 #pragma GCC diagnostic push
29 #pragma GCC diagnostic ignored "-Wold-style-cast"
31 #pragma GCC diagnostic pop
33 #include <system_info.h>
36 #include <dali/integration-api/debug.h>
37 #include <dali/public-api/math/vector2.h>
40 #include <widget-data.h>
54 static bool IsWidgetFeatureEnabled()
56 static bool feature = false;
57 static bool retrieved = false;
63 ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature);
64 if(ret != SYSTEM_INFO_ERROR_NONE)
66 DALI_LOG_ERROR("failed to get system info\n"); /* LCOV_EXCL_LINE */
67 return false; /* LCOV_EXCL_LINE */
75 static int SendLifecycleEvent(const char* classId, const char* instanceId, int status)
77 bundle* bundleData = bundle_create();
80 if (bundleData == NULL)
82 DALI_LOG_ERROR("out of memory");
86 bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId);
87 bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId);
88 bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int));
91 char temp[256] = {0, };
92 char *packageId = NULL;
93 if(aul_app_get_pkgid_bypid(getpid(), temp, sizeof(temp)) == 0)
95 packageId = strdup(temp);
100 DALI_LOG_ERROR("package_id is NULL");
103 bundle_add_str(bundleData, AUL_K_PKGID, packageId);
105 ret = aul_app_com_send("widget.status", bundleData);
108 DALI_LOG_ERROR("send lifecycle error:%d\n", ret);
110 bundle_free(bundleData);
115 static int SendUpdateStatus(const char* classId, const char* instanceId, int status, bundle* extra )
119 bundle_raw *raw = NULL;
122 bundleData = bundle_create();
125 DALI_LOG_ERROR("out of memory");
129 bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId);
130 bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId);
131 bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int));
135 bundle_encode(extra, &raw, &length);
136 #pragma GCC diagnostic push
137 #pragma GCC diagnostic ignored "-Wold-style-cast"
138 bundle_add_str(bundleData, "__WIDGET_CONTENT_INFO__", (const char*)raw);
139 #pragma GCC diagnostic pop
140 aul_widget_instance_add(classId, instanceId);
145 case AUL_WIDGET_INSTANCE_EVENT_CREATE:
146 lifecycle = Dali::Widget::WidgetLifecycleEventType::CREATE;
148 case AUL_WIDGET_INSTANCE_EVENT_DESTROY:
149 lifecycle = Dali::Widget::WidgetLifecycleEventType::DESTROY;
151 case AUL_WIDGET_INSTANCE_EVENT_PAUSE:
152 lifecycle = Dali::Widget::WidgetLifecycleEventType::PAUSE;
154 case AUL_WIDGET_INSTANCE_EVENT_RESUME:
155 lifecycle = Dali::Widget::WidgetLifecycleEventType::RESUME;
160 SendLifecycleEvent(classId, instanceId, lifecycle);
162 bundle_free(bundleData);
170 } // anonymous namespace
172 Dali::Widget Widget::New( const std::string& id )
174 if(!IsWidgetFeatureEnabled())
176 DALI_LOG_ERROR("not supported");
177 Dali::Widget handle(NULL);
183 DALI_LOG_ERROR("class id is NULL");
184 Dali::Widget handle(NULL);
188 WidgetPtr widget ( new Widget( id ) );
189 Dali::Widget handle( widget.Get() );
193 void Widget::InsertWidgetData( const char* id, Dali::WidgetData widgetData )
195 mIdWidgetContainer.push_back( std::make_pair( id, widgetData ) );
198 Dali::WidgetData* Widget::FindWidgetData( const char* key )
200 for( IdWidgetDataContainer::iterator iter = mIdWidgetContainer.begin(), endIter = mIdWidgetContainer.end(); iter != endIter; ++iter )
202 if( iter->first == key )
204 return &iter->second;
207 return NULL; // Not found
210 void Widget::DeleteWidgetData( const char* key )
212 for( IdWidgetDataContainer::iterator iter = mIdWidgetContainer.begin(), endIter = mIdWidgetContainer.end(); iter != endIter; ++iter )
214 if( iter->first == key )
216 iter = mIdWidgetContainer.erase(iter);
222 static void OnInit(appcore_multiwindow_base_instance_h context, void *data)
224 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
226 bundle* contentData = NULL;
227 char* operation = NULL;
228 char* content = NULL;
229 char* widthStr = NULL;
230 char* heightStr = NULL;
235 // currently, there is no implementaion in appcore;
236 appcore_multiwindow_base_class_on_create(context);
238 const char* id = appcore_multiwindow_base_instance_get_id(context);
239 bundle* createBundle = static_cast<bundle*>(appcore_multiwindow_base_instance_get_extra(context));
241 Dali::WidgetData widgetData = Dali::WidgetData::New( id, createBundle, NULL );
243 char* createContent = NULL;
244 bundle_get_str(createBundle, "__WIDGET_CONTENT_INFO__", &createContent);
247 widgetData.SetContent( const_cast<char *>(std::string(createContent).c_str()) );
249 widget->InsertWidgetData( id, widgetData );
251 bundleData = widgetData.GetArgs();
252 bundle_get_str(bundleData, "__WIDGET_OP__", &operation);
256 DALI_LOG_ERROR("no operation provided");
260 bundle_get_str(bundleData, "__WIDGET_CONTENT_INFO__", &content);
261 bundle_get_str(bundleData, "__WIDGET_WIDTH__", &widthStr);
262 bundle_get_str(bundleData, "__WIDGET_HEIGHT__", &heightStr);
265 width = static_cast<uint32_t>(g_ascii_strtoll(widthStr, &remain, 10));
268 height = static_cast<uint32_t>(g_ascii_strtoll(heightStr, &remain, 10));
271 #pragma GCC diagnostic push
272 #pragma GCC diagnostic ignored "-Wold-style-cast"
273 contentData = bundle_decode((const bundle_raw*)content, strlen(content));
274 #pragma GCC diagnostic pop
276 Any nativeHandle = Dali::Adaptor::Get().GetNativeWindowHandle();
277 Ecore_Wl_Window * wlWindow = AnyCast<Ecore_Wl_Window*>( nativeHandle );
279 struct wl_surface* surface = ecore_wl_window_surface_get(wlWindow);
281 screen_connector_provider_remote_enable(id, surface);
282 ecore_wl_window_class_name_set(wlWindow, id);
283 appcore_multiwindow_base_window_bind( context, wlWindow );
285 if(!widget->mCreateSignal.Empty())
287 widget->mCreateSignal.Emit(widgetData, contentData, Dali::Widget::WindowSize(width, height));
290 SendUpdateStatus(widget->mClassId.c_str(), const_cast<char*>(id), AUL_WIDGET_INSTANCE_EVENT_CREATE, NULL);
292 aul_widget_instance_add(widget->mClassId.c_str(), const_cast<char*>(id));
295 bundle_free(contentData);
298 static void OnTerminate(appcore_multiwindow_base_instance_h context, void *data)
301 char* operation = NULL;
304 Dali::Widget::WidgetTerminateType reason = Dali::Widget::WidgetTerminateType::TEMPORARY;
305 int event = AUL_WIDGET_INSTANCE_EVENT_TERMINATE;
308 id = appcore_multiwindow_base_instance_get_id(context);
310 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
312 Dali::WidgetData* widgetData = widget->FindWidgetData(id);
314 bundleData = widgetData->GetArgs();
318 bundle_get_str(bundleData, "__WIDGET_OP__", &operation);
319 if (operation && strcmp(operation, "destroy") == 0)
321 reason = Dali::Widget::WidgetTerminateType::PERMANENT;
325 char* content = widgetData->GetContent();
328 #pragma GCC diagnostic push
329 #pragma GCC diagnostic ignored "-Wold-style-cast"
330 contentData = bundle_decode((const bundle_raw *)content, strlen(content));
331 #pragma GCC diagnostic pop
335 contentData = bundle_create();
338 if(!widget->mTerminateSignal.Empty())
340 widget->mTerminateSignal.Emit(*widgetData, contentData, reason );
343 if(reason == Dali::Widget::WidgetTerminateType::PERMANENT)
345 event = AUL_WIDGET_INSTANCE_EVENT_DESTROY;
346 aul_widget_instance_del(widget->mClassId.c_str(), id);
350 SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, contentData);
355 bundle_free(contentData);
358 SendUpdateStatus(widget->mClassId.c_str(), id, event, NULL);
360 // currently, there is no implementaion in appcore;
361 appcore_multiwindow_base_class_on_terminate(context);
362 widget->DeleteWidgetData(id);
365 static void OnPause(appcore_multiwindow_base_instance_h context, void *data)
367 // currently, there is no implementaion in appcore;
368 appcore_multiwindow_base_class_on_pause(context);
370 const char *id = appcore_multiwindow_base_instance_get_id(context);
371 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
373 Dali::WidgetData* widgetData = widget->FindWidgetData(id);
375 if(!widget->mPauseSignal.Empty())
377 widget->mPauseSignal.Emit(*widgetData);
380 SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_PAUSE, NULL);
383 static void OnResume(appcore_multiwindow_base_instance_h context, void *data)
385 // currently, there is no implementaion in appcore;
386 appcore_multiwindow_base_class_on_resume(context);
388 const char *id = appcore_multiwindow_base_instance_get_id(context);
389 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
391 Dali::WidgetData* widgetData = widget->FindWidgetData(id);
393 if(!widget->mResumeSignal.Empty())
395 widget->mResumeSignal.Emit(*widgetData);
398 SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_RESUME, NULL);
401 void Widget::OnResize(appcore_multiwindow_base_instance_h context, Dali::Widget::WindowSize windowSize)
403 const char *id = appcore_multiwindow_base_instance_get_id(context);
404 Dali::WidgetData *widgetData = FindWidgetData(id);
406 if(!mResizeSignal.Empty())
408 mResizeSignal.Emit(*widgetData, windowSize);
411 SendUpdateStatus(mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL);
414 void Widget::OnUpdate(appcore_multiwindow_base_instance_h context, bundle* content, int force)
416 const char *id = appcore_multiwindow_base_instance_get_id(context);
417 Dali::WidgetData *widgetData = static_cast<Dali::WidgetData*>(appcore_multiwindow_base_instance_get_extra(context));
419 if(!mUpdateSignal.Empty())
421 mUpdateSignal.Emit(*widgetData, content, force);
424 SendUpdateStatus(mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_UPDATE, NULL);
427 Widget::Widget( const std::string& id )
437 appcore_multiwindow_base_class cls;
439 cls.id = const_cast<char*>(mClassId.c_str());
442 cls.terminate = OnTerminate;
444 cls.resume = OnResume;
446 appcore_multiwindow_base_class_add(cls);