2 * Copyright (c) 2015 - 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.
23 #include <aul_widget.h>
25 #include <Elementary.h>
26 #include <widget_errno.h>
27 #include <widget_instance.h>
29 #include "widget_base.h"
30 #include "widget_app.h"
31 #include "widget-log.h"
32 #include "widget-private.h"
33 #include "widget_app_internal.h"
39 #define LOG_TAG "CAPI_WIDGET_APPLICATION"
40 #define ICONIFY_TIMEOUT 500
42 struct instance_data {
49 widget_app_lifecycle_callback_s *callback;
53 struct app_class_cb_info {
54 widget_instance_lifecycle_callback_s callback;
58 static GList *__class_data_list;
60 static int __class_resize(widget_base_instance_h instance_h, int w, int h,
64 struct instance_data *data;
65 struct app_class_cb_info *callback_data =
66 (struct app_class_cb_info *)class_data;
68 widget_base_class_on_resize(instance_h, w, h);
69 data = (struct instance_data *)
70 widget_base_context_get_user_data(instance_h);
73 _E("widget_base_context_get_user_data() returns null");
79 evas_object_resize(data->win, w, h);
81 _E("unable to find window");
83 if (callback_data && callback_data->callback.resize) {
84 ret = callback_data->callback.resize(
85 (widget_context_h)instance_h,
86 w, h, callback_data->user_data);
92 static int __class_update(widget_base_instance_h instance_h, bundle *content,
93 int force, void *class_data)
96 struct app_class_cb_info *callback_data =
97 (struct app_class_cb_info *)class_data;
99 widget_base_class_on_update(instance_h, content, force);
100 if (callback_data && callback_data->callback.update) {
101 ret = callback_data->callback.update(
102 (widget_context_h)instance_h,
103 content, force, callback_data->user_data);
109 static int __class_create(widget_base_instance_h instance_h, bundle *content,
110 int w, int h, void *class_data)
113 struct app_class_cb_info *callback_data =
114 (struct app_class_cb_info *)class_data;
116 widget_base_class_on_create(instance_h, content, w, h);
117 if (callback_data && callback_data->callback.create) {
118 ret = callback_data->callback.create(
119 (widget_context_h)instance_h,
120 content, w, h, callback_data->user_data);
121 aul_widget_write_log(LOG_TAG, "[%s:%d] ret : %d",
122 __FUNCTION__, __LINE__, ret);
127 static int __class_destroy(widget_base_instance_h instance_h,
128 widget_base_destroy_type_e reason, bundle *content,
132 struct instance_data *data;
133 struct app_class_cb_info *callback_data =
134 (struct app_class_cb_info *)class_data;
136 if (callback_data && callback_data->callback.destroy) {
137 ret = callback_data->callback.destroy(
138 (widget_context_h)instance_h,
139 reason, content, callback_data->user_data);
140 aul_widget_write_log(LOG_TAG, "[%s:%d] ret : %d",
141 __FUNCTION__, __LINE__, ret);
144 data = (struct instance_data *)widget_base_context_get_user_data(instance_h);
146 widget_base_context_set_user_data(instance_h, NULL);
147 if (data->iconify_timer > 0)
148 g_source_remove(data->iconify_timer);
152 widget_base_class_on_destroy(instance_h, reason, content);
157 static gboolean __iconify_timeout_cb(gpointer user_data)
159 struct instance_data *data = user_data;
160 Ecore_Wl2_Window *win = ecore_evas_wayland2_window_get(
161 ecore_evas_ecore_evas_get(evas_object_evas_get(data->win)));
164 ecore_wl2_window_iconified_set(win, EINA_TRUE);
165 data->is_iconified = true;
166 _D("set iconify true");
169 data->iconify_timer = 0;
171 return G_SOURCE_REMOVE;
174 static int __class_pause(widget_base_instance_h instance_h, void *class_data)
177 struct app_class_cb_info *callback_data =
178 (struct app_class_cb_info *)class_data;
179 struct instance_data *data = (struct instance_data *)
180 widget_base_context_get_user_data(instance_h);
182 if (data->iconify_timer > 0)
183 g_source_remove(data->iconify_timer);
185 data->iconify_timer = g_timeout_add(ICONIFY_TIMEOUT,
186 __iconify_timeout_cb, data);
188 widget_base_class_on_pause(instance_h);
189 if (callback_data && callback_data->callback.pause) {
190 ret = callback_data->callback.pause(
191 (widget_context_h)instance_h,
192 callback_data->user_data);
198 static int __class_resume(widget_base_instance_h instance_h, void *class_data)
201 struct app_class_cb_info *callback_data =
202 (struct app_class_cb_info *)class_data;
203 Ecore_Wl2_Window *win;
204 struct instance_data *data = (struct instance_data *)
205 widget_base_context_get_user_data(instance_h);
207 if (data->iconify_timer > 0) {
208 g_source_remove(data->iconify_timer);
209 data->iconify_timer = 0;
212 if (data->is_iconified) {
213 win = ecore_evas_wayland2_window_get(
214 ecore_evas_ecore_evas_get(evas_object_evas_get(data->win)));
216 ecore_wl2_window_iconified_set(win, EINA_FALSE);
217 data->is_iconified = false;
218 _D("set iconify false");
222 widget_base_class_on_resume(instance_h);
223 if (callback_data && callback_data->callback.resume) {
224 ret = callback_data->callback.resume(
225 (widget_context_h)instance_h,
226 callback_data->user_data);
232 static int __widget_app_create(void *data)
234 struct app_cb_info *cb_info = (struct app_cb_info *)data;
235 widget_app_lifecycle_callback_s *callback;
237 widget_base_on_create();
238 if (cb_info && cb_info->callback && cb_info->callback->create) {
239 callback = cb_info->callback;
240 if (callback->create(cb_info->user_data) == NULL) {
241 _D("fail to create widget");
244 _D("widget app is created");
245 aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
252 static int __widget_app_terminate(void *data)
254 struct app_cb_info *cb_info = (struct app_cb_info *)data;
255 widget_app_lifecycle_callback_s *callback;
257 if (cb_info && cb_info->callback && cb_info->callback->terminate) {
258 callback = cb_info->callback;
259 callback->terminate(cb_info->user_data);
260 widget_base_on_terminate();
261 _D("widget app is terminated");
262 aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
266 widget_base_on_terminate();
271 static void __widget_app_init(int argc, char **argv, void *data)
273 elm_init(argc, argv);
276 static void __widget_app_finish(void)
281 static void __widget_app_run(void *data)
286 static void __widget_app_exit(void *data)
291 static void __widget_app_trim_memory(void *data)
294 elm_cache_all_flush();
295 widget_base_on_trim_memory();
298 EXPORT_API int widget_app_main(int argc, char **argv,
299 widget_app_lifecycle_callback_s *callback, void *user_data)
302 struct app_cb_info cb_info;
305 if (argc <= 0 || argv == NULL || callback == NULL)
306 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
309 if (callback->create == NULL)
310 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
312 "widget_app_create_cb() callback must be "
315 ops.create = __widget_app_create;
316 ops.terminate = __widget_app_terminate;
317 ops.init = __widget_app_init;
318 ops.finish = __widget_app_finish;
319 ops.run = __widget_app_run;
320 ops.exit = __widget_app_exit;
321 ops.trim_memory = __widget_app_trim_memory;
323 cb_info.callback = callback;
324 cb_info.user_data = user_data;
326 r = widget_base_init(ops, argc, argv, &cb_info);
329 if (__class_data_list) {
330 g_list_free_full(__class_data_list, free);
331 __class_data_list = NULL;
337 EXPORT_API int widget_app_exit(void)
339 return widget_base_exit();
342 EXPORT_API int widget_app_terminate_context(widget_context_h context)
344 return widget_base_terminate_context((widget_base_instance_h)context);
347 EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data)
349 return widget_base_foreach_context((widget_base_instance_cb)cb, data);
352 EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler,
353 app_event_type_e event_type,
354 app_event_cb callback,
357 return widget_base_add_event_handler(event_handler, event_type,
358 callback, user_data);
361 EXPORT_API int widget_app_remove_event_handler(app_event_handler_h
364 return widget_base_remove_event_handler(event_handler);
367 EXPORT_API const char *widget_app_get_id(widget_context_h context)
373 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
377 ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
378 if (ret != WIDGET_BASE_ERROR_NONE) {
379 _E("failed to get context id"); /* LCOV_EXCL_LINE */
380 set_last_result(ret); /* LCOV_EXCL_LINE */
381 return NULL; /* LCOV_EXCL_LINE */
384 set_last_result(WIDGET_ERROR_NONE);
388 static void __win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
391 plug_id = evas_object_data_del(obj, "___PLUGID");
395 EXPORT_API int widget_app_get_elm_win(widget_context_h context,
398 Evas_Object *ret_win = NULL;
399 Ecore_Wl2_Window *wl_win;
400 struct instance_data *data;
407 if (context == NULL || win == NULL)
408 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
411 ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
412 if (ret != WIDGET_BASE_ERROR_NONE) {
413 _E("failed to get context id"); /* LCOV_EXCL_LINE */
414 goto fault; /* LCOV_EXCL_LINE */
417 ret_win = elm_win_add(NULL, id, ELM_WIN_BASIC);
418 if (ret_win == NULL) {
419 _E("failed to create window"); /* LCOV_EXCL_LINE */
420 goto fault; /* LCOV_EXCL_LINE */
423 elm_win_wm_rotation_preferred_rotation_set(ret_win, -1);
424 elm_win_wm_rotation_available_rotations_set(ret_win, rots, 1);
426 wl_win = ecore_evas_wayland2_window_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ret_win)));
427 if (wl_win == NULL) {
428 _E("failed to get wayland window"); /* LCOV_EXCL_LINE */
432 ecore_wl2_window_class_set(wl_win, id);
433 elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1");
434 widget_base_context_window_bind((widget_base_instance_h)context, id, wl_win);
436 /* Set data to use in accessibility */
437 snprintf(buffer, sizeof(buffer), "%s:%d", id, getpid());
438 evas_object_data_set(ret_win, "___PLUGID", strdup(buffer));
439 evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL, __win_del_cb, NULL);
441 win_id = ecore_wl2_window_id_get(wl_win);
442 _D("window created: %d", win_id);
444 data = (struct instance_data *)widget_base_context_get_user_data(
445 (widget_base_instance_h)context);
447 data = calloc(1, sizeof(struct instance_data));
449 _E("failed to alloc instance_data"); /* LCOV_EXCL_LINE */
450 goto fault; /* LCOV_EXCL_LINE */
453 ret = widget_base_context_set_user_data((widget_base_instance_h)context, data);
454 if (ret != WIDGET_BASE_ERROR_NONE) {
455 _E("fail to set extra data"); /* LCOV_EXCL_LINE */
456 goto fault; /* LCOV_EXCL_LINE */
463 return WIDGET_ERROR_NONE;
466 if (ret_win) /* LCOV_EXCL_LINE */
467 evas_object_del(ret_win); /* LCOV_EXCL_LINE */
469 return WIDGET_ERROR_FAULT; /* LCOV_EXCL_LINE */
472 EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class,
473 const char *class_id,
474 widget_instance_lifecycle_callback_s callback, void *user_data)
476 widget_base_class cls;
477 struct app_class_cb_info *callback_data;
480 cls = widget_base_class_get_default();
482 /* override methods */
483 cls.ops.create = __class_create;
484 cls.ops.destroy = __class_destroy;
485 cls.ops.pause = __class_pause;
486 cls.ops.resume = __class_resume;
487 cls.ops.resize = __class_resize;
488 cls.ops.update = __class_update;
490 callback_data = calloc(1, sizeof(struct app_class_cb_info));
491 if (!callback_data) {
492 _E("failed to calloc : %s", __FUNCTION__);
493 set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
496 callback_data->callback = callback;
497 callback_data->user_data = user_data;
499 wc = (widget_class_h)widget_base_class_add(cls, class_id,
507 __class_data_list = g_list_append(__class_data_list, callback_data);
508 set_last_result(WIDGET_ERROR_NONE);
513 EXPORT_API widget_class_h widget_app_class_create(
514 widget_instance_lifecycle_callback_s callback, void *user_data)
521 LOGE("appid is NULL");
525 wc = (widget_class_h)widget_app_class_add(NULL, appid, callback,
532 EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag)
536 ret = widget_base_context_set_tag((widget_base_instance_h)context, tag);
537 if (ret != WIDGET_BASE_ERROR_NONE)
538 return widget_app_error(ret, __FUNCTION__, NULL);
540 return WIDGET_ERROR_NONE;
543 EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag)
547 ret = widget_base_context_get_tag((widget_base_instance_h)context, tag);
548 if (ret != WIDGET_BASE_ERROR_NONE)
549 return widget_app_error(ret, __FUNCTION__, NULL);
551 return WIDGET_ERROR_NONE;
554 EXPORT_API int widget_app_context_set_content_info(widget_context_h context,
555 bundle *content_info)
559 ret = widget_base_context_set_content_info(
560 (widget_base_instance_h)context, content_info);
561 if (ret != WIDGET_BASE_ERROR_NONE)
562 return widget_app_error(ret, __FUNCTION__, NULL);
564 return WIDGET_ERROR_NONE;
567 EXPORT_API int widget_app_context_set_title(widget_context_h context,
570 struct instance_data *data = NULL;
573 if (!context || !title) {
574 _E("Invalid parameter %p %p", context, title);
575 return WIDGET_ERROR_INVALID_PARAMETER;
578 data = (struct instance_data *)widget_base_context_get_user_data(
579 (widget_base_instance_h)context);
581 data = calloc(1, sizeof(struct instance_data));
583 return widget_app_error(WIDGET_ERROR_FAULT,
586 ret = widget_base_context_set_user_data(context, data);
587 if (ret != WIDGET_BASE_ERROR_NONE)
588 widget_app_error(ret, __FUNCTION__, NULL);
592 elm_win_title_set(data->win, title);
594 return WIDGET_ERROR_NONE;