From: Hwankyu Jhun Date: Wed, 3 Jul 2019 10:47:14 +0000 (+0900) Subject: Modify manual render X-Git-Tag: submit/tizen/20190710.225553~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=35868039ee49e1f89861ce71712a686f3a733324;p=platform%2Fcore%2Fappfw%2Fwidget-viewer.git Modify manual render When the consumer gets the launch request from another application, the consumer should start the rendering manually to solve a problem that the hands of the clock do not move. After calling the elm_win_norender_push() function, the watch-control sends a resume request to the provider. When getting the updated image in the screen-connector callback function, the manual render is stopped. Requires: - https://review.tizen.org/gerrit/#/c/platform/core/appfw/aul-1/+/209214/ Change-Id: I929690a89103397cf65a400f62c9314497188c76 Signed-off-by: Hwankyu Jhun --- diff --git a/watch-control/CMakeLists.txt b/watch-control/CMakeLists.txt index 83bbe713..542b3da7 100644 --- a/watch-control/CMakeLists.txt +++ b/watch-control/CMakeLists.txt @@ -19,9 +19,7 @@ pkg_check_modules(watch-control REQUIRED screen_connector_watcher_evas ) -SET(BUILD_SOURCE - src/control.c -) +AUX_SOURCE_DIRECTORY(src BUILD_SOURCE) FOREACH(flag ${watch-control_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/watch-control/src/control.c b/watch-control/src/control.c old mode 100755 new mode 100644 index 183c283a..8d541a4b --- a/watch-control/src/control.c +++ b/watch-control/src/control.c @@ -33,27 +33,12 @@ #include #include #include +#include -#define API __attribute__((visibility("default"))) - -#undef LOG_TAG -#define LOG_TAG "WATCH_CONTROL" - -#ifndef _E -#define _E LOGE -#endif - -#ifndef _D -#define _D LOGD -#endif - -#ifndef _W -#define _W LOGW -#endif +#include "watch_control_signal.h" +#include "watch_control_private.h" #define KEY_SCREEN_SHAPE_CIRCLE "http://tizen.org/feature/screen.shape.circle" -#define DEVICED_PATH_DISPLAY "/Org/Tizen/System/DeviceD/Display" -#define DEVICED_INTERFACE_DISPLAY "org.tizen.system.deviced.display" static int __watch_viewer_initialized = 0; static int __watch_size_policy = WATCH_POLICY_HINT_EXPAND; @@ -69,11 +54,8 @@ static char *viewer_appid; static int __is_dead_signal_connected; static aul_app_com_connection_h __conn_dead_signal; static unsigned int __watch_rid; -static bool __manual_render; -static guint __manual_render_timer; -static bool __is_bound = false; +static bool __is_bound; static int __viewer_visibility = AUL_SCREEN_STATUS_PAUSE; -static Ecore_Event_Handler *__pre_visibility; struct toolkit_info_s { char *appid; @@ -87,16 +69,250 @@ struct dead_cb_s { void *data; }; +struct manual_render_s { + aul_watch_control_h control_handle; + lcd_signal_h signal_handle; + Ecore_Event_Handler *pre_visibility; + Ecore_Event_Handler *visibility; + guint timer; + bool enabled; + bool started; + bool lcd_on; +}; + static bool __is_pended; static int __change_viewer_visibility(int visibility, bool update_cur_state); static int __change_visibility(int visibility); static aul_app_com_connection_h __conn_launch_signal; +static struct manual_render_s __manual_render; static int __listen_launch_signal(void); static void __ignore_launch_signal(void); static void __set_viewer_appid(void); static void __manual_render_start(void); -static void __manual_render_finish(void); +static void __manual_render_stop(void); + +static bool __watch_is_visible(void) +{ + Evas_Object *image; + bool is_visible = false; + + image = evas_object_data_get(__win, "tbm,watch"); + if (!image) + return false; + + screen_connector_toolkit_evas_is_visible(image, &is_visible); + + return is_visible; +} + +static gboolean __manual_render_timeout_cb(gpointer data) +{ + _W("Manual render timeout expired"); + watch_manager_pause(); + watch_manager_notify_paused_status_of_viewer(); + __manual_render.timer = 0; + __manual_render_stop(); + + return G_SOURCE_REMOVE; +} + +static void __manual_render_set_timer(void) +{ + if (__manual_render.timer) + return; + + __manual_render.timer = g_timeout_add(200, __manual_render_timeout_cb, + NULL); +} + +static void __manual_render_unset_timer(void) +{ + if (!__manual_render.timer) + return; + + g_source_remove(__manual_render.timer); + __manual_render.timer = 0; +} + +static void __manual_render_start(void) +{ + if (!__watch_is_visible()) { + _W("Watch is not visible. Skip manual render"); + return; + } + + __manual_render.enabled = true; + + if (__is_bound) { + _W("Watch is bound cannot manual render just call tick"); + __change_viewer_visibility(AUL_SCREEN_STATUS_PRE_RESUME, false); + watch_manager_resume(); + return; + } + + if (__manual_render.started) { + _W("Manual render is already started"); + return; + } + + elm_win_norender_push(__win); + watch_manager_notify_resumed_status_of_viewer(); + watch_manager_resume(); + __manual_render_set_timer(); + __manual_render.started = true; +} + +static void __manual_render_stop(void) +{ + if (!__manual_render.started) + return; + + elm_win_norender_pop(__win); + _I("Set manual false"); + + __manual_render.started = false; + __manual_render_unset_timer(); +} + +static void __aul_watch_control_cb(bundle *b, void *user_data) +{ + if (!__watch_is_visible() || !__manual_render.lcd_on) { + __manual_render.enabled = false; + return; + } + + __manual_render_start(); +} + +static void __obj_move_cb(void *data, Evas *e, Evas_Object *obj, + void *event_info) +{ + if (!__manual_render.enabled) + return; + + if (!__watch_is_visible() || !__manual_render.lcd_on) + return; + + __manual_render_start(); +} + +static void __lcd_signal_cb(bool lcd_on, void *user_data) +{ + _D("LCD status is changed to %s", lcd_on ? "on" : "off"); + __manual_render.lcd_on = lcd_on; +} + +static Eina_Bool __window_on_pre_visibility(void *data, int type, void *event) +{ + Ecore_Wl2_Event_Window_Pre_Visibility_Change *ev = event; + Ecore_Evas *ee; + Ecore_Wl2_Window *wl_win; + int win_id; + + if (!ev) + return ECORE_CALLBACK_RENEW; + + ee = ecore_evas_ecore_evas_get(evas_object_evas_get(__win)); + if (!ee) + return ECORE_CALLBACK_RENEW; + + wl_win = ecore_evas_wayland2_window_get(ee); + if (!wl_win) + return ECORE_CALLBACK_RENEW; + + win_id = ecore_wl2_window_id_get(wl_win); + if (ev->win != win_id) + return ECORE_CALLBACK_RENEW; + + if (ev && ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) { + __manual_render_start(); + LOGD("[__WINDOW_PRE_VISIBILITY_CHANGE__] win_id(%d)", ev->win); + } + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool __window_on_visibility(void *data, int type, void *event) +{ + Ecore_Wl2_Event_Window_Visibility_Change *ev = event; + Ecore_Evas *ee; + Ecore_Wl2_Window *wl_win; + int win_id; + + if (!ev) + return ECORE_CALLBACK_RENEW; + + ee = ecore_evas_ecore_evas_get(evas_object_evas_get(__win)); + if (!ee) + return ECORE_CALLBACK_RENEW; + + wl_win = ecore_evas_wayland2_window_get(ee); + if (!wl_win) + return ECORE_CALLBACK_RENEW; + + win_id = ecore_wl2_window_id_get(wl_win); + if (ev->win != win_id) + return ECORE_CALLBACK_RENEW; + + if (!ev->fully_obscured) { + LOGD("[__WINDOW_VISIBILITY_CHANGE__] win_id(%d)", ev->win); + __manual_render_unset_timer(); + } + + return ECORE_CALLBACK_RENEW; +} + +static int __manual_render_init(void) +{ + int ret; + + ret = aul_watch_control_add_handler(__aul_watch_control_cb, NULL, + &__manual_render.control_handle); + if (ret < 0) { + _E("Failed to add aul watch control handler"); + return -1; + } + + ret = watch_control_signal_add_lcd_signal_handler(__lcd_signal_cb, + NULL, &__manual_render.signal_handle); + if (ret < 0) { + _E("Failed to add lcd signal handler"); + return -1; + } + + __manual_render.pre_visibility = ecore_event_handler_add( + ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, + __window_on_pre_visibility, NULL); + if (!__manual_render.pre_visibility) + _W("Failed to add pre visibility change handler"); + + __manual_render.visibility = ecore_event_handler_add( + ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, + __window_on_visibility, NULL); + if (!__manual_render.visibility) + _W("Failed to add visibility change handler"); + + return 0; +} + +static void __manual_render_fini(void) +{ + __manual_render_stop(); + + ecore_event_handler_del(__manual_render.visibility); + __manual_render.visibility = NULL; + + ecore_event_handler_del(__manual_render.pre_visibility); + __manual_render.pre_visibility = NULL; + + watch_control_signal_remove_lcd_signal_handler( + __manual_render.signal_handle); + __manual_render.signal_handle = NULL; + + aul_watch_control_remove_handler(__manual_render.control_handle); + __manual_render.control_handle = NULL; +} static void __destroy_toolkit_info(gpointer data) { @@ -207,104 +423,6 @@ static void __win_resized(void *data, Evas *e, Evas_Object *obj, void *event_inf __default_height = h; } -static gboolean __manual_render_timeout(gpointer user_data) -{ - LOGW("manual render timeout expired"); - __manual_render_finish(); - __manual_render_timer = 0; - return G_SOURCE_REMOVE; -} - -static void __manual_render_start(void) -{ - Evas_Object *cur_image; - bool is_visible = false; - - if (__win == NULL) { - _E("Window is NULL"); - return; - } - - cur_image = evas_object_data_get(__win, "tbm,watch"); - screen_connector_toolkit_evas_is_visible(cur_image, &is_visible); - if (!is_visible) { - LOGW("watch is not visible skip manual render"); - return; - } - - if (__is_bound) { - LOGW("watch is bound cannot manual render just call tick"); - __change_viewer_visibility(AUL_SCREEN_STATUS_PRE_RESUME, false); - if (cur_image) - screen_connector_toolkit_evas_send_visibility(cur_image, - VISIBILITY_TYPE_UNOBSCURED); - - return; - } - - if (__manual_render) { - LOGW("manual render is already started"); - return; - } - - elm_win_norender_push(__win); - __change_viewer_visibility(AUL_SCREEN_STATUS_PRE_RESUME, false); - if (cur_image) - screen_connector_toolkit_evas_send_visibility(cur_image, - VISIBILITY_TYPE_UNOBSCURED); - __manual_render = true; - - __manual_render_timer = g_timeout_add(100, __manual_render_timeout, NULL); - LOGI("Manual render start"); -} - -static void __manual_render_finish(void) -{ - if (__win == NULL) { - _E("Window is NULL"); - return; - } - elm_win_norender_pop(__win); - LOGI("set manual false"); - - __manual_render = false; - if (__manual_render_timer > 0) { - g_source_remove(__manual_render_timer); - __manual_render_timer = 0; - } -} - -static Eina_Bool __window_on_pre_visibility(void *data, int type, void *event) -{ - Ecore_Wl2_Event_Window_Pre_Visibility_Change *ev = event; - Ecore_Evas *ee; - Ecore_Wl2_Window *wl_win; - unsigned int win_id; - - if (!ev) - return ECORE_CALLBACK_RENEW; - - ee = ecore_evas_ecore_evas_get(evas_object_evas_get(__win)); - if (!ee) - return ECORE_CALLBACK_RENEW; - - wl_win = ecore_evas_wayland2_window_get(ee); - if (!wl_win) - return ECORE_CALLBACK_RENEW; - - win_id = ecore_wl2_window_id_get(wl_win); - if (ev->win != win_id) - return ECORE_CALLBACK_RENEW; - - if (ev && ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) { - __manual_render_start(); - LOGD("[__WINDOW_PRE_VISIBILITY_CHANGE__] win_id(%u)", - (unsigned int)ev->win); - } - - return ECORE_CALLBACK_RENEW; -} - static int __watch_viewer_init(Evas_Object *win) { if (__watch_viewer_initialized) @@ -322,13 +440,8 @@ static int __watch_viewer_init(Evas_Object *win) __win_resized(NULL, NULL, win, NULL); /* init */ evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, __win_resized, NULL); - __pre_visibility = ecore_event_handler_add( - ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, - __window_on_pre_visibility, NULL); - if (!__pre_visibility) - _E("Failed to add pre visibility change handler"); + __manual_render_init(); - __manual_render = false; __watch_viewer_initialized = 1; return 0; @@ -336,10 +449,7 @@ static int __watch_viewer_init(Evas_Object *win) static void __watch_viewer_fini() { - if (__pre_visibility) { - ecore_event_handler_del(__pre_visibility); - __pre_visibility = NULL; - } + __manual_render_fini(); if (__win) { evas_object_event_callback_del(__win, EVAS_CALLBACK_RESIZE, __win_resized); @@ -387,6 +497,8 @@ static void __screen_connector_toolkit_evas_added_cb(const char *appid, const ch _D("w: %d, h: %d, x: %d y: %d", w, h, x, y); evas_object_smart_callback_call(__win, WATCH_SMART_SIGNAL_ADDED, image); evas_object_data_set(__win, "tbm,watch", image); + evas_object_event_callback_add(image, EVAS_CALLBACK_MOVE, + __obj_move_cb, image); screen_connector_toolkit_evas_get_rid(image, (int *)&__watch_rid); __flush_pending_queue(__watch_rid); __change_viewer_visibility(__viewer_visibility, false); @@ -408,6 +520,8 @@ static void __screen_connector_toolkit_evas_removed_cb(const char *appid, const _D("obj(%p) removed", image); evas_object_smart_callback_call(__win, WATCH_SMART_SIGNAL_REMOVED, image); + evas_object_event_callback_del_full(image, EVAS_CALLBACK_MOVE, + __obj_move_cb, image); cur_image = evas_object_data_get(__win, "tbm,watch"); if (cur_image == image) { evas_object_data_set(__win, "tbm,watch", NULL); @@ -446,8 +560,8 @@ static void __screen_connector_toolkit_evas_updated_cb( { evas_object_smart_callback_call( __win, WATCH_SMART_SIGNAL_UPDATED, image); - if (__manual_render) - __manual_render_finish(); + if (__manual_render.started) + __manual_render_stop(); else LOGI("updated"); } diff --git a/watch-control/src/watch_control_private.h b/watch-control/src/watch_control_private.h new file mode 100644 index 00000000..5618432d --- /dev/null +++ b/watch-control/src/watch_control_private.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WATCH_CONTROL_PRIVATE_H__ +#define __WATCH_CONTROL_PRIVATE_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "WATCH_CONTROL" + +#ifndef _E +#define _E LOGE +#endif + +#ifndef _W +#define _W LOGW +#endif + +#ifndef _I +#define _I LOGI +#endif + +#ifndef _D +#define _D LOGD +#endif + +#ifndef API +#define API __attribute__((visibility("default"))) +#endif + +#endif /* __WATCH_CONTROL_PRIVATE_H__ */ diff --git a/watch-control/src/watch_control_signal.c b/watch-control/src/watch_control_signal.c new file mode 100644 index 00000000..8c671aac --- /dev/null +++ b/watch-control/src/watch_control_signal.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +#include "watch_control_signal.h" +#include "watch_control_private.h" + +#define DEVICED_PATH_DISPLAY "/Org/Tizen/System/DeviceD/Display" +#define DEVICED_INTERFACE_DISPLAY "org.tizen.system.deviced.display" +#define SIGNAL_LCD_ON "LCDOn" +#define SIGNAL_LCD_OFF "LCDOff" + +struct lcd_signal_s { + GDBusConnection *conn; + guint source; + lcd_signal_cb callback; + void *user_data; +}; + +static void __on_lcd_signal_handler(GDBusConnection *connection, + const gchar *sender_name, const gchar *object_name, + const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) +{ + struct lcd_signal_s *h = (struct lcd_signal_s *)user_data; + bool lcd_on; + + if (signal_name && !strcmp(signal_name, SIGNAL_LCD_ON)) + lcd_on = true; + else + lcd_on = false; + + h->callback(lcd_on, h->user_data); +} + +static void __destroy_lcd_signal(struct lcd_signal_s *handle) +{ + if (handle->source) { + g_dbus_connection_signal_unsubscribe(handle->conn, + handle->source); + } + + if (handle->conn) + g_object_unref(handle->conn); + + free(handle); +} + +static struct lcd_signal_s *__create_lcd_signal(lcd_signal_cb callback, + void *user_data) +{ + struct lcd_signal_s *handle; + GError *err = NULL; + + handle = calloc(1, sizeof(struct lcd_signal_s)); + if (!handle) { + _E("Out of memory"); + return NULL; + } + + handle->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!handle->conn) { + _E("g_bus_get_sync() is failed. error(%s)", err->message); + g_error_free(err); + __destroy_lcd_signal(handle); + return NULL; + } + + handle->source = g_dbus_connection_signal_subscribe(handle->conn, + NULL, + DEVICED_INTERFACE_DISPLAY, + NULL, + DEVICED_PATH_DISPLAY, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __on_lcd_signal_handler, + handle, + NULL); + if (!handle->source) { + _E("g_dbus_connection_signal_subscribe() is failed"); + __destroy_lcd_signal(handle); + return NULL; + } + + handle->callback = callback; + handle->user_data = user_data; + + return handle; +} + +int watch_control_signal_add_lcd_signal_handler(lcd_signal_cb callback, + void *user_data, lcd_signal_h *handle) +{ + struct lcd_signal_s *h; + + if (!callback || !handle) { + _E("Invalid parameter"); + return -1; + } + + h = __create_lcd_signal(callback, user_data); + if (!h) + return -1; + + *handle = h; + + return 0; +} + +int watch_control_signal_remove_lcd_signal_handler(lcd_signal_h handle) +{ + struct lcd_signal_s *h = (struct lcd_signal_s *)handle; + + if (!h) { + _E("Invalid parameter"); + return -1; + } + + __destroy_lcd_signal(h); + + return 0; +} diff --git a/watch-control/src/watch_control_signal.h b/watch-control/src/watch_control_signal.h new file mode 100644 index 00000000..850fc7d0 --- /dev/null +++ b/watch-control/src/watch_control_signal.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WATCH_CONTROL_SIGNAL_H__ +#define __WATCH_CONTROL_SIGNAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *lcd_signal_h; + +typedef void (*lcd_signal_cb)(bool lcd_on, void *user_data); + +int watch_control_signal_add_lcd_signal_handler(lcd_signal_cb callback, + void *user_data, lcd_signal_h *handle); + +int watch_control_signal_remove_lcd_signal_handler(lcd_signal_h handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __WATCH_CONTROL_SIGNAL_H__ */