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));
90 char temp[256] = {0, };
91 char *packageId = NULL;
92 if(aul_app_get_pkgid_bypid(getpid(), temp, sizeof(temp)) == 0)
94 packageId = strdup(temp);
99 DALI_LOG_ERROR("package_id is NULL");
100 bundle_free(bundleData);
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);
111 bundle_free(bundleData);
116 static int SendUpdateStatus(const char* classId, const char* instanceId, int status, bundle* extra )
120 bundle_raw *raw = NULL;
123 bundleData = bundle_create();
126 DALI_LOG_ERROR("out of memory");
130 bundle_add_str(bundleData, AUL_K_WIDGET_ID, classId);
131 bundle_add_str(bundleData, AUL_K_WIDGET_INSTANCE_ID, instanceId);
132 bundle_add_byte(bundleData, AUL_K_WIDGET_STATUS, &status, sizeof(int));
136 bundle_encode(extra, &raw, &length);
137 #pragma GCC diagnostic push
138 #pragma GCC diagnostic ignored "-Wold-style-cast"
139 bundle_add_str(bundleData, "__WIDGET_CONTENT_INFO__", (const char*)raw);
140 #pragma GCC diagnostic pop
141 aul_widget_instance_add(classId, instanceId);
146 case AUL_WIDGET_INSTANCE_EVENT_CREATE:
147 lifecycle = Dali::Widget::WidgetLifecycleEventType::CREATE;
149 case AUL_WIDGET_INSTANCE_EVENT_DESTROY:
150 lifecycle = Dali::Widget::WidgetLifecycleEventType::DESTROY;
152 case AUL_WIDGET_INSTANCE_EVENT_PAUSE:
153 lifecycle = Dali::Widget::WidgetLifecycleEventType::PAUSE;
155 case AUL_WIDGET_INSTANCE_EVENT_RESUME:
156 lifecycle = Dali::Widget::WidgetLifecycleEventType::RESUME;
161 SendLifecycleEvent(classId, instanceId, lifecycle);
163 bundle_free(bundleData);
171 } // anonymous namespace
173 Dali::Widget Widget::New( const std::string& id )
175 if(!IsWidgetFeatureEnabled())
177 DALI_LOG_ERROR("not supported");
178 Dali::Widget handle(NULL);
184 DALI_LOG_ERROR("class id is NULL");
185 Dali::Widget handle(NULL);
189 WidgetPtr widget ( new Widget( id ) );
190 Dali::Widget handle( widget.Get() );
194 void Widget::InsertWidgetData( const char* id, Dali::WidgetData widgetData )
196 mIdWidgetContainer.push_back( std::make_pair( id, widgetData ) );
199 Dali::WidgetData* Widget::FindWidgetData( const char* key )
201 for( IdWidgetDataContainer::iterator iter = mIdWidgetContainer.begin(), endIter = mIdWidgetContainer.end(); iter != endIter; ++iter )
203 if( iter->first == key )
205 return &iter->second;
208 return NULL; // Not found
211 void Widget::DeleteWidgetData( const char* key )
213 for( IdWidgetDataContainer::iterator iter = mIdWidgetContainer.begin(), endIter = mIdWidgetContainer.end(); iter != endIter; ++iter )
215 if( iter->first == key )
217 iter = mIdWidgetContainer.erase(iter);
223 static void OnInit(appcore_multiwindow_base_instance_h context, void *data)
225 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
227 bundle* contentData = NULL;
228 char* operation = NULL;
229 char* content = NULL;
230 char* widthStr = NULL;
231 char* heightStr = NULL;
236 // currently, there is no implementaion in appcore;
237 appcore_multiwindow_base_class_on_create(context);
239 const char* id = appcore_multiwindow_base_instance_get_id(context);
240 bundle* createBundle = static_cast<bundle*>(appcore_multiwindow_base_instance_get_extra(context));
242 Dali::WidgetData widgetData = Dali::WidgetData::New( id, createBundle, NULL );
244 char* createContent = NULL;
245 bundle_get_str(createBundle, "__WIDGET_CONTENT_INFO__", &createContent);
248 widgetData.SetContent( const_cast<char *>(std::string(createContent).c_str()) );
250 widget->InsertWidgetData( id, widgetData );
252 bundleData = widgetData.GetArgs();
253 bundle_get_str(bundleData, "__WIDGET_OP__", &operation);
257 DALI_LOG_ERROR("no operation provided");
261 bundle_get_str(bundleData, "__WIDGET_CONTENT_INFO__", &content);
262 bundle_get_str(bundleData, "__WIDGET_WIDTH__", &widthStr);
263 bundle_get_str(bundleData, "__WIDGET_HEIGHT__", &heightStr);
266 width = static_cast<uint32_t>(g_ascii_strtoll(widthStr, &remain, 10));
269 height = static_cast<uint32_t>(g_ascii_strtoll(heightStr, &remain, 10));
272 #pragma GCC diagnostic push
273 #pragma GCC diagnostic ignored "-Wold-style-cast"
274 contentData = bundle_decode((const bundle_raw*)content, strlen(content));
275 #pragma GCC diagnostic pop
277 Any nativeHandle = Dali::Adaptor::Get().GetNativeWindowHandle();
278 Ecore_Wl_Window * wlWindow = AnyCast<Ecore_Wl_Window*>( nativeHandle );
280 struct wl_surface* surface = ecore_wl_window_surface_get(wlWindow);
282 screen_connector_provider_remote_enable(id, surface);
283 ecore_wl_window_class_name_set(wlWindow, id);
284 appcore_multiwindow_base_window_bind( context, wlWindow );
286 if(!widget->mCreateSignal.Empty())
288 widget->mCreateSignal.Emit(widgetData, contentData, Dali::Widget::WindowSize(width, height));
291 SendUpdateStatus(widget->mClassId.c_str(), const_cast<char*>(id), AUL_WIDGET_INSTANCE_EVENT_CREATE, NULL);
293 aul_widget_instance_add(widget->mClassId.c_str(), const_cast<char*>(id));
296 bundle_free(contentData);
299 static void OnTerminate(appcore_multiwindow_base_instance_h context, void *data)
302 char* operation = NULL;
305 Dali::Widget::WidgetTerminateType reason = Dali::Widget::WidgetTerminateType::TEMPORARY;
306 int event = AUL_WIDGET_INSTANCE_EVENT_TERMINATE;
309 id = appcore_multiwindow_base_instance_get_id(context);
311 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
313 Dali::WidgetData* widgetData = widget->FindWidgetData(id);
315 bundleData = widgetData->GetArgs();
319 bundle_get_str(bundleData, "__WIDGET_OP__", &operation);
320 if (operation && strcmp(operation, "destroy") == 0)
322 reason = Dali::Widget::WidgetTerminateType::PERMANENT;
326 char* content = widgetData->GetContent();
329 #pragma GCC diagnostic push
330 #pragma GCC diagnostic ignored "-Wold-style-cast"
331 contentData = bundle_decode((const bundle_raw *)content, strlen(content));
332 #pragma GCC diagnostic pop
336 contentData = bundle_create();
339 if(!widget->mTerminateSignal.Empty())
341 widget->mTerminateSignal.Emit(*widgetData, contentData, reason );
344 if(reason == Dali::Widget::WidgetTerminateType::PERMANENT)
346 event = AUL_WIDGET_INSTANCE_EVENT_DESTROY;
347 aul_widget_instance_del(widget->mClassId.c_str(), id);
351 SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, contentData);
356 bundle_free(contentData);
359 SendUpdateStatus(widget->mClassId.c_str(), id, event, NULL);
361 // currently, there is no implementaion in appcore;
362 appcore_multiwindow_base_class_on_terminate(context);
363 widget->DeleteWidgetData(id);
366 static void OnPause(appcore_multiwindow_base_instance_h context, void *data)
368 // currently, there is no implementaion in appcore;
369 appcore_multiwindow_base_class_on_pause(context);
371 const char *id = appcore_multiwindow_base_instance_get_id(context);
372 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
374 Dali::WidgetData* widgetData = widget->FindWidgetData(id);
376 if(!widget->mPauseSignal.Empty())
378 widget->mPauseSignal.Emit(*widgetData);
381 SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_PAUSE, NULL);
384 static void OnResume(appcore_multiwindow_base_instance_h context, void *data)
386 // currently, there is no implementaion in appcore;
387 appcore_multiwindow_base_class_on_resume(context);
389 const char *id = appcore_multiwindow_base_instance_get_id(context);
390 Internal::Adaptor::Widget* widget = static_cast< Internal::Adaptor::Widget* >( data );
392 Dali::WidgetData* widgetData = widget->FindWidgetData(id);
394 if(!widget->mResumeSignal.Empty())
396 widget->mResumeSignal.Emit(*widgetData);
399 SendUpdateStatus(widget->mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_RESUME, NULL);
402 void Widget::OnResize(appcore_multiwindow_base_instance_h context, Dali::Widget::WindowSize windowSize)
404 const char *id = appcore_multiwindow_base_instance_get_id(context);
405 Dali::WidgetData *widgetData = FindWidgetData(id);
407 if(!mResizeSignal.Empty())
409 mResizeSignal.Emit(*widgetData, windowSize);
412 SendUpdateStatus(mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL);
415 void Widget::OnUpdate(appcore_multiwindow_base_instance_h context, bundle* content, int force)
417 const char *id = appcore_multiwindow_base_instance_get_id(context);
418 Dali::WidgetData *widgetData = static_cast<Dali::WidgetData*>(appcore_multiwindow_base_instance_get_extra(context));
420 if(!mUpdateSignal.Empty())
422 mUpdateSignal.Emit(*widgetData, content, force);
425 SendUpdateStatus(mClassId.c_str(), id, AUL_WIDGET_INSTANCE_EVENT_UPDATE, NULL);
428 Widget::Widget( const std::string& id )
438 appcore_multiwindow_base_class cls;
440 cls.id = const_cast<char*>(mClassId.c_str());
443 cls.terminate = OnTerminate;
445 cls.resume = OnResume;
447 appcore_multiwindow_base_class_add(cls);