#include <aul_screen_connector.h>
#include <Ecore_Wl2.h>
#include <gio/gio.h>
+#include <aul_watch_control.h>
-#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;
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;
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)
{
__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)
__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;
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);
_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);
_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);
{
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");
}
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#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;
+}