From 6ca019fa86a3667a47f3ed4b6adfb28ac7ad5fe3 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 7 Feb 2023 17:21:58 +0900 Subject: [PATCH] Set service state by engine launching status - Issue: If the client is out of service by service reset, client can not get proper service state. - Solution: By the on-demand reprepare logic, the clients subscribing service state changed event can not get service state until that the client invokes the API. However, if the client invokes the API depending on service state, the client may not call the API, so it can be out of service permanently. To solve this problem, this patch adds logic for checking engine launching status. Through this patch, the client library can check whether the engine is launched or not. When the engine is launched, the client library notifies the service state changed event to the client app can run the code which depends on the service state. Change-Id: If4e3310054143732f5705ed4acfae42762fa21b1 Signed-off-by: Suyeon Hwang --- client/tts_core.c | 64 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/client/tts_core.c b/client/tts_core.c index 9098e4c6..fd4b4d6c 100644 --- a/client/tts_core.c +++ b/client/tts_core.c @@ -36,6 +36,7 @@ static int g_engine_update_status = 0; static atomic_bool g_is_engine_name_changed = false; static Ecore_Thread* g_reprepare_thread = NULL; +static Ecore_Idler *g_unset_app_context_cb_idler = NULL; static char* g_pkgmgr_status = NULL; static pkgmgr_client* g_pkgmgr = NULL; @@ -61,7 +62,7 @@ static const char* __convert_state(tts_state_e state) return "Invalid state"; } -static char* __get_engine_appid() { +static char* get_engine_appid() { if (NULL == g_engine_name) { return NULL; } @@ -156,7 +157,7 @@ static bool __is_engine_installed(const char* appid) static bool __is_engine_launched() { - char* appid = __get_engine_appid(); + char* appid = get_engine_appid(); if (NULL == appid) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID"); return false; @@ -702,6 +703,11 @@ int tts_core_deinitialize() ecore_thread_wait(g_reprepare_thread, 0.5); // wait g_reprepare_thread is terminated. } + if (NULL != g_unset_app_context_cb_idler) { + ecore_idler_del(g_unset_app_context_cb_idler); + g_unset_app_context_cb_idler = NULL; + } + if (NULL != g_pkgmgr_thread) { SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread"); g_is_thread_canceled = true; @@ -1230,6 +1236,54 @@ static void set_service_out_for_each_client(gpointer data, gpointer user_data) tts_core_notify_service_state_changed(client, before_state, TTS_SERVICE_STATE_BLOCKED); } +static void notify_engine_launch_for_each_client(gpointer data, gpointer user_data) +{ + tts_client_s *client = (tts_client_s *)data; + RETM_IF(false == tts_client_is_valid_client(client), "[ERROR] Client is not valid"); + + const tts_service_state_e before_state = tts_client_get_current_service_state(client); + if (TTS_SERVICE_STATE_BLOCKED == before_state) { + tts_core_notify_service_state_changed(client, before_state, TTS_SERVICE_STATE_READY); + } +} + +static Eina_Bool unset_app_context_cb_by_idler(void *user_data) +{ + app_manager_unset_app_context_event_cb(); + g_unset_app_context_cb_idler = NULL; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Unset callback for checking engine launching status"); + return EINA_FALSE; +} + +static void check_engine_launching_status(app_context_h app_context, app_context_event_e event, void *user_data) +{ + RET_IF(event != APP_CONTEXT_EVENT_LAUNCHED); + + char *app_id = NULL; + int ret = app_context_get_app_id(app_context, &app_id); + + RET_IF(ret != APP_MANAGER_ERROR_NONE || NULL == app_id); + + char *engine_id = get_engine_appid(); + bool is_engine = (0 == strncmp(app_id, engine_id, TTS_ENGINE_APPID_LEN)); + free(app_id); + free(engine_id); + + RET_IF(false == is_engine); + + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Engine is launched now"); + GList* client_list = tts_client_get_client_list(); + if (NULL != client_list) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Set service out to all clients"); + g_list_foreach(client_list, notify_engine_launch_for_each_client, NULL); + g_list_free(client_list); + } + + if (NULL == g_unset_app_context_cb_idler) { + g_unset_app_context_cb_idler = ecore_idler_add(unset_app_context_cb_by_idler, NULL); + } +} + int tts_core_handle_service_reset() { SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset"); @@ -1247,6 +1301,12 @@ int tts_core_handle_service_reset() g_list_foreach(client_list, set_service_out_for_each_client, &instant_reprepare_uid); g_list_free(client_list); + ret = app_manager_set_app_context_event_cb(check_engine_launching_status, NULL); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine launching status callback. ret(%d/%s)", ret, get_error_message(ret)); + return TTS_ERROR_OPERATION_FAILED; + } + return TTS_ERROR_NONE; } -- 2.34.1