From f03d93342f785490306dab9c0eba8fae6983bace Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E2=80=9Cvijay=2Etiwari=E2=80=9D?= Date: Tue, 29 Nov 2016 18:32:51 +0530 Subject: [PATCH] Implement Screen Reader for TaskManager Change-Id: I9d36e74367a4728a9f414fa0e96ce01672dc0047 --- inc/list.h | 2 - inc/main.h | 4 ++ res/edje/layout.edc | 2 - src/item.c | 64 ++++++++++++++++++ src/main.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/scroller.c | 46 ++++++++++--- 6 files changed, 282 insertions(+), 24 deletions(-) diff --git a/inc/list.h b/inc/list.h index 4f32808..206f33f 100644 --- a/inc/list.h +++ b/inc/list.h @@ -21,7 +21,6 @@ #include "util.h" typedef struct { - char *pkgid; char *appid; char *name; @@ -35,7 +34,6 @@ typedef struct { Eina_Bool multi_launch; Eina_Bool isAlreadySet; time_t launch_time; - } list_type_default_s; task_mgr_error_e list_create(); diff --git a/inc/main.h b/inc/main.h index 24f3eea..3a98b09 100644 --- a/inc/main.h +++ b/inc/main.h @@ -59,4 +59,8 @@ typedef main_s *main_h; main_h main_get_info(void); +void screen_reader_set_highlight_by_index(int index, Eina_Bool can_highlight); +void screen_reader_grab_highlight_by_index(int index); +void screen_reader_update(int cur_page); + #endif //__TASK_MGR_H__ diff --git a/res/edje/layout.edc b/res/edje/layout.edc index d17bd7e..578aacc 100644 --- a/res/edje/layout.edc +++ b/res/edje/layout.edc @@ -202,10 +202,8 @@ group { description { state : "show" 0.0; visible : 1; - min : 98 98; max : 98 98; - rel1 { relative : 0.5 0.5; to : "bg"; diff --git a/src/item.c b/src/item.c index ba09b7d..f7df286 100644 --- a/src/item.c +++ b/src/item.c @@ -361,6 +361,46 @@ static void _item_del_cb(void *data, Evas_Object *obj, const char *emission, con index_refresh(main_info); } +static Eina_Bool _screen_reader_launch_app(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info) +{ + Evas_Object *parent = NULL; + + if (data == NULL || obj == NULL) { + _E("parameter is NULL"); + return EINA_TRUE; + } + + parent = elm_atspi_accessible_parent_get(obj); + if (parent == NULL) { + _E("Failed to get parent object of access object"); + return EINA_TRUE; + } + + _clicked_cb(data, parent, NULL, NULL); + + return EINA_TRUE; +} + +static Eina_Bool _screen_reader_del_app(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info) +{ + Evas_Object *parent = NULL; + + if (data == NULL || obj == NULL) { + _E("parameter is NULL"); + return EINA_TRUE; + } + + parent = elm_atspi_accessible_parent_get(obj); + if (parent == NULL) { + _E("Failed to get parent object of access object"); + return EINA_TRUE; + } + + _item_del_cb(data, parent, NULL, NULL); + + return EINA_TRUE; +} + Evas_Object *item_create(void *data, list_type_default_s *info) { main_h main_info = data; @@ -395,6 +435,8 @@ Evas_Object *item_create(void *data, list_type_default_s *info) evas_object_show(label); elm_object_part_content_set(item, "txt.app_name", label); + + elm_atspi_accessible_can_highlight_set(label, EINA_FALSE); } icon = evas_object_image_add(evas_object_evas_get(item)); @@ -414,6 +456,28 @@ Evas_Object *item_create(void *data, list_type_default_s *info) evas_object_event_callback_add(item, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb_t, main_info); evas_object_data_set(item, DATA_KEY_ITEM_INFO, info); + /* Screen Reader */ + Evas_Object *ao_app_icon = NULL; + Evas_Object *ao_del_icon = NULL; + char buf[128] = { 0, }; + + ao_app_icon = elm_access_object_register(icon, item); + elm_atspi_accessible_name_set(ao_app_icon, info->name ? strdup(info->name) : NULL); + snprintf(buf, sizeof(buf), S_("IDS_AT_BODY_PAGE_P1SD_OF_P2SD_T_TTS"), main_info->cur_page + 1, eina_list_count(main_info->pkg_list)); + elm_atspi_accessible_description_set(ao_app_icon, buf ? strdup(buf) : NULL); + elm_atspi_accessible_translation_domain_set(ao_app_icon, PACKAGE); + elm_atspi_accessible_reading_info_type_set(ao_app_icon, (ELM_ACCESSIBLE_READING_INFO_TYPE_NAME | ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION)); + elm_access_action_cb_set(ao_app_icon, ELM_ACCESS_ACTION_ACTIVATE, _screen_reader_launch_app, main_info); + elm_atspi_accessible_can_highlight_set(ao_app_icon, EINA_FALSE); + + ao_del_icon = elm_access_object_register((Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(item), "img.recent_delete_bg"), item); + elm_atspi_accessible_name_set(ao_del_icon, strdup(S_("IDS_TASKMGR_OPT_CLOSE"))); + elm_atspi_accessible_description_set(ao_del_icon, strdup(S_("IDS_ACCS_BODY_BUTTON_TTS"))); + elm_atspi_accessible_translation_domain_set(ao_del_icon, PACKAGE); + elm_atspi_accessible_reading_info_type_set(ao_del_icon, (ELM_ACCESSIBLE_READING_INFO_TYPE_NAME | ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION)); + elm_access_action_cb_set(ao_del_icon, ELM_ACCESS_ACTION_ACTIVATE, _screen_reader_del_app, main_info); + elm_atspi_accessible_can_highlight_set(ao_del_icon, EINA_FALSE); + return item; ERROR: diff --git a/src/main.c b/src/main.c index f3760b7..9c28985 100644 --- a/src/main.c +++ b/src/main.c @@ -52,6 +52,151 @@ main_h main_get_info(void) return &main_info; } +void screen_reader_set_highlight_by_index(int index, Eina_Bool can_highlight) +{ + Evas_Object *box = NULL; + Evas_Object *item = NULL; + Evas_Object *target_obj = NULL; + Evas_Object *access_obj = NULL; + Eina_List *item_list = NULL; + main_h main_info = NULL; + + main_info = main_get_info(); + if (main_info == NULL) { + _E("main_info is NULL"); + return; + } + if (main_info->scroller == NULL) { + _E("scroller is NULL"); + return; + } + box = elm_object_content_get(main_info->scroller); + if (box == NULL) { + _E("box is NULL"); + return; + } + item_list = elm_box_children_get(box); + if (item_list == NULL) { + _E("item list is NULL"); + return; + } + item = eina_list_nth(item_list, index); + if (item == NULL) { + _E("item is NULL"); + return; + } + + target_obj = elm_object_part_content_get(item, "img.app_image"); + if (target_obj) { + access_obj = elm_access_object_get(target_obj); + if (access_obj) { + char buf[128] = { 0, }; + snprintf(buf, sizeof(buf), S_("IDS_AT_BODY_PAGE_P1SD_OF_P2SD_T_TTS"), main_info->cur_page + 1, eina_list_count(main_info->pkg_list)); + elm_atspi_accessible_description_set(access_obj, buf ? strdup(buf) : NULL); + elm_atspi_accessible_can_highlight_set(access_obj, can_highlight); + } + } + + target_obj = NULL; + + target_obj = (Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(item), "img.recent_delete_bg"); + if (target_obj) { + access_obj = elm_access_object_get(target_obj); + if (access_obj) { + elm_atspi_accessible_can_highlight_set(access_obj, can_highlight); + } + } +} + +void screen_reader_grab_highlight_by_index(int index) +{ + Evas_Object *box = NULL; + Evas_Object *item = NULL; + Evas_Object *target_obj = NULL; + Evas_Object *access_obj = NULL; + Eina_List *item_list = NULL; + main_h main_info = NULL; + + main_info = main_get_info(); + if (main_info == NULL) { + _E("main_info is NULL"); + return; + } + + if (main_info->scroller == NULL) { + _E("scroller is NULL"); + return; + } + + box = elm_object_content_get(main_info->scroller); + if (box == NULL) { + _E("box is NULL"); + return; + } + + item_list = elm_box_children_get(box); + if (item_list == NULL) { + _E("item list is NULL"); + return; + } + + item = eina_list_nth(item_list, index); + if (item == NULL) { + _E("item is NULL"); + return; + } + + target_obj = elm_object_part_content_get(item, "img.app_image"); + if (target_obj == NULL) { + _E("target object is NULL"); + return; + } + + access_obj = elm_access_object_get(target_obj); + if (access_obj == NULL) { + _E("access object is NULL"); + return; + } + + elm_atspi_component_highlight_grab(access_obj); +} + +void screen_reader_update(int cur_page) +{ + Evas_Object *box = NULL; + Eina_List *pkg_list = NULL; + main_h main_info = NULL; + int i = 0, total = 0; + + main_info = main_get_info(); + if (main_info == NULL) { + _E("data is NULL"); + return; + } + + box = elm_object_content_get(main_info->scroller); + if (box == NULL) { + _E("box is NULL"); + return; + } + + pkg_list = elm_box_children_get(box); + if (pkg_list == NULL) { + _E("pkg list is NULL"); + return; + } + + total = eina_list_count(pkg_list); + for (i = 0; i < total; i++) { + if (i == cur_page) { + screen_reader_set_highlight_by_index(i, EINA_TRUE); + screen_reader_grab_highlight_by_index(i); + } else { + screen_reader_set_highlight_by_index(i, EINA_FALSE); + } + } +} + static Eina_Bool _back_key_pressed(void *data, Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info) { _D(""); @@ -73,18 +218,19 @@ static task_mgr_error_e _create_layout(void *data) main_h main_info = data; Evas_Object *layout = NULL; Eina_Bool ret = EINA_FALSE; + char edje_path[PATH_MAX] = {0, }; + int res = 0; // create layout layout = elm_layout_add(main_info->win); goto_if(!layout, ERROR); - char edje_path[PATH_MAX] = {0, }; - int res = 0; res = getEdjepath(LAYOUT, edje_path, sizeof(edje_path)); goto_if(res < 0, ERROR); + _D("edje_path is : %s", edje_path); - ret = elm_layout_file_set(layout, edje_path, "taskmanager-main"); + ret = elm_layout_file_set(layout, edje_path, "taskmanager-main"); goto_if(EINA_FALSE == ret, ERROR); evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); @@ -92,6 +238,14 @@ static task_mgr_error_e _create_layout(void *data) evas_object_resize(layout, main_info->root_w, main_info->root_h); evas_object_show(layout); + /* Screen Reader */ + Evas_Object *ao_layout = NULL; + ao_layout = elm_access_object_register((Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(layout), "bg"), layout); + elm_atspi_accessible_name_set(ao_layout, strdup(S_("IDS_AT_BODY_NO_RECENT_APPS"))); + elm_atspi_accessible_translation_domain_set(ao_layout, PACKAGE); + elm_atspi_accessible_reading_info_type_set(ao_layout, (ELM_ACCESSIBLE_READING_INFO_TYPE_NAME)); + elm_atspi_accessible_can_highlight_set(ao_layout, EINA_FALSE); + main_info->layout = layout; // create scroller @@ -104,7 +258,7 @@ ERROR: if (layout) { evas_object_del(layout); layout = NULL; - } + } evas_object_del(main_info->win); main_info->win = NULL; return TASK_MGR_ERROR_FAIL; @@ -144,16 +298,25 @@ static Eina_Bool _list_timer_cb(void *data) _D("List count: %d", eina_list_count(main_info.pkg_list)); if (!main_info.pkg_list) { + Evas_Object *access_obj = NULL; + _E("pkg_list is empty"); - char text1[256] = { 0 }; - char text2[256] = { 0 }; - memset(text1, 0, sizeof(text1)); - memset(text2, 0, sizeof(text2)); - snprintf(text1, sizeof(text1), S_(STRING_TASK_MGR_NO_RECENT_APPS)); - snprintf(text2, sizeof(text2), S_(STRING_TASK_MGR_RECENT_APPS)); elm_layout_signal_emit(main_info.layout, "show,txt.no_apps", "txt.no_apps"); - elm_object_translatable_part_text_set(main_info.layout, "txt.no_apps", text1); - elm_object_translatable_part_text_set(main_info.layout, "txt.recent_title", text2); + elm_object_translatable_part_text_set(main_info.layout, "txt.no_apps", S_(STRING_TASK_MGR_NO_RECENT_APPS)); + elm_object_translatable_part_text_set(main_info.layout, "txt.recent_title", S_(STRING_TASK_MGR_RECENT_APPS)); + + access_obj = elm_access_object_get((Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(main_info.layout), "bg")); + if (access_obj) { + elm_atspi_accessible_can_highlight_set(access_obj, EINA_TRUE); + } + + access_obj = NULL; + + access_obj = elm_access_object_get((Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(main_info.layout), "close_all_text")); + if (access_obj) { + elm_atspi_accessible_can_highlight_set(access_obj, EINA_FALSE); + } + goto END; } @@ -182,6 +345,7 @@ static bool _create_cb(void *data) elm_win_indicator_opacity_set(main_info.win, ELM_WIN_INDICATOR_TRANSPARENT); elm_win_borderless_set(main_info.win, EINA_TRUE); + elm_atspi_accessible_name_set(main_info.win, strdup(S_("WDS_ST_OPT_RECENT_APPS_ABB"))); evas_object_show(main_info.win); main_info.e = evas_object_evas_get(main_info.win); diff --git a/src/scroller.c b/src/scroller.c index 7c96b34..bb9db1b 100644 --- a/src/scroller.c +++ b/src/scroller.c @@ -33,6 +33,7 @@ #define REMOVING_VALUE 12 #define VELOCITY_VALUE 0.45 +static Eina_Bool _screen_reader_close_all_apps(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info); static inline int __get_msec(struct timeval *s, struct timeval *e) { @@ -42,6 +43,7 @@ static inline int __get_msec(struct timeval *s, struct timeval *e) void close_button_disabled_set(Eina_Bool is_disabled) { main_h main_info = main_get_info(); + Evas_Object *access_obj = NULL; char text[256] = { 0 }; memset(text, 0, sizeof(text)); snprintf(text, sizeof(text), S_(STRING_TASK_MGR_CLOSE_ALL)); @@ -51,7 +53,14 @@ void close_button_disabled_set(Eina_Bool is_disabled) elm_object_signal_emit(main_info->layout, "set,close,show", "close.bg"); elm_object_translatable_part_text_set(main_info->layout, "close_all_text", text); } + + /* Screen Reader */ + access_obj = elm_access_object_get((Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(main_info->layout), "close_all_text")); + if (access_obj) { + elm_atspi_accessible_can_highlight_set(access_obj, !is_disabled); + } } + void set_freeze_scroller() { main_h main_info = main_get_info(); @@ -390,6 +399,9 @@ void _index_sync(void *data) if (label) elm_label_slide_go(label); eina_list_free(list); + + /* Screen Reader */ + screen_reader_update(cur_page); } void index_create(void *data) @@ -477,6 +489,9 @@ task_mgr_error_e scroller_push_all_item(void *data) index_create(main_info); } + /* Screen Reader */ + screen_reader_set_highlight_by_index(0, EINA_TRUE); + return TASK_MGR_ERROR_NONE; } @@ -506,11 +521,6 @@ static void _br_scroller_ani_start_cb(void *data, Evas_Object *scroller, void *e } -static void _br_scroller_ani_stop_cb(void *data, Evas_Object *scroller, void *event_info) -{ - _D("animation stoped"); -} - static void _box_layout_cb(Evas_Object *o, Evas_Object_Box_Data *priv, void *data) { main_h main_info = data; @@ -560,7 +570,6 @@ static void _scroller_scroll_cb(void *data, Evas_Object *scroller, void *event_i } */ - Evas_Object *scroller_create(void *data) { main_h main_info = data; @@ -583,7 +592,6 @@ Evas_Object *scroller_create(void *data) evas_object_smart_callback_add(scroller, "scroll,drag,start", _br_scroller_drag_start_cb, main_info); evas_object_smart_callback_add(scroller, "scroll", _br_scroller_scrolled_cb, main_info); evas_object_smart_callback_add(scroller, "scroll,anim,start", _br_scroller_ani_start_cb, NULL); - evas_object_smart_callback_add(scroller, "scroll,anim,stop", _br_scroller_ani_stop_cb, NULL); elm_object_style_set(scroller, "effect"); elm_object_part_content_set(main_info->layout, "list", scroller); @@ -624,6 +632,17 @@ Evas_Object *scroller_create(void *data) edje_object_signal_callback_add(elm_layout_edje_get(main_info->layout), "close_button,clicked", "clicked", _delete_all_btn_clicked_cb, main_info); close_button_disabled_set(EINA_TRUE); + /* Screen Reader */ + Evas_Object *ao_close_all_btn = NULL; + ao_close_all_btn = elm_access_object_register((Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(main_info->layout), "close_all_text"), main_info->layout); + elm_atspi_accessible_name_set(ao_close_all_btn, strdup(S_("WDS_ST_ACBUTTON_CLOSE_ALL_ABB"))); + elm_atspi_accessible_description_set(ao_close_all_btn, strdup(S_("IDS_ACCS_BODY_BUTTON_TTS"))); + elm_atspi_accessible_translation_domain_set(ao_close_all_btn, PACKAGE); + elm_atspi_accessible_reading_info_type_set(ao_close_all_btn, (ELM_ACCESSIBLE_READING_INFO_TYPE_NAME | ELM_ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION)); + elm_access_action_cb_set(ao_close_all_btn, ELM_ACCESS_ACTION_ACTIVATE, _screen_reader_close_all_apps, main_info); + + elm_atspi_accessible_can_highlight_set(index, EINA_FALSE); + return scroller; } @@ -668,9 +687,20 @@ void scroller_destroy(Evas_Object *scroller) evas_object_smart_callback_del(scroller, "scroll,drag,start", _br_scroller_drag_start_cb); evas_object_smart_callback_del(scroller, "scroll", _br_scroller_scrolled_cb); evas_object_smart_callback_del(scroller, "scroll,anim,start", _br_scroller_ani_start_cb); - evas_object_smart_callback_del(scroller, "scroll,anim,stop", _br_scroller_ani_stop_cb); evas_object_del(scroller); scroller = NULL; } +static Eina_Bool _screen_reader_close_all_apps(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info) +{ + if (data == NULL) { + _E("parameter is NULL"); + return EINA_TRUE; + } + + _delete_all_btn_clicked_cb(data, NULL, NULL, NULL); + + return EINA_TRUE; +} + /* End of the file */ -- 2.7.4