From 4f0d1d80f9b64826079f096ef675d9acb4d1771d Mon Sep 17 00:00:00 2001 From: Igor Olshevskyi Date: Mon, 15 Aug 2016 18:50:56 +0300 Subject: [PATCH] TizenRefApp-6949 [Call UI] Base implementation of indicator color change feature Change-Id: I90c9a9f6737c06e1d30c82bcb1d8cdaf3b97c628 --- inc/callui-common.h | 1 - inc/callui-display.h | 56 +++++-- inc/callui-indicator.h | 67 ++++++++ inc/callui-window.h | 20 ++- inc/callui.h | 12 +- src/callui-common.c | 25 +-- src/callui-display.c | 171 ++++++++++++++----- src/callui-indicator.c | 323 ++++++++++++++++++++++++++++++++++++ src/callui-listeners-collection.c | 2 - src/callui-proximity-lock-manager.c | 24 ++- src/callui-view-callend.c | 5 +- src/callui-view-incoming-call.c | 3 - src/callui-view-quickpanel.c | 2 - src/callui-window.c | 37 ++++- src/callui.c | 186 +++++++++++++++++---- tizen-manifest.xml | 6 +- 16 files changed, 815 insertions(+), 125 deletions(-) create mode 100644 inc/callui-indicator.h create mode 100644 src/callui-indicator.c diff --git a/inc/callui-common.h b/inc/callui-common.h index ad92083..e14cdcb 100644 --- a/inc/callui-common.h +++ b/inc/callui-common.h @@ -251,5 +251,4 @@ struct tm *_callui_common_get_current_time_diff_in_tm(long time); */ char *_callui_common_get_date_string_representation(time_t last_update_time); - #endif /*__CALLUI_COMMON_H_ */ diff --git a/inc/callui-display.h b/inc/callui-display.h index 5b66938..d6bfbac 100644 --- a/inc/callui-display.h +++ b/inc/callui-display.h @@ -21,6 +21,12 @@ #include "callui-common-types.h" typedef enum { + CALLUI_DISPLAY_NORMAL = 0, + CALLUI_DISPLAY_DIM, + CALLUI_DISPLAY_OFF, +} callui_display_state_e; + +typedef enum { CALLUI_DISPLAY_TIMEOUT_DEFAULT = 0, CALLUI_DISPLAY_TIMEOUT_SET, CALLUI_DISPLAY_TIMEOUT_UNSET, @@ -28,15 +34,18 @@ typedef enum { } callui_display_timeout_e; typedef enum { - CALLUI_DISPLAY_ON = 0, - CALLUI_DISPLAY_ON_LOCK, - CALLUI_DISPLAY_ON_UNLOCK, - CALLUI_DISPLAY_UNLOCK, - CALLUI_DISPLAY_OFF_SLEEP_LOCK, - CALLUI_DISPLAY_OFF_SLEEP_UNLOCK, - CALLUI_DISPLAY_OFF + CALLUI_DISPLAY_CONTROL_ON = 0, + CALLUI_DISPLAY_CONTROL_ON_LOCK, + CALLUI_DISPLAY_CONTROL_ON_UNLOCK, + CALLUI_DISPLAY_CONTROL_UNLOCK, + CALLUI_DISPLAY_CONTROL_OFF_SLEEP_LOCK, + CALLUI_DISPLAY_CONTROL_OFF_SLEEP_UNLOCK, + CALLUI_DISPLAY_CONTROL_OFF } callui_display_control_e; +/* Callback functions prototypes */ +typedef void (*callui_display_state_change_cb)(void *user_data); + /* Display handle */ typedef struct __callui_display *callui_display_h; @@ -79,12 +88,39 @@ callui_result_e _callui_display_set_timeout(callui_display_h disp, callui_displa callui_result_e _callui_display_set_control_state(callui_display_h disp, callui_display_control_e state); /** - * @brief Gets display turned on state + * @brief Gets display state + * + * @param[in] disp Display handle + * @param[out] state Display state + * + * @return CALLUI_RESULT_OK on success or another result type otherwise + */ +callui_result_e _callui_display_get_state(callui_display_h disp, callui_display_state_e *state); + +/** + * @brief Adds callback for display state change * * @param[in] disp Display handle + * @param[in] cb_func User callback function + * @param[in] cb_data User data * - * @return true if display is turned on or false otherwise + * @return CALLUI_RESULT_OK on success or another result type otherwise + */ +callui_result_e _callui_display_add_display_state_change_cb(callui_display_h disp, + callui_display_state_change_cb cb_func, + void *cb_data); + +/** + * @brief Removes callback for display state change + * + * @param[in] disp Display handle + * @param[in] cb_func User callback function + * @param[in] cb_data User data + * + * @return CALLUI_RESULT_OK on success or another result type otherwise */ -bool _callui_display_is_turned_on(callui_display_h display); +callui_result_e _callui_display_remove_display_state_change_cb(callui_display_h disp, + callui_display_state_change_cb cb_func, + void *cb_data); #endif /* __CALLUI_DISPLAY_H__ */ diff --git a/inc/callui-indicator.h b/inc/callui-indicator.h new file mode 100644 index 0000000..a06a304 --- /dev/null +++ b/inc/callui-indicator.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 __CALLUI_INDICATOR_H__ +#define __CALLUI_INDICATOR_H__ + +#include "callui-common-types.h" + +typedef struct __callui_indicator *callui_indicator_h; + +typedef struct appdata callui_app_data_t; + +/** + * @brief Creates indicator + * + * @param[in] appdata Application data + * + * @return Indicator instance + * + */ +callui_indicator_h _callui_indicator_create(callui_app_data_t *appdata); + +/** + * @brief Deletes indicator + * + * @param[in] indicator Indicator handler + * + */ +void _callui_indicator_destroy(callui_indicator_h indicator); + +/** + * @brief Sets indicator active state + * + * @param[in] indicator Indicator handler + * @param[in] is_active Flag to set indicator state + */ +void _callui_indicator_set_active(callui_indicator_h indicator, bool is_active); + +/** + * @brief Force sets indicator into deactivate state even if indicator is in lock state + * + * @param[in] indicator Indicator handler + */ +void _callui_indicator_force_deativate(callui_indicator_h indicator); +/** + * @brief Sets indicator locked state + * + * @param[in] indicator Indicator handler + * @param[in] is_locked Flag to set indicator state + */ +void _callui_indicator_set_locked(callui_indicator_h indicator, bool is_locked); + +#endif /* __CALLUI_INDICATOR_H__ */ diff --git a/inc/callui-window.h b/inc/callui-window.h index 10de3df..59e0e9d 100644 --- a/inc/callui-window.h +++ b/inc/callui-window.h @@ -194,21 +194,31 @@ callui_result_e _callui_window_unset_keygrab_mode(callui_window_h window_h, cons callui_result_e _callui_window_set_indicator_visible(callui_window_h window_h, bool is_visible); /** - * @brief Sets mode of displaying application window above lock screen + * @brief Sets state of displaying application window above lock screen * - * @param[in] window_h Window handle + * @param[in] window_h Window handle * @param[in] is_above_lockscreen Above lock screen displaying state * * @return CALLUI_RESULT_OK on success or another result otherwise */ -callui_result_e _callui_window_set_above_lockscreen_mode(callui_window_h window_h, bool is_above_lockscreen); + +callui_result_e _callui_window_set_above_lockscreen_state(callui_window_h window_h, bool is_above_lockscreen); + +/** + * @brief Gets state of displaying application window above lock screen + * + * @param[in] window_h Window handle + * + * @return true if above lock screen state is turned on or false otherwise + */ +bool _callui_window_get_above_lockscreen_state(callui_window_h window_h); /** * @brief Sets the quick panel for application window disable/enable state * @remark By default quick panel is enable * - * @param[in] window_h Window handle - * @param[in] is_disable Quick panel disable state to set + * @param[in] window_h Window handle + * @param[in] is_disable Quick panel disable state to set * * @return CALLUI_RESULT_OK on success or another result otherwise */ diff --git a/inc/callui.h b/inc/callui.h index e788f44..e06972e 100755 --- a/inc/callui.h +++ b/inc/callui.h @@ -21,7 +21,9 @@ #include #include #include +#include +#include "callui-common-types.h" #include "callui-view-manager.h" #include "callui-lock-manager.h" #include "callui-keypad.h" @@ -32,6 +34,7 @@ #include "callui-display.h" #include "callui-window.h" #include "callui-dpm.h" +#include "callui-indicator.h" #define CALLUI_APP_HANDLERS_COUNT 1 @@ -72,11 +75,14 @@ struct appdata { app_event_handler_h app_event_handlers[CALLUI_APP_HANDLERS_COUNT]; msg_handle_t msg_handle; + callui_indicator_h indicator; + callui_dpm_h dpm; - double app_pause_time; /* used to detect start time of application goes to pause as device locked with delay */ - bool need_win_minimize; /* used to check if it is needed to minimize application window on device unlock */ + /* used to check if it is needed to minimize application window on device unlock callback */ + bool need_win_minimize; - callui_dpm_h dpm; + Ecore_Timer *app_state_check_timer; + double powerkey_press_time; }; callui_app_data_t *_callui_get_app_data(); diff --git a/src/callui-common.c b/src/callui-common.c index 52f16d1..6ffb812 100755 --- a/src/callui-common.c +++ b/src/callui-common.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "callui-common.h" #include "callui-debug.h" @@ -133,7 +134,8 @@ callui_idle_lock_type_t _callui_common_get_idle_lock_type(void) err("vconf_get_int error"); } - if (lock_state == SYSTEM_SETTINGS_LOCK_STATE_LOCK) { + if (lock_state == SYSTEM_SETTINGS_LOCK_STATE_LOCK + || lock_state == SYSTEM_SETTINGS_LOCK_STATE_LAUNCHING_LOCK) { if (lock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD || lock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD) { ret_val = CALLUI_LOCK_TYPE_SECURITY_LOCK; @@ -181,7 +183,7 @@ static void __update_params_according_lockstate(callui_app_data_t *ad) { callui_idle_lock_type_t type = _callui_common_get_idle_lock_type(); if (type == CALLUI_LOCK_TYPE_SECURITY_LOCK) { - _callui_window_set_above_lockscreen_mode(ad->window, false); + _callui_window_set_above_lockscreen_state(ad->window, false); } if (type != CALLUI_LOCK_TYPE_UNLOCK) { @@ -191,6 +193,8 @@ static void __update_params_according_lockstate(callui_app_data_t *ad) static void __app_launch_reply_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data) { + debug_enter(); + CALLUI_RETURN_IF_FAIL(user_data); callui_app_data_t *ad = user_data; @@ -243,6 +247,8 @@ void _callui_common_launch_setting_bluetooth(void *appdata) */ void _callui_common_launch_dialer(void *appdata) { + debug_enter(); + CALLUI_RETURN_IF_FAIL(appdata); callui_app_data_t *ad = appdata; @@ -276,6 +282,8 @@ void _callui_common_launch_dialer(void *appdata) */ void _callui_common_launch_contacts(void *appdata) { + debug_enter(); + CALLUI_RETURN_IF_FAIL(appdata); callui_app_data_t *ad = appdata; @@ -319,6 +327,9 @@ static void __msg_composer_launch_with_app_exit_reply_cb(app_control_h request, static void __msg_composer_launch_without_app_exit_reply_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data) { __msg_composer_launch_reply_cb(user_data, result); + + callui_app_data_t *ad = user_data; + _callui_indicator_set_locked(ad->indicator, true); } /** @@ -412,7 +423,6 @@ static void __lock_state_changed_cb(system_settings_key_e key, void *user_data) if (_callui_common_get_idle_lock_type() == CALLUI_LOCK_TYPE_UNLOCK) { dbg("Device lock state [UNLOCKED]"); - _callui_window_set_above_lockscreen_mode(ad->window, false); if (ad->need_win_minimize) { ad->need_win_minimize = false; _callui_window_minimize(ad->window); @@ -421,16 +431,9 @@ static void __lock_state_changed_cb(system_settings_key_e key, void *user_data) dbg("Device lock state [LOCKED]"); if (!ad->on_background) { dbg("App on background [NO]"); - _callui_window_set_above_lockscreen_mode(ad->window, true); } else { dbg("App on background [YES]"); - double time_diff = ecore_time_get() - ad->app_pause_time; - dbg("Pause and Lock time diff [%lf]", time_diff); - if (time_diff <= CALLUI_PAUSE_LOCK_TIMEOUT_LIMIT_SEC) { - _callui_window_set_above_lockscreen_mode(ad->window, true); - ad->app_pause_time = 0.0; - ad->on_background = false; - } + if (_callui_lock_manager_is_started(ad->lock_handle)) { _callui_lock_manager_stop(ad->lock_handle); ad->start_lock_manager_on_resume = true; diff --git a/src/callui-display.c b/src/callui-display.c index 74486b0..47d0031 100644 --- a/src/callui-display.c +++ b/src/callui-display.c @@ -21,56 +21,73 @@ #include #include #include +#include #include "callui.h" #include "callui-display.h" #include "callui-debug.h" #include "callui-common-defines.h" +#include "callui-listeners-collection.h" struct __callui_display { GDBusConnection *conn; GCancellable *cancel_obj; callui_app_data_t *ad; + _callui_listeners_coll_t display_state_lc; }; typedef struct __callui_display __callui_display_t; -#define CALLUI_BUS_NAME "org.tizen.system.deviced" +#define CALLUI_BUS_NAME "org.tizen.system.deviced" #define CALLUI_OBJECT_PATH "/Org/Tizen/System/DeviceD" #define CALLUI_INTERFACE_NAME CALLUI_BUS_NAME -#define CALLUI_DEVICED_PATH_DISPLAY CALLUI_OBJECT_PATH"/Display" +#define CALLUI_DEVICED_PATH_DISPLAY CALLUI_OBJECT_PATH"/Display" #define CALLUI_DEVICED_INTERFACE_DISPLAY CALLUI_INTERFACE_NAME".display" #define CALLUI_METHOD_SET_DISPLAY_TIMEOUT "setlcdtimeout" #define CALLUI_TIMEOUT_PARAMS_COUNT 3 #define CALLUI_DBUS_REPLY_TIMEOUT (120 * 1000) -static callui_result_e _callui_display_init(callui_display_h display, callui_app_data_t *appdata); -static void _callui_display_deinit(callui_display_h display); -static callui_result_e __send_gdbus_msg_async(callui_display_h display, int *param); +static callui_result_e _callui_display_init(callui_display_h disp, callui_app_data_t *appdata); +static void _callui_display_deinit(callui_display_h disp); +static callui_result_e __send_gdbus_msg_async(callui_display_h disp, int *param); static void __gdbus_reply_msg_async_cb(GObject *source_object, GAsyncResult *res, gpointer user_data); +static void __display_state_changed_cb(device_callback_e type, void *value, void *data); +static void __display_state_change_handler_func(_callui_listener_t *listener, va_list args); + +static void __display_state_changed_cb(device_callback_e type, void *value, void *data) +{ + callui_display_h display = data; + _callui_listeners_coll_call_listeners(&display->display_state_lc); +} /** * @brief Deinitializes display instance * - * @param[in] display Display handle + * @param[in] disp Display handle * @param[in] appdata Application data * * @result CALLUI_RESULT_OK on success or other result otherwise */ -static callui_result_e _callui_display_init(callui_display_h display, callui_app_data_t *appdata) +static callui_result_e _callui_display_init(callui_display_h disp, callui_app_data_t *appdata) { - display->ad = appdata; + disp->ad = appdata; GError *err = NULL; - display->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + disp->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); if (err) { err("Connection error occurred. [%d]-[%s]", err->code, err->message); g_error_free(err); return CALLUI_RESULT_FAIL; } - display->cancel_obj = g_cancellable_new(); - CALLUI_RETURN_VALUE_IF_FAIL(display->cancel_obj, CALLUI_RESULT_FAIL); + disp->cancel_obj = g_cancellable_new(); + CALLUI_RETURN_VALUE_IF_FAIL(disp->cancel_obj, CALLUI_RESULT_FAIL); + + int res = _callui_listeners_coll_init(&disp->display_state_lc); + CALLUI_RETURN_VALUE_IF_FAIL(res == CALLUI_RESULT_OK, res); + + res = device_add_callback(DEVICE_CALLBACK_DISPLAY_STATE, __display_state_changed_cb, disp); + CALLUI_RETURN_VALUE_IF_FAIL(res == DEVICE_ERROR_NONE, CALLUI_RESULT_FAIL); return CALLUI_RESULT_OK; } @@ -78,13 +95,15 @@ static callui_result_e _callui_display_init(callui_display_h display, callui_app /** * @brief Deinitializes display instance * - * @param[in] display Display handle + * @param[in] disp Display handle */ -static void _callui_display_deinit(callui_display_h display) +static void _callui_display_deinit(callui_display_h disp) { - g_cancellable_cancel(display->cancel_obj); - g_object_unref (display->cancel_obj); - g_object_unref(display->conn); + g_cancellable_cancel(disp->cancel_obj); + g_object_unref (disp->cancel_obj); + g_object_unref(disp->conn); + + _callui_listeners_coll_deinit(&disp->display_state_lc); } /** @@ -114,13 +133,13 @@ callui_display_h _callui_display_create(callui_app_data_t *appdata) * * @param[in] disp Display handle */ -void _callui_display_destroy(callui_display_h display) +void _callui_display_destroy(callui_display_h disp) { - CALLUI_RETURN_IF_FAIL(display); + CALLUI_RETURN_IF_FAIL(disp); - _callui_display_deinit(display); + _callui_display_deinit(disp); - free(display); + free(disp); } static void __gdbus_reply_msg_async_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) @@ -149,9 +168,9 @@ static void __gdbus_reply_msg_async_cb(GObject *source_object, GAsyncResult *res debug_leave(); } -static callui_result_e __send_gdbus_msg_async(callui_display_h display, int *param) +static callui_result_e __send_gdbus_msg_async(callui_display_h disp, int *param) { - if (!display->conn) { + if (!disp->conn) { return CALLUI_RESULT_FAIL; } @@ -174,12 +193,12 @@ static callui_result_e __send_gdbus_msg_async(callui_display_h display, int *par g_dbus_message_set_body(msg, arguments); g_dbus_connection_send_message_with_reply( - display->conn, + disp->conn, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, CALLUI_DBUS_REPLY_TIMEOUT, NULL, - display->cancel_obj, + disp->cancel_obj, __gdbus_reply_msg_async_cb, NULL); @@ -196,11 +215,11 @@ static callui_result_e __send_gdbus_msg_async(callui_display_h display, int *par * * @return CALLUI_RESULT_OK on success or another result type otherwise */ -callui_result_e _callui_display_set_timeout(callui_display_h display, callui_display_timeout_e timeout_type) +callui_result_e _callui_display_set_timeout(callui_display_h disp, callui_display_timeout_e timeout_type) { debug_enter(); - CALLUI_RETURN_VALUE_IF_FAIL(display, CALLUI_RESULT_INVALID_PARAM); + CALLUI_RETURN_VALUE_IF_FAIL(disp, CALLUI_RESULT_INVALID_PARAM); CALLUI_RETURN_VALUE_IF_FAIL((timeout_type >= CALLUI_DISPLAY_TIMEOUT_DEFAULT) && (timeout_type <= CALLUI_DISPLAY_TIMEOUT_LS_SET), CALLUI_RESULT_INVALID_PARAM); @@ -231,7 +250,7 @@ callui_result_e _callui_display_set_timeout(callui_display_h display, callui_dis default: break; } - return __send_gdbus_msg_async(display, timeout_params); + return __send_gdbus_msg_async(disp, timeout_params); } /** @@ -242,48 +261,48 @@ callui_result_e _callui_display_set_timeout(callui_display_h display, callui_dis * * @return CALLUI_RESULT_OK on success or another result type otherwise */ -callui_result_e _callui_display_set_control_state(callui_display_h display, callui_display_control_e state) +callui_result_e _callui_display_set_control_state(callui_display_h disp, callui_display_control_e state) { debug_enter(); - CALLUI_RETURN_VALUE_IF_FAIL(display, CALLUI_RESULT_INVALID_PARAM); + CALLUI_RETURN_VALUE_IF_FAIL(disp, CALLUI_RESULT_INVALID_PARAM); dbg("[%d]", state); int result = -1; switch (state) { - case CALLUI_DISPLAY_ON: + case CALLUI_DISPLAY_CONTROL_ON: result = device_display_change_state(DISPLAY_STATE_NORMAL); CALLUI_RETURN_VALUE_IF_FAIL(result == DEVICE_ERROR_NONE, CALLUI_RESULT_FAIL); break; - case CALLUI_DISPLAY_ON_LOCK: + case CALLUI_DISPLAY_CONTROL_ON_LOCK: result = device_display_change_state(DISPLAY_STATE_NORMAL); CALLUI_RETURN_VALUE_IF_FAIL(result == DEVICE_ERROR_NONE, CALLUI_RESULT_FAIL); - result = _callui_window_set_screen_mode(display->ad->window, CALLUI_WIN_SCREEN_MODE_ALWAYS_ON); + result = _callui_window_set_screen_mode(disp->ad->window, CALLUI_WIN_SCREEN_MODE_ALWAYS_ON); CALLUI_RETURN_VALUE_IF_FAIL(result == CALLUI_RESULT_OK, result); break; - case CALLUI_DISPLAY_ON_UNLOCK: + case CALLUI_DISPLAY_CONTROL_ON_UNLOCK: result = device_display_change_state(DISPLAY_STATE_NORMAL); CALLUI_RETURN_VALUE_IF_FAIL(result == DEVICE_ERROR_NONE, CALLUI_RESULT_FAIL); - result = _callui_window_set_screen_mode(display->ad->window, CALLUI_WIN_SCREEN_MODE_DEFAULT); + result = _callui_window_set_screen_mode(disp->ad->window, CALLUI_WIN_SCREEN_MODE_DEFAULT); CALLUI_RETURN_VALUE_IF_FAIL(result == CALLUI_RESULT_OK, result); result = device_power_release_lock(POWER_LOCK_CPU); CALLUI_RETURN_VALUE_IF_FAIL(result == DEVICE_ERROR_NONE, CALLUI_RESULT_FAIL); break; - case CALLUI_DISPLAY_UNLOCK: - result = _callui_window_set_screen_mode(display->ad->window, CALLUI_WIN_SCREEN_MODE_DEFAULT); + case CALLUI_DISPLAY_CONTROL_UNLOCK: + result = _callui_window_set_screen_mode(disp->ad->window, CALLUI_WIN_SCREEN_MODE_DEFAULT); CALLUI_RETURN_VALUE_IF_FAIL(result == CALLUI_RESULT_OK, result); result = device_power_release_lock(POWER_LOCK_CPU); CALLUI_RETURN_VALUE_IF_FAIL(result == EFL_UTIL_ERROR_NONE, CALLUI_RESULT_FAIL); break; - case CALLUI_DISPLAY_OFF_SLEEP_LOCK: + case CALLUI_DISPLAY_CONTROL_OFF_SLEEP_LOCK: result = device_power_request_lock(POWER_LOCK_CPU, 0); CALLUI_RETURN_VALUE_IF_FAIL(result == EFL_UTIL_ERROR_NONE, CALLUI_RESULT_FAIL); break; - case CALLUI_DISPLAY_OFF_SLEEP_UNLOCK: + case CALLUI_DISPLAY_CONTROL_OFF_SLEEP_UNLOCK: result = device_power_release_lock(POWER_LOCK_CPU); CALLUI_RETURN_VALUE_IF_FAIL(result == EFL_UTIL_ERROR_NONE, CALLUI_RESULT_FAIL); break; - case CALLUI_DISPLAY_OFF: + case CALLUI_DISPLAY_CONTROL_OFF: result = device_display_change_state(DISPLAY_STATE_SCREEN_OFF); CALLUI_RETURN_VALUE_IF_FAIL(result == EFL_UTIL_ERROR_NONE, CALLUI_RESULT_FAIL); break; @@ -294,19 +313,81 @@ callui_result_e _callui_display_set_control_state(callui_display_h display, call } /** - * @brief Gets display turned on state + * @brief Gets display state * * @param[in] disp Display handle + * @param[out] state Display state * - * @return true if display is turned on or false otherwise + * @return CALLUI_RESULT_OK on success or another result type otherwise */ -bool _callui_display_is_turned_on(callui_display_h display) +callui_result_e _callui_display_get_state(callui_display_h disp, callui_display_state_e *state) { - CALLUI_RETURN_VALUE_IF_FAIL(display, false); + CALLUI_RETURN_VALUE_IF_FAIL(disp, CALLUI_RESULT_FAIL); display_state_e disp_state = DISPLAY_STATE_NORMAL; int res = device_display_get_state(&disp_state); - CALLUI_RETURN_VALUE_IF_FAIL(res == DEVICE_ERROR_NONE, false); + CALLUI_RETURN_VALUE_IF_FAIL(res == DEVICE_ERROR_NONE, CALLUI_RESULT_FAIL); + + switch (disp_state) { + case DISPLAY_STATE_NORMAL: + dbg("Display screen state [ON]"); + *state = CALLUI_DISPLAY_NORMAL; + break; + case DISPLAY_STATE_SCREEN_DIM: + dbg("Display screen state [DIM]"); + *state = CALLUI_DISPLAY_DIM; + break; + case DISPLAY_STATE_SCREEN_OFF: + dbg("Display screen state [OFF]"); + *state = CALLUI_DISPLAY_OFF; + break; + default: + err("Get correct display state failed"); + return CALLUI_RESULT_FAIL; + } + return CALLUI_RESULT_OK; +} + +static void __display_state_change_handler_func(_callui_listener_t *listener, va_list args) +{ + ((callui_display_state_change_cb)(listener->cb_func))(listener->cb_data); +} + +/** + * @brief Adds callback for display state change + * + * @param[in] disp Display handle + * @param[in] cb_func User callback function + * @param[in] cb_data User data + * + * @return CALLUI_RESULT_OK on success or another result type otherwise + */ +callui_result_e _callui_display_add_display_state_change_cb(callui_display_h disp, + callui_display_state_change_cb cb_func, + void *cb_data) +{ + CALLUI_RETURN_VALUE_IF_FAIL(disp, CALLUI_RESULT_INVALID_PARAM); + CALLUI_RETURN_VALUE_IF_FAIL(cb_func, CALLUI_RESULT_INVALID_PARAM); + + return _callui_listeners_coll_add_listener(&disp->display_state_lc, + __display_state_change_handler_func, cb_func, cb_data); +} + +/** + * @brief Removes callback for display state change + * + * @param[in] disp Display handle + * @param[in] cb_func User callback function + * @param[in] cb_data User data + * + * @return CALLUI_RESULT_OK on success or another result type otherwise + */ +callui_result_e _callui_display_remove_display_state_change_cb(callui_display_h disp, + callui_display_state_change_cb cb_func, + void *cb_data) +{ + CALLUI_RETURN_VALUE_IF_FAIL(disp, CALLUI_RESULT_INVALID_PARAM); + CALLUI_RETURN_VALUE_IF_FAIL(cb_func, CALLUI_RESULT_INVALID_PARAM); - return (disp_state == DISPLAY_STATE_NORMAL || disp_state == DISPLAY_STATE_SCREEN_DIM); + return _callui_listeners_coll_remove_listener(&disp->display_state_lc, cb_func, cb_data); } diff --git a/src/callui-indicator.c b/src/callui-indicator.c new file mode 100644 index 0000000..8f3c30d --- /dev/null +++ b/src/callui-indicator.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 "callui-indicator.h" +#include "callui.h" +#include "callui-debug.h" +#include "callui-common-defines.h" + +#define CALLUI_LOCAL_PORT_NAME "callui/indicator" +#define CALLUI_REMOTE_PORT_NAME "indicator/bg/color" + +#define CALLUI_KEY_BG "indicator/bg/color" +#define CALLUI_KEY_VALUE_BG_CALL "indicator/bg/color/call" + +#define CALLUI_INDICATOR_APP "org.tizen.indicator" + +typedef enum { + CALLUI_INDICATOR_DEFAULT = 0, + CALLUI_INDICATOR_DURING_CALL, + CALLUI_INDICATOR_CALL_ON_HOLD, + CALLUI_INDICATOR_END_CALL, + CALLUI_INDICATOR_COUNT +} __callui_indicator_type_e; + +static const char *color_param[CALLUI_INDICATOR_COUNT] = { + "call/idle", /* Default bg color */ + "call/during_call", /* Incoming call or during call */ + "call/on_hold", /* Call on hold */ + "call/end_call" /* Call ended */ +}; + +struct __callui_indicator { + + int local_port_id; + bool active; + bool locked; + callui_app_data_t *ad; + __callui_indicator_type_e cur_type; +}; +typedef struct __callui_indicator __callui_indicator_t; + +typedef struct appdata callui_app_data_t; + +static callui_result_e __callui_indicator_init(callui_indicator_h indicator, callui_app_data_t *ad); +static void __callui_indicator_deinit(callui_indicator_h indicator); + +static void __reset_indicator_color(callui_indicator_h indicator); +static void __refresh_indicator_color(callui_indicator_h indicator); + +static callui_result_e __register_local_msg_port(callui_indicator_h indicator, const char *port_name); +static void __unregister_local_msg_port(callui_indicator_h indicator); + +static callui_result_e __convert_msg_port_result(int err); +static void __msg_port_cb(int trusted_local_port_id, const char *remote_app_id, + const char *remote_port, bool trusted_remote_port, bundle *message, void *data); + +static bundle *__create_color_change_msg(__callui_indicator_type_e type); +static callui_result_e __send_color_change_msg(callui_indicator_h indicator, bundle *message); + +void __state_event_cb(void *user_data, + callui_call_event_type_e call_event_type, + unsigned int call_id, + callui_sim_slot_type_e sim_type, + void *event_info) +{ + debug_enter(); + callui_indicator_h indicator = user_data; + if (indicator->active) { + __refresh_indicator_color(user_data); + } +} + +static callui_result_e __callui_indicator_init(callui_indicator_h indicator, callui_app_data_t *ad) +{ + indicator->ad = ad; + indicator->cur_type = CALLUI_INDICATOR_DEFAULT; + + CALLUI_RETURN_VALUE_IF_FAIL(ad->state_provider, CALLUI_RESULT_FAIL); + callui_result_e res = _callui_stp_add_call_state_event_cb(indicator->ad->state_provider, __state_event_cb, indicator); + CALLUI_RETURN_VALUE_IF_FAIL(res == CALLUI_RESULT_OK, res); + + bool port_exists = false; + res = __convert_msg_port_result( + message_port_check_trusted_remote_port(CALLUI_INDICATOR_APP, CALLUI_REMOTE_PORT_NAME, &port_exists)); + CALLUI_RETURN_VALUE_IF_FAIL(res == CALLUI_RESULT_OK, res); + + if (port_exists) { + return __register_local_msg_port(indicator, CALLUI_LOCAL_PORT_NAME); + } else { + return CALLUI_RESULT_NOT_REGISTERED; + } +} + +static void __reset_indicator_color(callui_indicator_h indicator) +{ + if (indicator->cur_type != CALLUI_INDICATOR_DEFAULT) { + dbg("Indicator is not default type. Current type [%d]. Need to reset to default", indicator->cur_type); + indicator->cur_type = CALLUI_INDICATOR_DEFAULT; + bundle *msg = __create_color_change_msg(indicator->cur_type); + CALLUI_RETURN_IF_FAIL(msg); + callui_result_e res = __send_color_change_msg(indicator, msg); + if (res != CALLUI_RESULT_OK) { + err("Call __send_color_change_msg() failed. res[%d]", res); + } + } +} + +static void __callui_indicator_deinit(callui_indicator_h indicator) +{ + _callui_stp_remove_call_state_event_cb(indicator->ad->state_provider, __state_event_cb, indicator); + + if (indicator->local_port_id) { + __reset_indicator_color(indicator); + __unregister_local_msg_port(indicator); + } +} + +static callui_result_e __convert_msg_port_result(int err) +{ + int result = CALLUI_RESULT_FAIL; + + switch (err) { + case MESSAGE_PORT_ERROR_NONE: + result = CALLUI_RESULT_OK; + break; + case MESSAGE_PORT_ERROR_IO_ERROR: + err("MessagePort error: i/o error"); + break; + case MESSAGE_PORT_ERROR_OUT_OF_MEMORY: + err("MessagePort error: out of memory"); + break; + case MESSAGE_PORT_ERROR_INVALID_PARAMETER: + err("MessagePort error: invalid parameter"); + break; + case MESSAGE_PORT_ERROR_PORT_NOT_FOUND: + err("MessagePort error: message port not found"); + break; + case MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH: + err("MessagePort error: certificate not match"); + break; + case MESSAGE_PORT_ERROR_MAX_EXCEEDED: + err("MessagePort error: max exceeded"); + break; + default: + err("MessagePort error: unknown error"); + break; + } + return result; +} + +static void __msg_port_cb(int trusted_local_port_id, const char *remote_app_id, + const char *remote_port, bool trusted_remote_port, bundle *message, void *data) +{ + debug_enter(); + + callui_indicator_h indicator = data; + + elm_win_render(_callui_window_get_eo(indicator->ad->window)); +} + +static callui_result_e __register_local_msg_port(callui_indicator_h indicator, const char *port_name) +{ + int temp_id = message_port_register_trusted_local_port(port_name, __msg_port_cb, indicator); + + if (temp_id < 0) { + err("Failed to register local message port"); + indicator->local_port_id = 0; + return __convert_msg_port_result(temp_id); + } + + dbg("Message port %s registered with id: %d", port_name, temp_id); + indicator->local_port_id = temp_id; + + return CALLUI_RESULT_OK; +} + +static void __unregister_local_msg_port(callui_indicator_h indicator) +{ + callui_result_e res = __convert_msg_port_result( + message_port_unregister_trusted_local_port(indicator->local_port_id)); + if (res) { + err("Failed to unregister local message port [%d]", indicator->local_port_id); + } +} + +callui_indicator_h _callui_indicator_create(callui_app_data_t *appdata) +{ + CALLUI_RETURN_NULL_IF_FAIL(appdata); + + callui_indicator_h indicator = calloc(1, sizeof(__callui_indicator_t)); + CALLUI_RETURN_NULL_IF_FAIL(indicator); + + callui_result_e res = __callui_indicator_init(indicator, appdata); + if (res != CALLUI_RESULT_OK) { + err("Init indicator failed. res[%d]", res); + __callui_indicator_deinit(indicator); + FREE(indicator); + } + return indicator; +} + +void _callui_indicator_destroy(callui_indicator_h indicator) +{ + CALLUI_RETURN_IF_FAIL(indicator); + + __callui_indicator_deinit(indicator); + + free(indicator); +} + +static void __refresh_indicator_color(callui_indicator_h indicator) +{ + callui_app_data_t *ad = indicator->ad; + + if (!ad->state_provider) { + err("State provider is NULL"); + return; + } + + const callui_call_data_t *incom = _callui_stp_get_call_data(ad->state_provider, + CALLUI_CALL_DATA_INCOMING); + const callui_call_data_t *active = _callui_stp_get_call_data(ad->state_provider, + CALLUI_CALL_DATA_ACTIVE); + const callui_call_data_t *held = _callui_stp_get_call_data(ad->state_provider, + CALLUI_CALL_DATA_HELD); + + __callui_indicator_type_e type = CALLUI_INDICATOR_DEFAULT; + + if (active || incom) { + type = CALLUI_INDICATOR_DURING_CALL; + } else if (held) { + type = CALLUI_INDICATOR_CALL_ON_HOLD; + } else if (!incom && !active && !held) { + type = CALLUI_INDICATOR_END_CALL; + } + + if (type != indicator->cur_type) { + indicator->cur_type = type; + bundle *msg = __create_color_change_msg(type); + CALLUI_RETURN_IF_FAIL(msg); + callui_result_e res = __send_color_change_msg(indicator, msg); + if (res != CALLUI_RESULT_OK) { + err("Call __send_color_change_msg() failed. res[%d]", res); + } + } +} + +void _callui_indicator_set_active(callui_indicator_h indicator, bool is_active) +{ + CALLUI_RETURN_IF_FAIL(indicator); + + if (indicator->locked) { + dbg("Indicator is locked. Set [%s] state ignored!", is_active? "active":"not active"); + return; + } + + if (indicator->active == is_active) { + dbg("Already [%s]", is_active ? "active" : "not active"); + return; + } + + indicator->active = is_active; + + if (indicator->active) { + dbg("Indicator is active. Try to refresh indicator color..."); + __refresh_indicator_color(indicator); + } else { + dbg("Indicator is not active. Try to reset to default indicator color..."); + __reset_indicator_color(indicator); + } +} + +void _callui_indicator_force_deativate(callui_indicator_h indicator) +{ + CALLUI_RETURN_IF_FAIL(indicator); + + indicator->active = false; + __reset_indicator_color(indicator); +} + +void _callui_indicator_set_locked(callui_indicator_h indicator, bool is_locked) +{ + CALLUI_RETURN_IF_FAIL(indicator); + + indicator->locked = is_locked; +} + +static bundle *__create_color_change_msg(__callui_indicator_type_e type) +{ + bundle *message = bundle_create(); + CALLUI_RETURN_NULL_IF_FAIL(message); + + dbg("INDICATOR TYPE TO SET [%d]", type); + bundle_add_str(message, CALLUI_KEY_BG, CALLUI_KEY_VALUE_BG_CALL); + bundle_add_str(message, CALLUI_KEY_VALUE_BG_CALL, color_param[type]); + + return message; +} + +static callui_result_e __send_color_change_msg(callui_indicator_h indicator, bundle *message) +{ + callui_result_e res = __convert_msg_port_result(message_port_send_trusted_message_with_local_port(CALLUI_INDICATOR_APP, + CALLUI_REMOTE_PORT_NAME, message, indicator->local_port_id)); + + bundle_free(message); + return res; +} diff --git a/src/callui-listeners-collection.c b/src/callui-listeners-collection.c index 93a2acd..24b50a8 100644 --- a/src/callui-listeners-collection.c +++ b/src/callui-listeners-collection.c @@ -163,7 +163,6 @@ callui_result_e _callui_listeners_coll_add_listener(_callui_listeners_coll_t *li */ callui_result_e _callui_listeners_coll_call_listeners(_callui_listeners_coll_t *listeners_coll, ...) { - debug_enter(); CALLUI_RETURN_VALUE_IF_FAIL(listeners_coll, CALLUI_RESULT_INVALID_PARAM); CALLUI_RETURN_VALUE_IF_FAIL(listeners_coll->is_initialized, CALLUI_RESULT_FAIL); @@ -188,7 +187,6 @@ callui_result_e _callui_listeners_coll_call_listeners(_callui_listeners_coll_t * __delete_empty_listeners(listeners_coll); listeners_coll->is_need_validate = false; } - debug_leave(); return CALLUI_RESULT_OK; } diff --git a/src/callui-proximity-lock-manager.c b/src/callui-proximity-lock-manager.c index 85d4a95..784b2a8 100644 --- a/src/callui-proximity-lock-manager.c +++ b/src/callui-proximity-lock-manager.c @@ -134,7 +134,7 @@ static void __callui_proximity_lock_manager_turn_lcd_on(_callui_proximity_lock_t callui_app_data_t *ad = _callui_get_app_data(); dbg("Turn display [ON]"); - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_ON); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_ON); proximity_h->lcd_state = CALLUI_PLM_LCD_ON; if (proximity_h->unlock_cb) { @@ -148,6 +148,10 @@ static Eina_Bool __callui_proximity_lock_manager_turn_lcd_on_timer_cb(void *data { _callui_proximity_lock_t *proximity_h = data; + /* Unlock indicator color change mechanism */ + callui_app_data_t *ad = _callui_get_app_data(); + _callui_indicator_set_locked(ad->indicator, false); + __callui_proximity_lock_manager_turn_lcd_on(proximity_h); proximity_h->lcd_turn_on_timer = NULL; @@ -176,13 +180,19 @@ static void __callui_proximity_lock_manager_cb(sensor_h sensor, sensor_event_s * proximity_h->lcd_turn_on_timer = ecore_timer_add(CALLUI_LCD_TURN_ON_DELAY_INTERVAL, __callui_proximity_lock_manager_turn_lcd_on_timer_cb, proximity_h); } } else { - if (_callui_display_is_turned_on(ad->display)) { + + callui_display_state_e state; + if (_callui_display_get_state(ad->display, &state) == CALLUI_RESULT_OK && state != CALLUI_DISPLAY_OFF) { if (proximity_h->lcd_turn_on_timer) { dbg("Cancel request on turn display [ON] with delay"); DELETE_ECORE_TIMER(proximity_h->lcd_turn_on_timer); } else { dbg("Turn display [OFF]"); - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_OFF); + + /* Lock indicator to not change its color while proximity sensor is turn display off */ + _callui_indicator_set_locked(ad->indicator, true); + + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_OFF); proximity_h->lcd_state = CALLUI_PLM_LCD_OFF; } } else { @@ -241,13 +251,12 @@ static void __callui_proximity_lock_manager_start(void *lock_h) } } -#ifdef _DBUS_DISPLAY_DEVICE_TIMEOUT_ callui_app_data_t *ad = _callui_get_app_data(); +#ifdef _DBUS_DISPLAY_DEVICE_TIMEOUT_ _callui_display_set_timeout(ad->display, CALLUI_DISPLAY_TIMEOUT_SET); #endif - proximity_h->run_state = CALLUI_PLM_STATE_STARTED; - proximity_h->lcd_state = _callui_display_is_turned_on(ad->display) ? CALLUI_PLM_LCD_ON : CALLUI_PLM_LCD_OFF; + proximity_h->lcd_state = CALLUI_PLM_LCD_UNDEFINED; } static void __callui_proximity_lock_manager_force_stop(void *lock_h, bool force) @@ -265,7 +274,7 @@ static void __callui_proximity_lock_manager_force_stop(void *lock_h, bool force) static void __callui_proximity_lock_manager_stop(void *lock_h) { - dbg(".."); + debug_enter(); CALLUI_RETURN_IF_FAIL(lock_h); _callui_proximity_lock_t *proximity_h = (_callui_proximity_lock_t *)lock_h; int ret = sensor_listener_stop(proximity_h->sensor_listener); @@ -301,6 +310,7 @@ static bool __callui_proximity_lock_manager_is_lcd_off(void *lock_h) dbg(".."); CALLUI_RETURN_VALUE_IF_FAIL(lock_h, false); _callui_proximity_lock_t *proximity_h = (_callui_proximity_lock_t *)lock_h; + dbg("Proximity lock manager LCD state [%s]", (proximity_h->lcd_state == CALLUI_PLM_LCD_OFF) ? "OFF":"ON"); return (proximity_h->lcd_state == CALLUI_PLM_LCD_OFF); } diff --git a/src/callui-view-callend.c b/src/callui-view-callend.c index 054767b..8319dba 100644 --- a/src/callui-view-callend.c +++ b/src/callui-view-callend.c @@ -132,9 +132,10 @@ static callui_result_e __callui_view_callend_oncreate(call_view_data_base_t *vie CALLUI_RETURN_VALUE_IF_FAIL(appdata, CALLUI_RESULT_INVALID_PARAM); callui_view_callend_h vd = (callui_view_callend_h)view_data; - callui_app_data_t *ad = (callui_app_data_t *)appdata; + vd->base_view.ad = appdata; - vd->base_view.ad = ad; + vd->base_view.ad->start_lock_manager_on_resume = false; + _callui_lock_manager_stop(vd->base_view.ad->lock_handle); callui_result_e res = __create_main_content(vd, parent); CALLUI_RETURN_VALUE_IF_FAIL(res == CALLUI_RESULT_OK, res); diff --git a/src/callui-view-incoming-call.c b/src/callui-view-incoming-call.c index 5814b28..257e391 100644 --- a/src/callui-view-incoming-call.c +++ b/src/callui-view-incoming-call.c @@ -128,9 +128,6 @@ static callui_result_e __callui_view_incoming_call_oncreate(call_view_data_base_ _callui_window_set_size_type(ad->window, CALLUI_WIN_SIZE_FULLSCREEN); _callui_window_set_rotation_locked(ad->window, true); - _callui_window_set_above_lockscreen_mode(ad->window, true); - -// evas_object_pointer_mode_set(ad->win, EVAS_OBJECT_POINTER_MODE_NOGRAB); if (_callui_window_set_keygrab_mode(ad->window, CALLUI_KEY_SELECT, CALLUI_WIN_KEYGRAB_TOPMOST) != CALLUI_RESULT_OK) { dbg("KEY_SELECT key grab failed"); diff --git a/src/callui-view-quickpanel.c b/src/callui-view-quickpanel.c index d03cc02..b1b8011 100755 --- a/src/callui-view-quickpanel.c +++ b/src/callui-view-quickpanel.c @@ -300,8 +300,6 @@ static void __main_layout_mouse_up_cb(void *data, Evas *evas, Evas_Object *obj, err("app_control_send_launch_request() is failed. ret[%d]", ret); } else { callui_app_data_t *ad = qp->ad; - - ad->on_background = false; _callui_lock_manager_start(ad->lock_handle); __hide_minicontrol(qp); } diff --git a/src/callui-window.c b/src/callui-window.c index 1191d57..4a8c1ef 100644 --- a/src/callui-window.c +++ b/src/callui-window.c @@ -24,6 +24,7 @@ #include "callui-common-defines.h" #include "callui-debug.h" #include "callui-view-layout.h" +#include "callui-common.h" #define CALLUI_WIN_ACT_NOTI_HEIGHT ELM_SCALE_SIZE(413) #define CALLUI_WIN_ACT_NOTI_ROTATION_COUNT 4 @@ -57,6 +58,7 @@ static callui_result_e __eo_win_set_rotation_locked(callui_window_h window_h, bo static void __eo_win_move_and_resize(callui_window_h window_h, bool force_resize); static Elm_Win_Keygrab_Mode __convert_app_keygrab_mode(callui_win_keygrab_mode_e mode); static callui_result_e __create_tzsh_qp(callui_window_h window_h); +static callui_result_e __set_above_lockscreen_state(callui_window_h window_h, bool above_lockscreen); static callui_result_e __create_tzsh_qp(callui_window_h window_h) { @@ -169,6 +171,9 @@ callui_result_e __callui_window_init(callui_window_h window_h, callui_app_data_t callui_result_e res = __create_tzsh_qp(window_h); CALLUI_RETURN_VALUE_IF_FAIL(res == CALLUI_RESULT_OK, CALLUI_RESULT_FAIL); + res = __set_above_lockscreen_state(window_h, true); + CALLUI_RETURN_VALUE_IF_FAIL(res == CALLUI_RESULT_OK, CALLUI_RESULT_FAIL); + __eo_win_update_size(window_h, CALLUI_WIN_SIZE_ACTIVE_NOTI); return __eo_win_set_rotation_locked(window_h, true); @@ -425,12 +430,10 @@ callui_result_e _callui_window_set_indicator_visible(callui_window_h window_h, b return CALLUI_RESULT_OK; } -callui_result_e _callui_window_set_above_lockscreen_mode(callui_window_h window_h, bool above_lockscreen) +static callui_result_e __set_above_lockscreen_state(callui_window_h window_h, bool above_lockscreen) { CALLUI_RETURN_VALUE_IF_FAIL(window_h, CALLUI_RESULT_INVALID_PARAM); - dbg("Above lock screen [%s]", above_lockscreen ? "YES" : "NO"); - int id = elm_win_aux_hint_id_get(window_h->win, "wm.policy.win.above.lock"); if (above_lockscreen) { if (id == -1) { @@ -448,6 +451,34 @@ callui_result_e _callui_window_set_above_lockscreen_mode(callui_window_h window_ return CALLUI_RESULT_OK; } +callui_result_e _callui_window_set_above_lockscreen_state(callui_window_h window_h, bool above_lockscreen) +{ + CALLUI_RETURN_VALUE_IF_FAIL(window_h, CALLUI_RESULT_INVALID_PARAM); + + dbg("Set above lock screen state [%s]", above_lockscreen ? "YES" : "NO"); + + return __set_above_lockscreen_state(window_h, above_lockscreen); +} + +bool _callui_window_get_above_lockscreen_state(callui_window_h window_h) +{ + CALLUI_RETURN_VALUE_IF_FAIL(window_h, false); + + bool res = false; + int id = elm_win_aux_hint_id_get(window_h->win, "wm.policy.win.above.lock"); + if (id >= 0) { + const char *value = elm_win_aux_hint_val_get(window_h->win, id); + if(value) { + sec_dbg("Aux hint value [%s]", value); + if (!strcmp(value, "1")) { + res = true; + } + } + } + dbg("Above lock screen state [%s]", res ? "YES" : "NO"); + return res; +} + callui_result_e _callui_window_set_quickpanel_disable(callui_window_h window_h, bool is_disable) { CALLUI_RETURN_VALUE_IF_FAIL(window_h, CALLUI_RESULT_INVALID_PARAM); diff --git a/src/callui.c b/src/callui.c index 1ac5c6d..ce2088b 100755 --- a/src/callui.c +++ b/src/callui.c @@ -30,12 +30,19 @@ #include "callui-sound-manager.h" #include "callui-state-provider.h" +#define CALLUI_KEY_HOME "XF86Home" #define CALLUI_KEY_BACK "XF86Back" #define CALLUI_KEY_MEDIA "XF86AudioMedia" -#define CALLUI_KEY_HOME "XF86Home" #define CALLUI_KEY_VOLUMEUP "XF86AudioRaiseVolume" #define CALLUI_KEY_VOLUMEDOWN "XF86AudioLowerVolume" +#define CALLUI_EARSET_KEY_LONG_PRESS_TIMEOUT_SEC 1.0 +#define CALLUI_APP_STATE_TIMEOUT_SEC 0.3 +#define CALLUI_POWERKEY_PRESS_TIME_LIMIT_SEC 0.1 + +int g_callui_sig_to_handle[] = {SIGILL, SIGABRT, SIGFPE, SIGSEGV}; +#define APP_SIG_COUNT ((int)(sizeof(g_callui_sig_to_handle) / sizeof(g_callui_sig_to_handle[0]))) + static bool __app_create(void *data); static void __app_terminate(void *data); static void __app_pause(void *data); @@ -70,9 +77,10 @@ static void __set_main_power_key_grab(callui_app_data_t *ad); static void __powerkey_mode_changed_cb(keynode_t *node, void *user_data); static void __unset_main_win_key_grab(callui_app_data_t *ad); static void __set_text_classes_params(); - static void __process_power_key_up(callui_app_data_t *ad); static void __process_home_key_up(callui_app_data_t *ad); +static void __init_signals_handling(); +static void __app_signal_handler(int signum, siginfo_t *info, void *context); static callui_app_data_t g_ad; @@ -216,9 +224,9 @@ static void __call_state_change_cb(void *user_data, switch (call_event_type) { case CALLUI_CALL_EVENT_ACTIVE: if (_callui_lock_manager_is_lcd_off(ad->lock_handle)) { - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_UNLOCK); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_UNLOCK); } else { - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_ON_UNLOCK); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_ON_UNLOCK); } #ifdef _DBUS_DISPLAY_DEVICE_TIMEOUT_ callui_audio_state_type_e audio_state = _callui_sdm_get_audio_state(ad->sound_manager); @@ -229,9 +237,9 @@ static void __call_state_change_cb(void *user_data, break; case CALLUI_CALL_EVENT_END: if (_callui_lock_manager_is_lcd_off(ad->lock_handle)) { - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_UNLOCK); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_UNLOCK); } else { - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_ON_UNLOCK); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_ON_UNLOCK); } break; default: @@ -325,6 +333,60 @@ static void __dial_status_cb(void *user_data, callui_dial_status_e dial_status) } } +static void __init_signals_handling() +{ + struct sigaction act; + act.sa_sigaction = __app_signal_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + act.sa_flags |= SA_RESETHAND; + int i = 0; + for (; i < APP_SIG_COUNT; ++i) { + if (sigaction(g_callui_sig_to_handle[i], &act, NULL) < 0) { + err("sigaction() failed!"); + } + } +} + +static Eina_Bool __app_state_check_timer_cb(void *data) +{ + dbg("****** APP STATE CHECK TIMER CALLBACK START ******"); + + CALLUI_RETURN_VALUE_IF_FAIL(data, ECORE_CALLBACK_CANCEL); + + callui_app_data_t *ad = data; + + callui_display_state_e state; + if (_callui_display_get_state(ad->display, &state) == CALLUI_RESULT_OK && state != CALLUI_DISPLAY_OFF && ad->on_background) { + _callui_indicator_set_active(ad->indicator, true); + } + ad->app_state_check_timer = NULL; + + dbg("****** APP STATE CHECK TIMER CALLBACK END ******"); + + return ECORE_CALLBACK_DONE; +} + +static void __display_state_changed_cb(void *user_data) +{ + dbg("****** DISPLAY STATE CHANGED START ******"); + callui_app_data_t *ad = user_data; + + callui_display_state_e state; + if (_callui_display_get_state(ad->display, &state) == CALLUI_RESULT_OK && state == CALLUI_DISPLAY_NORMAL) { + + double diff = ecore_time_get() - ad->powerkey_press_time; + dbg("Display state change time <-> Powerkey_Down_Event [%.3f]", diff); + if (diff > CALLUI_POWERKEY_PRESS_TIME_LIMIT_SEC) { + dbg("Need check application state with delay"); + ad->powerkey_press_time = 0; + DELETE_ECORE_TIMER(ad->app_state_check_timer); + ad->app_state_check_timer = ecore_timer_add(CALLUI_APP_STATE_TIMEOUT_SEC, __app_state_check_timer_cb, ad); + } + } + dbg("****** DISPLAY STATE CHANGED END ******"); +} + static bool __app_init(callui_app_data_t *ad) { __init_app_event_handlers(ad); @@ -371,17 +433,28 @@ static bool __app_init(callui_app_data_t *ad) ad->display = _callui_display_create(ad); CALLUI_RETURN_VALUE_IF_FAIL(ad->display, false); + _callui_display_add_display_state_change_cb(ad->display, __display_state_changed_cb, ad); + ad->lock_handle = _callui_lock_manager_create(); CALLUI_RETURN_VALUE_IF_FAIL(ad->lock_handle, false); + ad->indicator = _callui_indicator_create(ad); + if (!ad->indicator) { + err("Failed to create status bar module"); + } + __set_main_win_key_grab(ad); __add_ecore_event_key_handlers(ad); __set_text_classes_params(); + __init_signals_handling(); + _callui_common_set_lock_state_changed_cb(ad); + elm_theme_extension_add(NULL, CALLUI_CALL_THEME_EDJ_PATH); + return true; } @@ -421,8 +494,11 @@ static void __app_deinit(callui_app_data_t *ad) { debug_enter(); + app_manager_unset_app_context_event_cb(); + _callui_common_unset_lock_state_changed_cb(); + _callui_display_remove_display_state_change_cb(ad->display, __display_state_changed_cb, ad); _callui_stp_remove_call_state_event_cb(ad->state_provider, __call_state_change_cb, ad); _callui_sdm_remove_audio_state_changed_cb(ad->sound_manager, __audio_state_changed_cb, ad); @@ -430,10 +506,17 @@ static void __app_deinit(callui_app_data_t *ad) __unset_main_win_key_grab(ad); + DELETE_ECORE_TIMER(ad->app_state_check_timer); + if (ad->msg_handle) { _callui_common_deinit_msg_client(ad); } + if (ad->indicator) { + _callui_indicator_destroy(ad->indicator); + ad->indicator = NULL; + } + if (ad->lock_handle) { _callui_lock_manager_destroy(ad->lock_handle); ad->lock_handle = NULL; @@ -501,7 +584,7 @@ static void __app_terminate(void *data) static void __app_pause(void *data) { - debug_enter(); + dbg("****** PAUSE START ******"); callui_app_data_t *ad = data; @@ -510,30 +593,44 @@ static void __app_pause(void *data) ad->start_lock_manager_on_resume = true; } + ad->on_background = true; + _callui_vm_pause(ad->view_manager); - if (_callui_common_get_idle_lock_type() == CALLUI_LOCK_TYPE_UNLOCK) { - dbg("Device is unlocked"); - ad->on_background = true; - _callui_window_set_above_lockscreen_mode(ad->window, false); - ad->app_pause_time = ecore_time_get(); - } + DELETE_ECORE_TIMER(ad->app_state_check_timer); + ad->app_state_check_timer = ecore_timer_add(CALLUI_APP_STATE_TIMEOUT_SEC, __app_state_check_timer_cb, ad); + + dbg("****** PAUSE END ******"); } static void __app_resume(void *data) { - debug_enter(); + dbg("****** RESUME START ******"); callui_app_data_t *ad = data; + _callui_indicator_set_locked(ad->indicator, false); + _callui_indicator_set_active(ad->indicator, false); + + _callui_window_set_above_lockscreen_state(ad->window, true); + ad->on_background = false; - if (ad->start_lock_manager_on_resume) { + _callui_vm_resume(ad->view_manager); + + /* + * Temporary. When proximity sensor is ON suddenly resume callback can be called. + * To over step problem with turning off lock manager it is used view type check + */ + callui_view_type_e type = _callui_vm_get_cur_view_type(ad->view_manager); + if (ad->start_lock_manager_on_resume || (type != CALLUI_VIEW_ENDCALL + && type != CALLUI_VIEW_INCOMING_CALL + && type != CALLUI_VIEW_INCOMING_CALL_NOTI)) { ad->start_lock_manager_on_resume = false; _callui_lock_manager_start(ad->lock_handle); } - _callui_vm_resume(ad->view_manager); + dbg("****** RESUME END ******"); } static void __app_service(app_control_h app_control, void *data) @@ -549,7 +646,7 @@ static void __app_service(app_control_h app_control, void *data) && !ad->waiting_dialing) { err("CALLUI_VIEW_UNDEFINED. Clear data"); __reset_state_params(ad); - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_OFF_SLEEP_LOCK); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_OFF_SLEEP_LOCK); } ret = app_control_get_operation(app_control, &operation); @@ -565,7 +662,7 @@ static void __app_service(app_control_h app_control, void *data) if ((strcmp(operation, APP_CONTROL_OPERATION_CALL) == 0) && (strncmp(uri_bundle, "tel:", 4) == 0)) { if ((strncmp(uri_bundle, "tel:MT", 6) == 0)) { - _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_ON_LOCK); + _callui_display_set_control_state(ad->display, CALLUI_DISPLAY_CONTROL_ON_LOCK); ret = app_control_get_extra_data(app_control, "handle", &tmp); if (ret != APP_CONTROL_ERROR_NONE) { err("app_control_get_extra_data failed"); @@ -611,7 +708,7 @@ static void __app_service(app_control_h app_control, void *data) } } else if (strcmp(operation, CALLUI_APP_CONTROL_OPERATION_LS_RESUME) == 0) { _callui_window_activate(ad->window); - _callui_window_set_above_lockscreen_mode(ad->window, true); + _callui_window_set_above_lockscreen_state(ad->window, true); } free(operation); @@ -628,9 +725,11 @@ static void __process_power_key_up(callui_app_data_t *ad) CALLUI_CALL_DATA_ACTIVE); int is_powerkey_enabled = _callui_common_is_powerkey_ending_call_mode_on(); - dbg("[KEY]KEY_POWER pressed, is_powerkey_enabled(%d)", is_powerkey_enabled); + dbg("End call with power key [%s]", is_powerkey_enabled ? "ON":"OFF"); - if (is_powerkey_enabled && _callui_display_is_turned_on(ad->display)) { + callui_display_state_e state; + if (_callui_display_get_state(ad->display, &state) == CALLUI_RESULT_OK + && state != CALLUI_DISPLAY_OFF && is_powerkey_enabled) { if (view_type == CALLUI_VIEW_DIALLING) { if (active) { _callui_manager_end_call(ad->call_manager, active->call_id, @@ -646,6 +745,8 @@ static void __process_power_key_up(callui_app_data_t *ad) _callui_vm_change_view(ad->view_manager, CALLUI_VIEW_INCOMING_CALL); } } else { + dbg("Power key to lock device [UP]"); + const callui_call_data_t *incom = _callui_stp_get_call_data(ad->state_provider, CALLUI_CALL_DATA_INCOMING); const callui_call_data_t *held = _callui_stp_get_call_data(ad->state_provider, @@ -705,8 +806,14 @@ static void __process_home_key_up(callui_app_data_t *ad) dbg("KEY_SELECT key grab failed"); } } + } else if (view_type == CALLUI_VIEW_ENDCALL) { + _callui_common_exit_app(); + } else if (_callui_lock_manager_is_lcd_off(ad->lock_handle)) { + dbg("Lock Manager LCD status [OFF]. Return"); + return; } else { if (ad->on_background) { + dbg("App on background. Return"); return; } @@ -714,14 +821,13 @@ static void __process_home_key_up(callui_app_data_t *ad) callui_idle_lock_type_t lock_type = _callui_common_get_idle_lock_type(); if (lock_type == CALLUI_LOCK_TYPE_SECURITY_LOCK) { _callui_common_unlock_swipe_lock(); - _callui_window_set_above_lockscreen_mode(ad->window, false); + _callui_window_set_above_lockscreen_state(ad->window, false); _callui_window_minimize(ad->window); } else if (lock_type == CALLUI_LOCK_TYPE_SWIPE_LOCK) { ad->need_win_minimize = true; _callui_common_unlock_swipe_lock(); } } - } debug_leave(); @@ -731,8 +837,8 @@ static Eina_Bool __hard_key_up_cb(void *data, int type, void *event) { debug_enter(); - CALLUI_RETURN_VALUE_IF_FAIL(data, EINA_FALSE); - CALLUI_RETURN_VALUE_IF_FAIL(event, EINA_FALSE); + CALLUI_RETURN_VALUE_IF_FAIL(data, ECORE_CALLBACK_CANCEL); + CALLUI_RETURN_VALUE_IF_FAIL(event, ECORE_CALLBACK_CANCEL); callui_app_data_t *ad = data; Ecore_Event_Key *ev = event; @@ -750,16 +856,40 @@ static Eina_Bool __hard_key_up_cb(void *data, int type, void *event) } else if (!strcmp(ev->keyname, CALLUI_KEY_SELECT) || !strcmp(ev->keyname, CALLUI_KEY_HOME)) { dbg("KEY_SELECT or KEY_HOME"); __process_home_key_up(ad); + } else if (!strcmp(ev->keyname, CALLUI_KEY_BACK)) { + if (_callui_vm_get_cur_view_type(ad->view_manager) == CALLUI_VIEW_ENDCALL) { + _callui_common_exit_app(); + } } - return EINA_FALSE; + return ECORE_CALLBACK_DONE; } static Eina_Bool __hard_key_down_cb(void *data, int type, void *event) { debug_enter(); - return EINA_FALSE; + CALLUI_RETURN_VALUE_IF_FAIL(data, ECORE_CALLBACK_CANCEL); + CALLUI_RETURN_VALUE_IF_FAIL(event, ECORE_CALLBACK_CANCEL); + + callui_app_data_t *ad = data; + Ecore_Event_Key *ev = event; + + /* power key case */ + if (!strcmp(ev->keyname, CALLUI_KEY_POWER)) { + dbg("KEY_POWER"); + ad->powerkey_press_time = ecore_time_get(); + } + + return ECORE_CALLBACK_DONE; +} + +static void __app_signal_handler(int signum, siginfo_t *info, void *context) +{ + err("Received [%d] signal", signum); + + _callui_indicator_force_deativate(g_ad.indicator); + raise(signum); } callui_app_data_t *_callui_get_app_data() @@ -770,7 +900,7 @@ callui_app_data_t *_callui_get_app_data() CALLUI_EXPORT_API int main(int argc, char *argv[]) { dbg(".."); - ui_app_lifecycle_callback_s event_callback = {0,}; + ui_app_lifecycle_callback_s event_callback = { 0 }; event_callback.create = __app_create; event_callback.terminate = __app_terminate; diff --git a/tizen-manifest.xml b/tizen-manifest.xml index 826fc85..e6b655f 100644 --- a/tizen-manifest.xml +++ b/tizen-manifest.xml @@ -15,13 +15,13 @@ - http://tizen.org/privilege/window.priority.set http://tizen.org/privilege/keygrab http://tizen.org/privilege/notification - http://tizen.org/privilege/appmanager.launch http://tizen.org/privilege/message.write - http://tizen.org/privilege/display + http://tizen.org/privilege/appmanager.launch http://tizen.org/privilege/message.read + http://tizen.org/privilege/display + http://tizen.org/privilege/window.priority.set http://tizen.org/privilege/contact.read -- 2.7.4