2 * Copyright (c) 2017 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.
21 #include <bundle_internal.h>
25 #include <glib-object.h>
28 #include <widget_errno.h>
29 #include <widget_instance.h>
30 #include <aul_app_com.h>
31 #include <Ecore_Wayland.h>
32 #include <system_info.h>
34 #include <vconf-internal-keys.h>
35 #include <screen_connector_provider.h>
36 #include <appcore_multiwindow_base.h>
38 #include "widget_base.h"
44 #define LOG_TAG "CAPI_WIDGET_APPLICATION"
45 #define APP_TYPE_WIDGET "widgetapp"
46 #define STATUS_FOREGROUND "fg"
47 #define STATUS_BACKGROUND "bg"
49 static int __app_event_converter[APPCORE_BASE_EVENT_MAX] = {
50 [APP_EVENT_LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY,
51 [APP_EVENT_LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY,
52 [APP_EVENT_LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE,
53 [APP_EVENT_DEVICE_ORIENTATION_CHANGED]
54 = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED,
55 [APP_EVENT_REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE,
56 [APP_EVENT_SUSPENDED_STATE_CHANGED]
57 = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE,
60 struct app_event_info {
61 app_event_type_e type;
65 struct app_event_handler {
66 app_event_type_e type;
72 struct widget_foreach_context {
73 widget_base_instance_cb callback;
77 typedef struct _widget_base_context {
83 } widget_base_context;
85 typedef struct _widget_base_instance_data {
90 } widget_base_instance_data;
92 static widget_base_context __context;
94 static char *__package_id;
95 static bool __fg_signal;
96 static char *__viewer_endpoint;
98 static bool __is_widget_feature_enabled(void)
100 static bool feature = false;
101 static bool retrieved = false;
104 if (retrieved == true)
107 ret = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
108 if (ret != SYSTEM_INFO_ERROR_NONE) {
109 LOGE("failed to get system info"); /* LCOV_EXCL_LINE */
110 return false; /* LCOV_EXCL_LINE */
118 /* LCOV_EXCL_START */
119 static void __on_poweroff(keynode_t *key, void *data)
123 val = vconf_keynode_get_int(key);
125 case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
126 case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
127 LOGI("power off changed: %d", val);
130 case VCONFKEY_SYSMAN_POWER_OFF_NONE:
131 case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
139 static void __check_empty_instance(void)
141 int cnt = appcore_multiwindow_base_instance_get_cnt();
147 static void __instance_drop(appcore_multiwindow_base_instance_h instance_h)
149 widget_base_instance_data *data;
151 data = appcore_multiwindow_base_instance_get_extra(instance_h);
152 appcore_multiwindow_base_instance_drop(instance_h);
155 __check_empty_instance();
158 static gint __comp_class(gconstpointer a, gconstpointer b)
160 const widget_base_class *cls = a;
162 return strcmp(cls->id, b);
165 static widget_base_class __get_class(const char *class_id)
167 widget_base_class *cls;
170 class_node = g_list_find_custom(__context.classes, class_id,
172 cls = (widget_base_class *)class_node->data;
177 static int __send_lifecycle_event(const char *class_id, const char *instance_id,
180 bundle *b = bundle_create();
184 LOGE("out of memory"); /* LCOV_EXCL_LINE */
185 return -1; /* LCOV_EXCL_LINE */
188 bundle_add_str(b, AUL_K_WIDGET_ID, class_id);
189 bundle_add_str(b, AUL_K_WIDGET_INSTANCE_ID, instance_id);
190 bundle_add_byte(b, AUL_K_WIDGET_STATUS, &status, sizeof(int));
191 bundle_add_str(b, AUL_K_PKGID, __package_id);
193 LOGD("send lifecycle %s(%d)", instance_id, status);
194 ret = aul_app_com_send("widget.status", b);
196 LOGE("send lifecycle error:%d", ret); /* LCOV_EXCL_LINE */
203 static int __send_update_status(const char *class_id, const char *instance_id,
204 int status, bundle *extra)
208 bundle_raw *raw = NULL;
213 LOGE("out of memory"); /* LCOV_EXCL_LINE */
214 return -1; /* LCOV_EXCL_LINE */
217 bundle_add_str(b, AUL_K_WIDGET_ID, class_id);
218 bundle_add_str(b, AUL_K_WIDGET_INSTANCE_ID, instance_id);
219 bundle_add_byte(b, AUL_K_WIDGET_STATUS, &status, sizeof(int));
222 bundle_encode(extra, &raw, &len);
223 bundle_add_str(b, WIDGET_K_CONTENT_INFO, (const char *)raw);
224 aul_widget_instance_add(class_id, instance_id);
227 LOGD("send update %s(%d) to %s", instance_id, status, __viewer_endpoint);
228 aul_app_com_send(__viewer_endpoint, b);
231 case WIDGET_INSTANCE_EVENT_CREATE:
232 lifecycle = WIDGET_LIFE_CYCLE_EVENT_CREATE;
234 case WIDGET_INSTANCE_EVENT_DESTROY:
235 lifecycle = WIDGET_LIFE_CYCLE_EVENT_DESTROY;
237 case WIDGET_INSTANCE_EVENT_PAUSE:
238 lifecycle = WIDGET_LIFE_CYCLE_EVENT_PAUSE;
240 case WIDGET_INSTANCE_EVENT_RESUME:
241 lifecycle = WIDGET_LIFE_CYCLE_EVENT_RESUME;
246 __send_lifecycle_event(class_id, instance_id, lifecycle);
255 static void __control_create(const char *class_id, const char *id, bundle *b)
257 widget_base_instance_data *data;
258 char *content = NULL;
260 data = (widget_base_instance_data *)
261 calloc(1, sizeof(widget_base_instance_data));
263 LOGE("Out of memory");
269 /* call stub create */
270 appcore_multiwindow_base_instance_run(class_id, id, data);
272 bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content);
274 data->content = strdup(content);
278 static void __control_resume(const char *class_id, const char *id, bundle *b)
280 appcore_multiwindow_base_instance_h cxt;
282 cxt = appcore_multiwindow_base_instance_find(id);
284 LOGE("context not found: %s", id);
288 /* call stub resume */
289 appcore_multiwindow_base_instance_resume(cxt);
292 static void __control_pause(const char *class_id, const char *id, bundle *b)
294 appcore_multiwindow_base_instance_h instance_h;
296 instance_h = appcore_multiwindow_base_instance_find(id);
299 LOGE("instance not found: %s", id);
303 /* call stub pause */
304 appcore_multiwindow_base_instance_pause(instance_h);
307 static void __control_resize(const char *class_id, const char *id, bundle *b)
309 appcore_multiwindow_base_instance_h instance_h;
316 widget_base_class cls;
317 const appcore_multiwindow_base_class *raw_cls;
319 instance_h = appcore_multiwindow_base_instance_find(id);
321 LOGE("context not found: %s", id);
325 raw_cls = appcore_multiwindow_base_instance_get_class(instance_h);
329 cls = __get_class(class_id);
330 class_data = raw_cls->data;
331 bundle_get_str(b, WIDGET_K_WIDTH, &w_str);
332 bundle_get_str(b, WIDGET_K_HEIGHT, &h_str);
335 w = (int)g_ascii_strtoll(w_str, &remain, 10);
338 h = (int)g_ascii_strtoll(h_str, &remain, 10);
341 cls.ops.resize(instance_h, w, h, class_data);
343 LOGD("%s is resized to %dx%d", id, w, h);
344 __send_update_status(class_id, id,
345 WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL);
348 static void __update_cb(const char *class_id, const char *id,
349 appcore_multiwindow_base_instance_h instance_h, void *data)
352 const appcore_multiwindow_base_class *raw_cls;
353 bundle *content = NULL;
354 char *content_raw = NULL;
355 char *force_str = NULL;
358 widget_base_class cls;
361 LOGE("bundle is NULL");
365 raw_cls = appcore_multiwindow_base_instance_get_class(instance_h);
367 LOGE("class is NULL");
371 class_data = raw_cls->data;
372 cls = __get_class(class_id);
374 if (!cls.ops.update) {
375 LOGE("update callback is NULL");
379 bundle_get_str(b, WIDGET_K_FORCE, &force_str);
381 if (force_str && strcmp(force_str, "true") == 0)
386 bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content_raw);
389 content = bundle_decode((const bundle_raw *)content_raw,
390 strlen(content_raw));
394 cls.ops.update(instance_h, content, force, class_data);
396 __send_update_status(class_id, id,
397 WIDGET_INSTANCE_EVENT_UPDATE, NULL);
398 LOGD("updated:%s", id);
401 bundle_free(content);
404 static void __control_update(const char *class_id, const char *id, bundle *b)
406 appcore_multiwindow_base_instance_h instance_h;
409 appcore_multiwindow_base_instance_foreach(class_id,
414 instance_h = appcore_multiwindow_base_instance_find(id);
416 LOGE("context not found: %s", id);
420 __update_cb(class_id, id, instance_h, b);
423 static void __control_destroy(const char *class_id, const char *id, bundle *b)
425 appcore_multiwindow_base_instance_h instance_h;
426 widget_base_instance_data *data;
428 instance_h = appcore_multiwindow_base_instance_find(id);
430 LOGE("could not find widget obj: %s, clear amd info", id);
431 aul_widget_instance_del(class_id, id);
435 data = (widget_base_instance_data *)
436 appcore_multiwindow_base_instance_get_extra(instance_h);
439 /* call stub terminate */
440 appcore_multiwindow_base_instance_exit(instance_h);
443 __check_empty_instance();
446 static int __multiwindow_create(void *data)
448 char pkgid[256] = {0, };
451 appcore_multiwindow_base_on_create();
452 app_get_id(&__appid);
453 if (aul_app_get_pkgid_bypid(getpid(), pkgid, sizeof(pkgid)) == 0)
454 __package_id = strdup(pkgid);
456 if (!__package_id || !__appid) {
457 LOGE("__package_id is NULL");
461 screen_connector_provider_init();
462 vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
463 __on_poweroff, NULL);
466 if (__context.ops.create)
467 ret = __context.ops.create(data);
469 LOGD("widget base is created");
473 static int __multiwindow_terminate(void *data)
475 if (__context.ops.terminate)
476 __context.ops.terminate(data);
478 vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
480 screen_connector_provider_fini();
482 if (__viewer_endpoint) {
483 free(__viewer_endpoint);
484 __viewer_endpoint = NULL;
497 appcore_multiwindow_base_on_terminate();
499 LOGD("widget base is terminated");
503 static int __multiwindow_control(bundle *b, void *data)
505 char *class_id = NULL;
507 char *operation = NULL;
509 appcore_multiwindow_base_on_control(b);
510 bundle_get_str(b, WIDGET_K_CLASS, &class_id);
511 /* for previous version compatibility, use appid for default class id */
512 if (class_id == NULL)
515 bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &id);
516 bundle_get_str(b, WIDGET_K_OPERATION, &operation);
519 LOGE("operation is NULL");
523 if (strcmp(operation, "create") == 0)
524 __control_create(class_id, id, b);
525 else if (strcmp(operation, "resize") == 0)
526 __control_resize(class_id, id, b);
527 else if (strcmp(operation, "update") == 0)
528 __control_update(class_id, id, b);
529 else if (strcmp(operation, "destroy") == 0)
530 __control_destroy(class_id, id, b);
531 else if (strcmp(operation, "resume") == 0)
532 __control_resume(class_id, id, b);
533 else if (strcmp(operation, "pause") == 0)
534 __control_pause(class_id, id, b);
535 else if (strcmp(operation, "terminate") == 0)
536 __control_destroy(class_id, id, b);
541 static void __inst_resume_cb(const char *class_id, const char *id,
542 appcore_multiwindow_base_instance_h cxt, void *data)
544 __control_resume(class_id, id, data);
547 static void __get_content(bundle *b)
549 char *instance_id = NULL;
550 appcore_multiwindow_base_instance_h cxt;
551 widget_base_instance_data * we;
553 bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &instance_id);
555 LOGE("instance id is NULL");
559 cxt = appcore_multiwindow_base_instance_find(instance_id);
561 LOGE("could not find widget obj: %s", instance_id);
565 we = appcore_multiwindow_base_instance_get_extra(cxt);
567 LOGE("widget extra is NULL");
572 bundle_add_str(b, AUL_K_WIDGET_CONTENT_INFO, we->content);
573 LOGD("content info of %s found", instance_id);
575 bundle_add_str(b, AUL_K_WIDGET_CONTENT_INFO, "");
576 LOGD("empty content info added");
580 static int __multiwindow_receive(aul_type type, bundle *b, void *data)
582 appcore_multiwindow_base_on_receive(type, b);
586 appcore_multiwindow_base_instance_foreach_full(
587 __inst_resume_cb, b);
592 case AUL_WIDGET_CONTENT:
602 static void __multiwindow_init(int argc, char **argv, void *data)
604 if (__context.ops.init)
605 __context.ops.init(argc, argv, data);
608 static void __multiwindow_finish(void)
610 if (__context.ops.finish) {
611 __context.ops.finish();
612 /* Check Loader case */
613 if (getenv("AUL_LOADER_INIT")) {
614 unsetenv("AUL_LOADER_INIT");
615 __context.ops.finish();
620 static void __multiwindow_run(void *data)
622 if (__context.ops.run)
623 __context.ops.run(data);
626 static void __multiwindow_exit(void *data)
628 if (__context.ops.exit)
629 __context.ops.exit(data);
632 EXPORT_API int widget_base_exit(void)
634 appcore_multiwindow_base_exit();
635 aul_widget_notify_exit();
640 static gboolean __finish_event_cb(gpointer user_data)
642 appcore_multiwindow_base_instance_h cxt = user_data;
645 const char *class_id;
648 LOGE("user_data is NULL");
652 id = appcore_multiwindow_base_instance_get_id(cxt);
653 class_id = appcore_multiwindow_base_instance_get_class_id(cxt);
657 LOGE("Out-of-memory");
661 bundle_add_str(b, WIDGET_K_OPERATION, "terminate");
662 __control_destroy(class_id, id, b);
668 EXPORT_API int widget_base_terminate_context(widget_base_instance_h context)
670 if (!__is_widget_feature_enabled()) {
671 LOGE("not supported"); /* LCOV_EXCL_LINE */
672 return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
676 LOGE("context is null");
677 return WIDGET_ERROR_INVALID_PARAMETER;
680 g_idle_add(__finish_event_cb, context);
682 return WIDGET_ERROR_NONE;
685 static void __inst_full_cb(const char *class_id, const char *id,
686 appcore_multiwindow_base_instance_h cxt, void *data)
688 struct widget_foreach_context *foreach_context = data;
693 if (foreach_context->callback)
694 foreach_context->callback(cxt, foreach_context->data);
697 EXPORT_API int widget_base_foreach_context(widget_base_instance_cb cb, void *data)
699 struct widget_foreach_context foreach_context;
701 if (!__is_widget_feature_enabled()) {
702 LOGE("not supported"); /* LCOV_EXCL_LINE */
703 return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
707 LOGE("callback is NULL");
708 return WIDGET_ERROR_INVALID_PARAMETER;
711 foreach_context.callback = cb;
712 foreach_context.data = data;
713 appcore_multiwindow_base_instance_foreach_full(__inst_full_cb, &foreach_context);
715 return WIDGET_ERROR_NONE;
718 static int __event_cb(void *event, void *data)
720 app_event_handler_h handler = data;
722 struct app_event_info app_event;
724 app_event.type = handler->type;
725 app_event.value = event;
728 handler->cb(&app_event, handler->data);
733 EXPORT_API int widget_base_add_event_handler(app_event_handler_h *event_handler,
734 app_event_type_e event_type,
735 app_event_cb callback,
740 app_event_handler_h handler;
742 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
744 return WIDGET_BASE_ERROR_FAULT;
747 return WIDGET_BASE_ERROR_NOT_SUPPORTED;
749 if (event_handler == NULL || callback == NULL)
750 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
752 if (event_type < APP_EVENT_LOW_MEMORY
753 || event_type > APP_EVENT_REGION_FORMAT_CHANGED)
754 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
756 if (event_type == APP_EVENT_DEVICE_ORIENTATION_CHANGED)
757 return WIDGET_BASE_ERROR_NOT_SUPPORTED;
760 handler = calloc(1, sizeof(struct app_event_handler));
762 return WIDGET_BASE_ERROR_OUT_OF_MEMORY;
764 handler->type = event_type;
765 handler->cb = callback;
766 handler->data = user_data;
767 handler->raw = appcore_base_add_event(
768 __app_event_converter[event_type], __event_cb, handler);
769 *event_handler = handler;
771 return WIDGET_BASE_ERROR_NONE;
774 EXPORT_API int widget_base_remove_event_handler(app_event_handler_h
779 app_event_type_e type;
781 r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature);
783 return WIDGET_BASE_ERROR_FAULT;
786 return WIDGET_BASE_ERROR_NOT_SUPPORTED;
788 if (event_handler == NULL)
789 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
791 type = event_handler->type;
792 if (type < APP_EVENT_LOW_MEMORY ||
793 type > APP_EVENT_REGION_FORMAT_CHANGED)
794 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
796 r = appcore_base_remove_event(event_handler->raw);
798 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
802 return WIDGET_BASE_ERROR_NONE;
805 EXPORT_API int widget_base_context_set_content_info(
806 widget_base_instance_h context,
807 bundle *content_info)
810 bundle_raw *raw = NULL;
813 const char *class_id;
814 widget_base_instance_data *data;
815 appcore_multiwindow_base_instance_h instance_h;
817 if (!__is_widget_feature_enabled()) {
818 LOGE("not supported"); /* LCOV_EXCL_LINE */
819 return WIDGET_BASE_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
822 if (!context || !content_info)
823 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
825 instance_h = (appcore_multiwindow_base_instance_h)context;
826 id = appcore_multiwindow_base_instance_get_id(instance_h);
827 class_id = appcore_multiwindow_base_instance_get_class_id(instance_h);
828 data = appcore_multiwindow_base_instance_get_extra(instance_h);
830 if (!class_id || !id || !data)
831 return WIDGET_BASE_ERROR_FAULT;
833 ret = __send_update_status(class_id, id,
834 WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info);
839 bundle_encode(content_info, &raw, &len);
841 data->content = strdup((const char *)raw);
843 data->content = NULL;
847 /* LCOV_EXCL_START */
848 LOGE("failed to send content info: %s of %s (%d)", id,
850 return WIDGET_BASE_ERROR_IO_ERROR;
854 return WIDGET_BASE_ERROR_NONE;
857 EXPORT_API int widget_base_context_get_tag(widget_base_instance_h context, void **tag)
859 appcore_multiwindow_base_instance_h instance_h;
860 widget_base_instance_data *data;
862 if (!__is_widget_feature_enabled()) {
863 LOGE("not supported"); /* LCOV_EXCL_LINE */
864 return WIDGET_BASE_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
867 if (!context || !tag) {
868 LOGE("Invalid parameter");
869 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
872 instance_h = (appcore_multiwindow_base_instance_h)context;
873 data = (widget_base_instance_data *)
874 appcore_multiwindow_base_instance_get_extra(instance_h);
877 LOGE("Invalid parameter");
878 return WIDGET_ERROR_INVALID_PARAMETER;
883 return WIDGET_BASE_ERROR_NONE;
886 EXPORT_API int widget_base_context_set_tag(widget_base_instance_h context, void *tag)
888 appcore_multiwindow_base_instance_h instance_h;
889 widget_base_instance_data *data;
891 if (!__is_widget_feature_enabled()) {
892 LOGE("not supported"); /* LCOV_EXCL_LINE */
893 return WIDGET_BASE_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
897 LOGE("Invalid parameter");
898 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
901 instance_h = (appcore_multiwindow_base_instance_h)context;
902 data = (widget_base_instance_data *)
903 appcore_multiwindow_base_instance_get_extra(instance_h);
906 return WIDGET_BASE_ERROR_NONE;
909 EXPORT_API void *widget_base_context_get_user_data(
910 widget_base_instance_h context)
912 appcore_multiwindow_base_instance_h instance_h;
913 widget_base_instance_data *data;
915 if (!__is_widget_feature_enabled()) {
916 LOGE("not supported"); /* LCOV_EXCL_LINE */
917 return NULL; /* LCOV_EXCL_LINE */
921 LOGE("Invalid parameter");
925 instance_h = (appcore_multiwindow_base_instance_h)context;
926 data = (widget_base_instance_data *)
927 appcore_multiwindow_base_instance_get_extra(instance_h);
929 return data->user_data;
933 EXPORT_API int widget_base_context_set_user_data(
934 widget_base_instance_h context, void *user_data)
936 appcore_multiwindow_base_instance_h instance_h;
937 widget_base_instance_data *data;
939 if (!__is_widget_feature_enabled()) {
940 LOGE("not supported"); /* LCOV_EXCL_LINE */
941 return WIDGET_BASE_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
945 LOGE("Invalid parameter");
946 return WIDGET_BASE_ERROR_INVALID_PARAMETER;
949 instance_h = (appcore_multiwindow_base_instance_h)context;
950 data = (widget_base_instance_data *)
951 appcore_multiwindow_base_instance_get_extra(instance_h);
952 data->user_data = user_data;
954 return WIDGET_BASE_ERROR_NONE;
957 EXPORT_API int widget_base_context_get_id(widget_base_instance_h context, char **id)
959 appcore_multiwindow_base_instance_h instance_h;
961 if (!__is_widget_feature_enabled()) {
962 LOGE("not supported"); /* LCOV_EXCL_LINE */
963 return WIDGET_BASE_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
966 instance_h = (appcore_multiwindow_base_instance_h)context;
967 *id = (char *)appcore_multiwindow_base_instance_get_id(instance_h);
969 return WIDGET_BASE_ERROR_NONE;
972 EXPORT_API const char *widget_base_get_viewer_endpoint()
974 return __viewer_endpoint;
977 EXPORT_API int widget_base_init(widget_base_ops ops, int argc, char **argv,
981 char *viewer_endpoint = NULL;
982 appcore_multiwindow_base_ops raw_ops
983 = appcore_multiwindow_base_get_default_ops();
986 __context.argc = argc;
987 __context.argv = argv;
988 __context.data = data;
990 /* override methods */
991 raw_ops.base.create = __multiwindow_create;
992 raw_ops.base.control = __multiwindow_control;
993 raw_ops.base.terminate = __multiwindow_terminate;
994 raw_ops.base.receive = __multiwindow_receive;
995 raw_ops.base.init = __multiwindow_init;
996 raw_ops.base.finish = __multiwindow_finish;
997 raw_ops.base.run = __multiwindow_run;
998 raw_ops.base.exit = __multiwindow_exit;
1000 if (!__is_widget_feature_enabled()) {
1001 LOGE("not supported"); /* LCOV_EXCL_LINE */
1002 return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */
1005 kb = bundle_import_from_argv(argc, argv);
1007 bundle_get_str(kb, WIDGET_K_ENDPOINT, &viewer_endpoint);
1008 if (viewer_endpoint) {
1009 LOGD("viewer endpoint :%s", viewer_endpoint);
1010 __viewer_endpoint = strdup(viewer_endpoint);
1012 LOGE("endpoint is missing");
1017 LOGE("failed to get launch argv"); /* LCOV_EXCL_LINE */
1018 return WIDGET_ERROR_FAULT;
1021 if (appcore_multiwindow_base_init(raw_ops, argc, argv, data) < 0)
1022 return WIDGET_ERROR_FAULT;
1024 return WIDGET_ERROR_NONE;
1027 static int __on_create(void *data)
1029 return widget_base_on_create();
1032 static int __on_terminate(void *data)
1034 return widget_base_on_terminate();
1037 static void __on_init(int argc, char **argv, void *data)
1039 widget_base_on_init(argc, argv);
1042 static void __on_finish(void)
1044 widget_base_on_finish();
1047 static void __on_run(void *data)
1049 widget_base_on_run();
1052 static void __on_exit(void *data)
1054 widget_base_on_exit();
1057 EXPORT_API int widget_base_on_create(void)
1059 appcore_multiwindow_base_on_create();
1064 EXPORT_API int widget_base_on_terminate(void)
1066 appcore_multiwindow_base_on_terminate();
1071 EXPORT_API int widget_base_on_init(int argc, char **argv)
1076 EXPORT_API void widget_base_on_finish(void)
1080 EXPORT_API void widget_base_on_run(void)
1084 EXPORT_API void widget_base_on_exit(void)
1088 EXPORT_API widget_base_ops widget_base_get_default_ops(void)
1090 widget_base_ops ops;
1092 /* override methods */
1093 ops.create = __on_create;
1094 ops.terminate = __on_terminate;
1095 ops.init = __on_init;
1096 ops.finish = __on_finish;
1098 ops.exit = __on_exit;
1103 static void __free_class(gpointer data)
1105 widget_base_class *cls = data;
1111 EXPORT_API void widget_base_fini(void)
1113 g_list_free_full(__context.classes, __free_class);
1114 __context.classes = NULL;
1116 appcore_multiwindow_base_fini();
1119 EXPORT_API int widget_base_context_window_bind(
1120 widget_base_instance_h instance_h, const char *id,
1121 Ecore_Wl_Window *wl_win)
1123 struct wl_surface *surface;
1125 surface = ecore_wl_window_surface_get(wl_win);
1126 if (surface == NULL) {
1127 LOGE("failed to get surface"); /* LCOV_EXCL_LINE */
1128 return WIDGET_BASE_ERROR_FAULT; /* LCOV_EXCL_LINE */
1131 screen_connector_provider_remote_enable(id, surface);
1132 appcore_multiwindow_base_window_bind(instance_h, wl_win);
1134 return WIDGET_BASE_ERROR_NONE;
1137 static int __class_on_create(widget_base_instance_h instance_h, bundle *content,
1138 int w, int h, void *class_data)
1140 return widget_base_class_on_create(instance_h, content, w, h);
1143 static int __class_on_resume(widget_base_instance_h instance_h, void *class_data)
1145 return widget_base_class_on_resume(instance_h);
1148 static int __class_on_pause(widget_base_instance_h instance_h,
1151 return widget_base_class_on_pause(instance_h);
1154 static int __class_on_resize(widget_base_instance_h instance_h, int w, int h,
1157 return widget_base_class_on_resize(instance_h, w, h);
1160 static int __class_on_update(widget_base_instance_h instance_h, bundle *content,
1161 int force, void *class_data)
1163 return widget_base_class_on_update(instance_h, content, force);
1166 static int __class_on_destroy(widget_base_instance_h instance_h,
1167 widget_base_destroy_type_e reason, bundle *content,
1170 return widget_base_class_on_destroy(instance_h, reason, content);
1173 static void __multiwindow_instance_create(
1174 appcore_multiwindow_base_instance_h instance_h,
1177 widget_base_instance_data *instance_data;
1179 bundle *content_info = NULL;
1181 char *class_id = NULL;
1182 char *operation = NULL;
1183 char *content = NULL;
1186 char *remain = NULL;
1190 widget_base_class cls;
1192 appcore_multiwindow_base_class_on_create(instance_h);
1193 instance_data = appcore_multiwindow_base_instance_get_extra(instance_h);
1194 b = instance_data->args;
1196 bundle_get_str(b, WIDGET_K_CLASS, &class_id);
1197 /* for previous version compatibility, use appid for default class id */
1198 if (class_id == NULL)
1201 cls = __get_class(class_id);
1202 bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &id);
1203 bundle_get_str(b, WIDGET_K_OPERATION, &operation);
1206 LOGE("no operation provided");
1210 bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content);
1211 bundle_get_str(b, WIDGET_K_WIDTH, &w_str);
1212 bundle_get_str(b, WIDGET_K_HEIGHT, &h_str);
1215 w = (int)g_ascii_strtoll(w_str, &remain, 10);
1218 h = (int)g_ascii_strtoll(h_str, &remain, 10);
1221 content_info = bundle_decode((const bundle_raw *)content,
1225 ret = cls.ops.create(instance_h, content_info, w, h, class_data);
1228 LOGW("Create callback returns error(%d)", ret);
1229 ret = __send_update_status(class_id, id,
1230 WIDGET_INSTANCE_EVENT_CREATE_ABORTED, NULL);
1231 __instance_drop(instance_h);
1233 LOGD("%s is created", id);
1234 ret = __send_update_status(class_id, id,
1235 WIDGET_INSTANCE_EVENT_CREATE, NULL);
1237 aul_widget_instance_add(class_id, id);
1241 bundle_free(content_info);
1244 static void __multiwindow_instance_resume(
1245 appcore_multiwindow_base_instance_h instance_h,
1249 const char *class_id;
1250 widget_base_class cls;
1252 appcore_multiwindow_base_class_on_resume(instance_h);
1253 id = appcore_multiwindow_base_instance_get_id(instance_h);
1254 class_id = appcore_multiwindow_base_instance_get_class_id(instance_h);
1255 cls = __get_class(class_id);
1258 cls.ops.resume(instance_h, class_data);
1260 LOGD("%s is resumed", id);
1261 __send_update_status(class_id, id,
1262 WIDGET_INSTANCE_EVENT_RESUME, NULL);
1265 LOGD("Send fg signal to resourceD");
1266 aul_send_app_status_change_signal(getpid(),
1275 static void __multiwindow_instance_pause(
1276 appcore_multiwindow_base_instance_h instance_h,
1280 const char *class_id;
1281 widget_base_class cls;
1283 appcore_multiwindow_base_class_on_pause(instance_h);
1284 id = appcore_multiwindow_base_instance_get_id(instance_h);
1285 class_id = appcore_multiwindow_base_instance_get_class_id(instance_h);
1286 cls = __get_class(class_id);
1289 cls.ops.pause(instance_h, class_data);
1291 LOGD("%s is paused", id);
1292 __send_update_status(class_id, id,
1293 WIDGET_INSTANCE_EVENT_PAUSE, NULL);
1296 LOGD("Send bg signal to resourceD");
1297 aul_send_app_status_change_signal(getpid(),
1302 __fg_signal = false;
1306 static void __multiwindow_instance_terminate(
1307 appcore_multiwindow_base_instance_h instance_h,
1310 widget_base_instance_data *data;
1312 char *operation = NULL;
1313 bundle *content_info;
1314 widget_base_destroy_type_e reason = WIDGET_BASE_DESTROY_TYPE_TEMPORARY;
1315 int event = WIDGET_INSTANCE_EVENT_TERMINATE;
1317 const char *class_id;
1318 widget_base_class cls;
1320 id = appcore_multiwindow_base_instance_get_id(instance_h);
1321 class_id = appcore_multiwindow_base_instance_get_class_id(instance_h);
1322 data = appcore_multiwindow_base_instance_get_extra(
1323 (appcore_multiwindow_base_instance_h)instance_h);
1325 cls = __get_class(class_id);
1328 bundle_get_str(b, WIDGET_K_OPERATION, &operation);
1329 if (operation && strcmp(operation, "destroy") == 0)
1330 reason = WIDGET_BASE_DESTROY_TYPE_PERMANENT;
1334 content_info = bundle_decode((const bundle_raw *)data->content,
1335 strlen(data->content));
1337 content_info = bundle_create();
1339 if (cls.ops.destroy)
1340 cls.ops.destroy(instance_h, reason, content_info, class_data);
1342 LOGD("%s is destroyed %d", id, reason);
1343 if (reason == WIDGET_BASE_DESTROY_TYPE_PERMANENT) {
1344 event = WIDGET_INSTANCE_EVENT_DESTROY;
1345 aul_widget_instance_del(class_id, id);
1347 __send_update_status(class_id, id,
1348 WIDGET_INSTANCE_EVENT_EXTRA_UPDATED,
1353 bundle_free(content_info);
1355 __send_update_status(class_id, id, event, NULL);
1356 appcore_multiwindow_base_class_on_terminate(instance_h);
1359 EXPORT_API int widget_base_class_on_create(widget_base_instance_h instance_h,
1360 bundle *content, int w, int h)
1362 appcore_multiwindow_base_class_on_create(instance_h);
1367 EXPORT_API int widget_base_class_on_pause(widget_base_instance_h instance_h)
1369 appcore_multiwindow_base_class_on_pause(instance_h);
1374 EXPORT_API int widget_base_class_on_resume(widget_base_instance_h instance_h)
1376 appcore_multiwindow_base_class_on_resume(instance_h);
1381 EXPORT_API int widget_base_class_on_resize(widget_base_instance_h instance_h,
1387 EXPORT_API int widget_base_class_on_update(widget_base_instance_h instance_h,
1388 bundle *content, int force)
1393 EXPORT_API int widget_base_class_on_destroy(widget_base_instance_h instance_h,
1394 widget_base_destroy_type_e reason, bundle *content)
1396 appcore_multiwindow_base_class_on_terminate(instance_h);
1401 EXPORT_API widget_base_class widget_base_class_get_default(void)
1403 widget_base_class cls;
1405 cls.ops.create = __class_on_create;
1406 cls.ops.resize = __class_on_resize;
1407 cls.ops.update = __class_on_update;
1408 cls.ops.destroy = __class_on_destroy;
1409 cls.ops.pause = __class_on_pause;
1410 cls.ops.resume = __class_on_resume;
1415 EXPORT_API widget_base_class *widget_base_class_add(widget_base_class cls,
1416 const char *class_id, void *class_data)
1418 widget_base_class *c;
1419 appcore_multiwindow_base_class raw_cls;
1421 if (!__is_widget_feature_enabled()) {
1422 LOGE("not supported");
1423 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
1428 LOGE("class is is NULL");
1429 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
1433 raw_cls.id = strdup(class_id);
1434 raw_cls.data = class_data;
1435 raw_cls.create = __multiwindow_instance_create;
1436 raw_cls.terminate = __multiwindow_instance_terminate;
1437 raw_cls.pause = __multiwindow_instance_pause;
1438 raw_cls.resume = __multiwindow_instance_resume;
1439 appcore_multiwindow_base_class_add(raw_cls);
1441 c = malloc(sizeof(widget_base_class));
1446 c->id = strdup(class_id);
1447 __context.classes = g_list_append(__context.classes, c);