4 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #ifdef _SUPPORT_SCREEN_READER2
26 #include <vconf-keys.h>
31 static void _tts_init(void);
32 static void _tts_fini(void);
34 static struct _s_info {
42 typedef struct _QP_TTS {
50 static QP_TTS_T * _tts_entry_new(int id, char *message)
52 QP_TTS_T *entry = NULL;
53 retif(message == NULL, NULL, "NULL message");
55 entry = (QP_TTS_T *)calloc(1, sizeof(QP_TTS_T));
56 retif(entry == NULL, NULL, "failed to memory allocation");
59 entry->message = strdup(message);
66 static void _tts_entry_del(QP_TTS_T *entry)
68 retif(entry == NULL, ,"invalid parameter");
70 if (entry->message != NULL) {
79 static QP_TTS_T *_tts_list_get_first(void)
81 return eina_list_nth(s_info.list, 0);
86 static void _tts_list_add(QP_TTS_T *entry)
88 retif(entry == NULL, ,"invalid parameter");
90 s_info.list = eina_list_prepend(s_info.list, entry);
95 static void _tts_list_del(QP_TTS_T *entry)
97 retif(entry == NULL, ,"invalid parameter");
99 s_info.list = eina_list_remove(s_info.list, entry);
104 static void _tts_list_clean(void)
106 QP_TTS_T *entry = NULL;
108 while ((entry = _tts_list_get_first()) != NULL) {
109 _tts_list_del(entry);
110 _tts_entry_del(entry);
116 static int _is_screenreader_on(void)
118 int ret = -1, status = 0;
120 ret = vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &status);
121 retif(ret != 0, 0, "failed to read VCONFKEY_SETAPPL_ACCESSIBILITY_TTS %d", ret);
128 static tts_state_e _tts_state_get(void)
130 int ret = TTS_ERROR_NONE;
131 tts_state_e state = TTS_STATE_READY;
133 if (s_info.tts_handler != NULL) {
134 ret = tts_get_state(s_info.tts_handler, &state);
135 if (TTS_ERROR_NONE != ret){
136 ERR("get state error(%d)", ret);
148 static void _tts_play(const char *message)
151 int ret = TTS_ERROR_NONE;
153 if (s_info.tts_handler == NULL) {
154 ERR("critical, TTS handler isn't initialized");
158 DBG("adding %s", message);
160 ret = tts_add_text(s_info.tts_handler, message, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &utt);
161 if (TTS_ERROR_NONE != ret){
162 ERR("add text error!");
166 ret = tts_play(s_info.tts_handler);
167 if(ret != TTS_ERROR_NONE) {
168 ERR("play error(%d) state(%d)", ret);
174 static void _tts_stop(void)
176 int ret = TTS_ERROR_NONE;
178 if (s_info.tts_handler == NULL) {
179 ERR("critical, TTS handler isn't initialized");
183 ret = tts_stop(s_info.tts_handler);
184 if (TTS_ERROR_NONE != ret){
185 ERR("failed to stop play:%d", ret);
192 static void _tts_state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data)
194 QP_TTS_T *entry = NULL;
196 DBG("_tts_state_changed_cb(%d => %d)", previous, current);
198 if(previous == TTS_STATE_CREATED && current == TTS_STATE_READY) {
199 entry = _tts_list_get_first();
201 _tts_play(entry->message);
202 _tts_list_del(entry);
203 _tts_entry_del(entry);
211 static void _tts_utt_started_cb(tts_h tts, int utt_id, void *user_data)
213 DBG("_tts_utt_started_cb");
218 static void _tts_utt_completed_cb(tts_h tts, int utt_id, void *user_data)
220 DBG("_tts_utt_completed_cb");
225 static void _tts_error_cb(tts_h tts, int utt_id, tts_error_e reason, void* user_data)
227 DBG("_tts_error_cb");
232 static int _tts_callback_set(tts_h tts, void* data)
236 if (TTS_ERROR_NONE != (ret = tts_set_state_changed_cb(tts, _tts_state_changed_cb, tts))){
237 ERR("set interrupted callback error !!:%d", ret);
241 if (TTS_ERROR_NONE != (ret = tts_set_utterance_started_cb(tts, _tts_utt_started_cb, data))) {
242 ERR("set utterance started callback error !!:%d", ret);
246 if (TTS_ERROR_NONE != (ret = tts_set_utterance_completed_cb(tts, _tts_utt_completed_cb, data))) {
247 ERR("set utterance completed callback error !!:%d", ret);
251 if (TTS_ERROR_NONE != (ret = tts_set_error_cb(tts, _tts_error_cb, data))) {
252 ERR("set error callback error !!:%d", ret);
261 static void _tts_init()
264 int ret = TTS_ERROR_NONE;
266 if (s_info.tts_handler == NULL) {
267 ret = tts_create(&tts);
268 if(ret != TTS_ERROR_NONE) {
269 ERR("tts_create() failed");
273 ret = tts_set_mode(tts, TTS_MODE_NOTIFICATION);
274 if(ret != TTS_ERROR_NONE) {
275 ERR("tts_create() failed");
276 tts_destroy(s_info.tts_handler);
277 s_info.tts_handler = NULL;
281 if(_tts_callback_set(tts, NULL) != 0) {
282 ERR("_tts_callback_set() failed");
283 tts_destroy(s_info.tts_handler);
284 s_info.tts_handler = NULL;
288 ret = tts_prepare(tts);
289 if(ret != TTS_ERROR_NONE) {
290 ERR("tts_create() failed");
291 tts_destroy(s_info.tts_handler);
292 s_info.tts_handler = NULL;
296 s_info.tts_handler = tts;
302 static void _tts_fini(void)
304 int ret = TTS_ERROR_NONE;
306 if (s_info.tts_handler != NULL) {
307 ret = tts_destroy(s_info.tts_handler);
308 if(ret != TTS_ERROR_NONE) {
309 ERR("tts_destroy() failed");
311 s_info.tts_handler = NULL;
317 static void _tts_vconf_cb(keynode_t *key, void *data){
318 if(_is_screenreader_on() == 0) {
319 DBG("TTS turned off");
328 void indicator_service_tts_init(void *data) {
331 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS,
332 _tts_vconf_cb, data);
337 void indicator_service_tts_fini(void *data) {
340 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS,
341 _tts_vconf_cb, data);
348 void indicator_service_tts_play(char *message) {
349 tts_state_e state = 0;
350 QP_TTS_T *entry = NULL;
351 retif(message == NULL, ,"invalid parameter");
353 if (_is_screenreader_on() == 1) {
356 state = _tts_state_get();
358 if (state == TTS_STATE_CREATED) {
360 entry = _tts_entry_new(-1, message);
362 _tts_list_add(entry);
364 } else if (state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED) {
367 } else if (state == TTS_STATE_READY) {
370 ERR("invalid status: %d", state);
374 #endif /* _SUPPORT_SCREEN_READER2 */