2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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.
24 #include <glib-object.h>
25 #include <app_control.h>
26 #include <app_control_internal.h>
28 #include <widget_service.h>
29 #include <widget_service_internal.h>
30 #include <widget_provider_app.h>
31 #include <widget_provider_app_internal.h>
32 #include <Elementary.h>
34 #include <widget_errno.h>
35 #include <system_info.h>
37 #include "widget_app.h"
38 #include "widget-log.h"
39 #include "widget-private.h"
40 #include "widget_app_internal.h"
46 #define STR_MAX_BUF 128
47 #define LOG_TAG "CAPI_WIDGET_APPLICATION"
48 #define K_REASON "__WC_K_REASON__"
50 #define ELM_WIN_TIZEN_WIDGET -1
52 * This definition is intended to prevent the build break.
53 * This should be removed after adding ELM_WIN_TIZEN_WIDGET in Elm_Win_Type.
56 #define WIDGET_APP_EVENT_MAX 5
57 static GList *handler_list[WIDGET_APP_EVENT_MAX] = {NULL, };
59 typedef enum _widget_obj_state_e {
66 struct app_event_handler {
67 app_event_type_e type;
72 struct app_event_info {
73 app_event_type_e type;
77 struct _widget_class {
78 widget_instance_lifecycle_callback_s ops;
79 widget_obj_private_ops_s ops_private;
82 struct _widget_context {
86 widget_instance_lifecycle_callback_s ops;
87 widget_obj_private_ops_s ops_private;
90 typedef struct _widget_class widget_class_s;
91 typedef struct _widget_context widget_context_s;
93 static widget_app_lifecycle_callback_s *app_ops = NULL;
94 static void *app_user_data = NULL;
95 static widget_class_factory_full_s factory;
96 static widget_class_s *widget_class = NULL;
97 static widget_class_s widget_class_tmp;
98 static GList *contexts = NULL;
99 static int is_init_provider = 0;
100 static char *appid = NULL;
101 static int is_background = -1;
103 static gint __comp_by_id(gconstpointer a, gconstpointer b)
105 widget_context_s *wc = (widget_context_s*)a;
107 return strcmp(wc->id, (const char*)b);
110 static void __check_status_for_cgroup(void)
112 GList *iter = g_list_first(contexts);
114 while (iter != NULL) {
115 widget_context_s *cxt = (widget_context_s*) iter->data;
117 if (cxt->state != WC_PAUSED) {
118 if (is_background != 0) {
120 _I("enter foreground group");
121 //TODO: Do something to enter foreground group
125 iter = g_list_next(iter);
128 if (g_list_length(contexts) > 0 && is_background == 0) {
130 _I("enter background group");
131 //TODO: DO something to enter background group
135 static widget_context_s* __find_context_by_id(const char *id)
137 GList* ret = g_list_find_custom(contexts, id, __comp_by_id);
145 static int __provider_create_cb(const char *id, const char *content, int w,
149 int ret = WIDGET_ERROR_FAULT;
150 widget_context_s *wc = (widget_context_s*)malloc(sizeof(widget_context_s));
152 return WIDGET_ERROR_OUT_OF_MEMORY;
155 wc->state = WC_READY;
157 wc->ops = widget_class->ops;
158 wc->ops_private = widget_class->ops_private;
159 contexts = g_list_append(contexts, wc);
161 if (wc->ops.create) {
162 bundle *b = bundle_decode((const bundle_raw*)content, strlen(content));
163 ret = wc->ops.create(wc, b, w, h);
166 _I("widget obj was created");
171 static int __provider_resize_cb(const char *id, int w, int h, void *data)
173 int ret = WIDGET_ERROR_FAULT;
174 widget_context_s *cxt = __find_context_by_id(id);
178 ret = cxt->ops.resize(cxt, w, h);
179 _I("received resizing signal");
181 _E("could not find widget obj : %s", __FUNCTION__);
187 static int __provider_destroy_cb(const char *id, widget_destroy_type_e reason,
190 int ret = WIDGET_ERROR_FAULT;
191 widget_context_s *cxt = __find_context_by_id(id);
194 cxt->state = WC_TERMINATED;
195 if (cxt->ops.destroy) {
196 bundle *b = bundle_create();
197 ret = cxt->ops.destroy(cxt,(widget_app_destroy_type_e)reason, b);
199 bundle_raw *raw = NULL;
202 bundle_encode(b, &raw, &len);
204 widget_provider_app_send_extra_info(id, (const char*)raw, NULL);
209 contexts = g_list_remove(contexts, cxt);
214 _I("widget obj was deleted");
216 _E("could not find widget obj : %s", __FUNCTION__);
222 static int __provider_update_cb(const char *id, const char *content, int force,
225 int ret = WIDGET_ERROR_FAULT;
226 widget_context_s *cxt = __find_context_by_id(id);
229 if (cxt->ops.update) {
230 bundle *b = bundle_decode((const bundle_raw*)content, strlen(content));
231 ret = cxt->ops.update(cxt, b, force);
234 _I("received updating signal");
236 _E("could not find widget obj : %s", __FUNCTION__);
242 static int __provider_pause_cb(const char *id, void *data)
244 int ret = WIDGET_ERROR_FAULT;
245 widget_context_s *cxt = __find_context_by_id(id);
249 ret = cxt->ops.pause(cxt);
250 cxt->state = WC_PAUSED;
251 _I("widget obj was paused");
253 _E("could not find widget obj : %s", __FUNCTION__);
256 __check_status_for_cgroup();
260 static int __provider_resume_cb(const char *id, void *data)
262 int ret = WIDGET_ERROR_FAULT;
263 widget_context_s *cxt = __find_context_by_id(id);
267 ret = cxt->ops.resume(cxt);
268 cxt->state = WC_RUNNING;
269 _I("widget obj was resumed");
271 _E("could not find widget obj : %s", __FUNCTION__);
274 __check_status_for_cgroup();
278 static int __provider_text_signal_cb(const char *id, const char *signal_name,
279 const char *source, struct widget_event_info *info, void *data)
281 int ret = WIDGET_ERROR_FAULT;
282 widget_context_s *cxt = __find_context_by_id(id);
285 if (cxt->ops_private.text_signal) {
286 ret = cxt->ops_private.text_signal(cxt, signal_name, source,
287 (widget_obj_event_info_s*)info);
289 _I("received text signal");
291 _E("could not find widget obj : %s", __FUNCTION__);
297 static const widget_class_factory_full_s*
298 __widget_class_factory_override_text_signal(widget_instance_text_signal_cb op)
300 widget_class_tmp.ops_private.text_signal = op;
304 static void __free_handler_cb(gpointer data)
310 static void __free_handler_list(void)
314 for (i = 0; i < WIDGET_APP_EVENT_MAX; i++) {
315 g_list_free_full(handler_list[i], __free_handler_cb);
316 handler_list[i] = NULL;
320 static void __control(bundle *b)
322 app_control_h app_control;
324 if (is_init_provider) {
325 _E("already initialized");
329 if (app_control_create_event(b, &app_control) != 0) {
330 _E("failed to get the app_control handle");
335 app_control_get_operation(app_control, &op);
337 if (op && strcmp(op, "http://tizen.org/appcontrol/operation/main") == 0) {
338 static struct widget_provider_event_callback cb = {
339 .create = __provider_create_cb,
340 .resize = __provider_resize_cb,
341 .destroy = __provider_destroy_cb,
343 .update = __provider_update_cb,
344 .text_signal = __provider_text_signal_cb,
346 .pause = __provider_pause_cb,
347 .resume = __provider_resume_cb,
350 .disconnected = NULL,
355 if (widget_provider_app_init(app_control, &cb) == 0) {
356 is_init_provider = 1;
360 app_control_destroy(app_control);
365 static void __pause_all()
367 GList *iter = g_list_first(contexts);
369 while (iter != NULL) {
370 widget_context_s *cxt = (widget_context_s*) iter->data;
371 const char *id = cxt->id;
373 switch (cxt->state) {
375 __provider_resume_cb(id, NULL);
376 __provider_pause_cb(id, NULL);
380 __provider_pause_cb(id, NULL);
383 iter = g_list_next(iter);
387 static int __aul_handler(aul_type type, bundle *b, void *data)
405 static char* __get_domain_name(const char *aid)
407 char *name_token = NULL;
414 // com.vendor.name -> name
415 name_token = strrchr(aid, '.');
417 if (name_token == NULL) {
418 _E("appid is invalid");
424 return strdup(name_token);
427 static int __before_loop(int argc, char **argv)
431 #if !(GLIB_CHECK_VERSION(2, 36, 0))
435 elm_init(argc, argv);
437 factory.override_text_signal = __widget_class_factory_override_text_signal;
439 r = aul_launch_init(__aul_handler, NULL);
441 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__,
442 "Fail to call the aul_launch_init");
445 r = aul_launch_argv_handler(argc, argv);
447 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__,
448 "Fail to call the aul_launch_argv_handler");
451 r = app_get_id(&appid);
452 if (r != APP_ERROR_NONE)
455 char *name = __get_domain_name(appid);
458 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__,
459 "Fail to call __get_domain_name");
466 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__,
467 "Fail to call _set_i18n");
470 widget_provider_app_create_app();
472 memset(&widget_class_tmp, 0, sizeof(widget_class_tmp));
473 widget_class = app_ops->create(app_user_data);
474 if (widget_class == NULL) {
475 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__,
476 "widget_class is NULL");
479 return WIDGET_ERROR_NONE;
482 static void __after_loop()
485 widget_provider_app_terminate_app(WIDGET_DESTROY_TYPE_TEMPORARY, 1);
487 if (app_ops->terminate)
488 app_ops->terminate(app_user_data);
490 if (is_init_provider) {
491 widget_provider_app_fini();
492 is_init_provider = 0;
494 __free_handler_list();
499 g_list_free(contexts);
503 static gboolean __finish_event_cb(gpointer user_data)
505 if (user_data == NULL)
508 widget_context_s *wc = (widget_context_s*) user_data;
509 const char* id = wc->id;
513 __provider_resume_cb(id, NULL);
514 __provider_pause_cb(id, NULL);
515 __provider_destroy_cb(id, WIDGET_DESTROY_TYPE_DEFAULT, NULL);
519 __provider_pause_cb(id, NULL);
520 __provider_destroy_cb(id, WIDGET_DESTROY_TYPE_DEFAULT, NULL);
524 __provider_destroy_cb(id, WIDGET_DESTROY_TYPE_DEFAULT, NULL);
528 widget_provider_app_send_deleted(id);
532 static void __on_low_memory(keynode_t *key, void *data)
536 val = vconf_keynode_get_int(key);
537 if (val == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
538 app_event_handler_h handler;
539 struct app_event_info event;
541 _I("widget_app_low_memory");
543 event.type = APP_EVENT_LOW_MEMORY;
544 event.value = (void*)&val;
546 GList *iter = g_list_first(handler_list[APP_EVENT_LOW_MEMORY]);
549 handler = (app_event_handler_h) iter->data;
550 handler->cb(&event, handler->data);
551 iter = g_list_next(iter);
556 static void __on_low_battery(keynode_t *key, void *data)
560 val = vconf_keynode_get_int(key);
561 if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW) {
562 app_event_handler_h handler;
563 struct app_event_info event;
565 _I("widget_app_low_battery");
567 event.type = APP_EVENT_LOW_BATTERY;
568 event.value = (void*)&val;
570 GList *iter = g_list_first(handler_list[APP_EVENT_LOW_BATTERY]);
573 handler = (app_event_handler_h) iter->data;
574 handler->cb(&event, handler->data);
575 iter = g_list_next(iter);
580 static void __on_lang_changed(keynode_t *key, void *data)
585 val = vconf_keynode_get_str(key);
587 app_event_handler_h handler;
588 struct app_event_info event;
590 _I("widget_app_lang_changed");
592 event.type = APP_EVENT_LANGUAGE_CHANGED;
593 event.value = (void*)val;
595 GList *iter = g_list_first(handler_list[APP_EVENT_LANGUAGE_CHANGED]);
598 handler = (app_event_handler_h) iter->data;
599 handler->cb(&event, handler->data);
600 iter = g_list_next(iter);
604 static void __on_region_changed(keynode_t *key, void *data)
609 val = vconf_keynode_get_str(key);
611 app_event_handler_h handler;
612 struct app_event_info event;
614 _I("widget_app_region_changed");
616 event.type = APP_EVENT_REGION_FORMAT_CHANGED;
617 event.value = (void*)val;
619 GList *iter = g_list_first(handler_list[APP_EVENT_REGION_FORMAT_CHANGED]);
622 handler = (app_event_handler_h) iter->data;
623 handler->cb(&event, handler->data);
624 iter = g_list_next(iter);
628 static void __register_event(int event_type)
630 switch (event_type) {
631 case APP_EVENT_LOW_MEMORY:
632 vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL);
635 case APP_EVENT_LOW_BATTERY:
636 vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery,
640 case APP_EVENT_LANGUAGE_CHANGED:
641 vconf_notify_key_changed(VCONFKEY_LANGSET, __on_lang_changed, NULL);
644 case APP_EVENT_REGION_FORMAT_CHANGED:
645 vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_changed, NULL);
650 static void __unregister_event(int event_type)
652 switch (event_type) {
653 case APP_EVENT_LOW_MEMORY:
654 vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory);
657 case APP_EVENT_LOW_BATTERY:
658 vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery);
661 case APP_EVENT_LANGUAGE_CHANGED:
662 vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_lang_changed);
665 case APP_EVENT_REGION_FORMAT_CHANGED:
666 vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_changed);
671 EXPORT_API int widget_app_main(int argc, char **argv,
672 widget_app_lifecycle_callback_s *callback, void *user_data)
677 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
679 return WIDGET_ERROR_FAULT;
682 return WIDGET_ERROR_NOT_SUPPORTED;
684 if (argc <= 0 || argv == NULL || callback == NULL)
685 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
687 if (callback->create == NULL)
688 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, "widget_app_create_cb() callback must be registered");
691 app_user_data = user_data;
692 r = __before_loop(argc, argv);
696 ecore_main_loop_begin();
697 //aul_status_update(STATUS_DYING);
700 return WIDGET_ERROR_NONE;
703 EXPORT_API int widget_app_exit(void)
708 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
710 return WIDGET_ERROR_FAULT;
713 return WIDGET_ERROR_NOT_SUPPORTED;
715 ecore_main_loop_quit();
717 return WIDGET_ERROR_NONE;
720 EXPORT_API int widget_app_terminate_context(widget_context_h context)
725 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
727 return WIDGET_ERROR_FAULT;
730 return WIDGET_ERROR_NOT_SUPPORTED;
732 if (context == NULL) {
733 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__,
737 g_idle_add(__finish_event_cb, context);
738 return WIDGET_ERROR_NONE;
741 EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data)
746 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
748 return WIDGET_ERROR_FAULT;
751 return WIDGET_ERROR_NOT_SUPPORTED;
754 return WIDGET_ERROR_INVALID_PARAMETER;
756 GList *iter = g_list_first(contexts);
758 while (iter != NULL) {
759 widget_context_s *cxt = (widget_context_s*) iter->data;
760 if ( !cb(cxt, data)) {
761 return WIDGET_ERROR_CANCELED;
764 iter = g_list_next(iter);
767 return WIDGET_ERROR_NONE;
770 EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler,
771 app_event_type_e event_type, app_event_cb callback, void *user_data)
776 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
778 return WIDGET_ERROR_FAULT;
781 return WIDGET_ERROR_NOT_SUPPORTED;
783 app_event_handler_h handler;
785 if (event_handler == NULL || callback == NULL)
786 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
788 if (event_type < APP_EVENT_LOW_MEMORY
789 || event_type > APP_EVENT_REGION_FORMAT_CHANGED)
790 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
792 if (event_type == APP_EVENT_DEVICE_ORIENTATION_CHANGED)
793 return widget_app_error(WIDGET_ERROR_NOT_SUPPORTED, __FUNCTION__, NULL);
795 GList *iter = g_list_first(handler_list[event_type]);
798 handler = (app_event_handler_h) iter->data;
800 if (handler->cb == callback)
801 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
802 iter = g_list_next(iter);
805 handler = calloc(1, sizeof(struct app_event_handler));
807 return widget_app_error(WIDGET_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
809 if (g_list_length(handler_list[event_type]) == 0) {
810 __register_event(event_type);
813 handler->type = event_type;
814 handler->cb = callback;
815 handler->data = user_data;
816 handler_list[event_type] = g_list_append(handler_list[event_type], handler);
818 *event_handler = handler;
820 return WIDGET_ERROR_NONE;
823 EXPORT_API int widget_app_remove_event_handler(app_event_handler_h
829 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
831 return WIDGET_ERROR_FAULT;
834 return WIDGET_ERROR_NOT_SUPPORTED;
836 app_event_type_e type;
838 if (event_handler == NULL)
839 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
841 type = event_handler->type;
842 if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_REGION_FORMAT_CHANGED)
843 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
845 handler_list[type] = g_list_remove(handler_list[type], event_handler);
848 if (g_list_length(handler_list[type]) == 0)
849 __unregister_event(type);
851 return WIDGET_ERROR_NONE;
854 EXPORT_API const char* widget_app_get_id(widget_context_h context)
859 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
861 set_last_result(WIDGET_ERROR_FAULT);
866 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
870 if (context == NULL) {
871 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
875 widget_context_s *cxt = (widget_context_s*)context;
877 set_last_result(WIDGET_ERROR_NONE);
881 EXPORT_API int widget_app_get_elm_win(widget_context_h context,
887 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
889 return WIDGET_ERROR_FAULT;
892 return WIDGET_ERROR_NOT_SUPPORTED;
894 if (context == NULL || win == NULL) {
895 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
898 widget_context_s *cxt = (widget_context_s*)context;
900 Evas_Object *ret_win = NULL;
902 evas = widget_get_evas(cxt->id);
904 Evas_Object *widget_parent;
905 widget_parent = evas_object_rectangle_add(evas);
907 ret_win = elm_win_add(widget_parent, cxt->id, ELM_WIN_TIZEN_WIDGET);
908 evas_object_del(widget_parent);
909 if (ret_win == NULL) {
911 return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL);
914 _E("Failed to get parent widget");
915 return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL);
918 _E("parent evas object is NULL");
919 return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL);
923 return WIDGET_ERROR_NONE;
926 EXPORT_API widget_class_h widget_app_class_create(widget_instance_lifecycle_callback_s callback)
931 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
933 set_last_result(WIDGET_ERROR_FAULT);
938 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
942 widget_class_s *wc = (widget_class_s*)malloc(sizeof(widget_class_s));
945 _E("failed to malloc : %s", __FUNCTION__);
946 set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
951 wc->ops_private = widget_class_tmp.ops_private;
952 set_last_result(WIDGET_ERROR_NONE);
956 EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag)
961 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
963 return WIDGET_ERROR_FAULT;
966 return WIDGET_ERROR_NOT_SUPPORTED;
968 if (context == NULL) {
969 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
974 return WIDGET_ERROR_NONE;
977 EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag)
982 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
984 return WIDGET_ERROR_FAULT;
987 return WIDGET_ERROR_NOT_SUPPORTED;
989 if (context == NULL || tag == NULL) {
990 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
995 return WIDGET_ERROR_NONE;
998 EXPORT_API int widget_app_context_set_content_info(widget_context_h context, bundle *content_info)
1003 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
1005 return WIDGET_ERROR_FAULT;
1008 return WIDGET_ERROR_NOT_SUPPORTED;
1010 if (content_info == NULL)
1011 return WIDGET_ERROR_INVALID_PARAMETER;
1013 bundle_raw *raw = NULL;
1015 int ret = WIDGET_ERROR_FAULT;
1017 bundle_encode(content_info, &raw, &len);
1019 ret = widget_provider_app_send_extra_info(context->id, (const char*)raw, NULL);
1026 EXPORT_API int widget_app_context_set_title(widget_context_h context, const char *title)
1031 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
1033 return WIDGET_ERROR_FAULT;
1036 return WIDGET_ERROR_NOT_SUPPORTED;
1038 if (context == NULL)
1039 return WIDGET_ERROR_INVALID_PARAMETER;
1041 return widget_provider_app_send_extra_info(context->id, NULL, title);
1045 EXPORT_API const widget_class_factory_full_s* widget_app_get_class_factory(void)