Fix for toast popup reading 54/284454/1 accepted/tizen/6.5/unified/20221129.124316 submit/tizen_6.5/20221124.012612
authorLukasz Oleksak <l.oleksak@samsung.com>
Thu, 10 Nov 2022 10:30:36 +0000 (11:30 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Thu, 17 Nov 2022 09:25:01 +0000 (10:25 +0100)
This patch allows a transient notification UI element (like toast popup)
to be read without inducing navigation context change. It requires,
the UI element to be given an ATSPI_ROLE_NOTIFICATION by application developer.
This is analogous case to the requirement of seting ATSPI_ROLE_TOGGLE_BUTTON role
for button using custom tizen theme style.

Change-Id: I373e6f700d28364967d256af280e33de34083b36

include/utils.h
include/window_tracker.h
src/app_tracker.c
src/navigator.c
src/utils.c
src/window_tracker.c
tests2/wrappers/mocked_app_tracker.cpp
tests2/wrappers/mocked_app_tracker.h
tests2/wrappers/mocked_window_tracker.cpp
tests2/wrappers/mocked_window_tracker.h

index 0eff4eef289ba69724e68818a62b9819c3e4b43f..99ee7ea4b8fcbeb5585d05f4eac17b841f65839d 100644 (file)
@@ -113,7 +113,7 @@ enum Reading_Info {
        ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION = 1 << 2,
        ACCESSIBLE_READING_INFO_TYPE_STATE = 1 << 3
 };
-unsigned short int get_objects_attributes(AtspiAccessible *obj);
+unsigned short int get_object_reading_info_type_attributes(AtspiAccessible *obj);
 void utils_a11y_bus_connection_set(Eldbus_Connection *conn);
 Eldbus_Connection *utils_a11y_bus_connection_get(void);
 
index 6ae9f965493a8a71ee456a5682aa7ca9c4cb7bc8..b7b3128bc0ef4b7e89bbb3cbd278bdc04c660ea0 100644 (file)
@@ -84,6 +84,4 @@ WindowActivateInfoType window_tracker_window_activate_info_type_get(WindowTracke
 
 WindowInfo* window_tracker_top_window_info_get(WindowTrackerData *wtd);
 
-AtspiAccessible* window_tracker_subroot_get(WindowTrackerData *wtd);
-
 #endif // WINDOW_TRACKER_H
index 8f299e90444cb1924fa14dd32143ac1391d5a1ad..a61aeb209d726cda35ee43dfe659b88c9ad47407 100644 (file)
@@ -118,9 +118,6 @@ static gboolean _on_timeout_rebuild_navigation_context(gpointer user_data)
                        }
                }
 
-               if (default_label_enabled)
-                       tw_purge(EINA_TRUE);
-
                gchar *id = atspi_accessible_get_unique_id(dli->obj, NULL);
                DEBUG("Rebuilding navigation context - root: %s, role: %d, default_label_enabled : %s", id, dli->role, default_label_enabled ? "true" : "false");
                g_free(id);
@@ -325,28 +322,18 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                                // refresh default label for newly showing page tab
                                DEBUG("Refreshing TAB");
                                timer_reschedule(atd);
+                       } else if (role == ATSPI_ROLE_NOTIFICATION) {
+                               // Read notification without rebuilding context
+                               char *text_to_speak = NULL;
+                               ReadingComposerData *rc = reading_composer_data_get(event->source);
+                               text_to_speak = reading_composer_description_get(rc);
+                               reading_composer_data_free(rc);
+                               DEBUG("READING NOTIFICATION : %s", text_to_speak ? text_to_speak : "text_to_speak nil");
+                               tw_speak_customized(text_to_speak, EINA_TRUE, EINA_TRUE, event->source, 0);
+                               free(text_to_speak);
                        } else if (object_has_modal_role(role)) {
-                               // push modal to base_root stack
-                               DEBUG("Pushing modal: ROLE: %d", role);
-                               Service_Data *sd = get_pointer_to_service_data_struct();
-                               Eina_Bool is_text_selection_mode = navigator_get_is_text_selection_mode(sd->navigator_data);
-                               if (is_text_selection_mode) {
-                                       /*TODO: this ignores toast popup providing cut, copy information.
-                                       if other popup is showing then rebuild navigation context. */
-                                       goto end;
-                               }
-                               if (window_tracker_subroot_get(atd->window_tracker_data)) {
-                                       char *text_to_speak = NULL;
-                                       ReadingComposerData *rc = reading_composer_data_get(event->source);
-                                       text_to_speak = reading_composer_description_get(rc);
-                                       reading_composer_data_free(rc);
-                                       DEBUG("SPEAK : %s", text_to_speak ? text_to_speak : "text_to_speak nil");
-                                       tw_speak_customized(text_to_speak, EINA_TRUE, EINA_TRUE, event->source, 0);
-                                       free(text_to_speak);
-                               }
-                               else {
-                                       timer_reschedule(atd);
-                               }
+                               DEBUG("Rebuilding context on modal PUSH");
+                               timer_reschedule(atd);
                        }
                } else { /* Not Showing */
                        if (role == ATSPI_ROLE_WINDOW) {
@@ -356,9 +343,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                                DEBUG("Remove Window");
                                window_tracker_window_remove(atd->window_tracker_data, event->source);
                        } else if (object_has_modal_role(role)) {
-                               //TODO: check if source is same with modals->data
-                               // pop modal
-                               DEBUG("Pop modal");
+                               DEBUG("Rebuilding context on modal POP");
                                timer_reschedule(atd);
                        } else if (atspi_accessible_is_equal(flat_navi_context_current_get(navigator_get_flat_navi_context(atd->view_content_changed_ecd->user_data)), event->source)) {
                                DEBUG("Current highlighted object becomes not-showing");
@@ -402,7 +387,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                        }
                }
        } else if (!g_strcmp0(event->type, "object:property-change:accessible-name") && object_has_highlighted_state(event->source)
-                        && (get_objects_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_NAME)) {
+                        && (get_object_reading_info_type_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_NAME)) {
                gchar *name = atspi_accessible_get_name(event->source, NULL);
                if (!name) {
                        ERROR("name is null");
@@ -413,7 +398,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                g_free(name);
                goto end;
        } else if (!g_strcmp0(event->type, "object:property-change:accessible-value")) { // for reading slider and spinner value changes
-               if (role == ATSPI_ROLE_SLIDER && (get_objects_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_STATE)) {
+               if (role == ATSPI_ROLE_SLIDER && (get_object_reading_info_type_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_STATE)) {
                        _read_value(event->source);
                } else if (role == ATSPI_ROLE_FILLER) {
                        gchar *name = atspi_accessible_get_name(event->source, NULL);
@@ -425,7 +410,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                        g_free(name);
                }
        } else if (!g_strcmp0(event->type, "object:state-changed:animated") && (role == ATSPI_ROLE_LIST_ITEM)
-                          && (get_objects_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION)) {
+                          && (get_object_reading_info_type_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_DESCRIPTION)) {
                GError *err = NULL;
                char buf[256] = "\0";
                gint idx = atspi_accessible_get_index_in_parent(event->source, &err);
@@ -436,7 +421,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                tw_speak_customized(buf, EINA_TRUE, EINA_TRUE, event->source, 0);
                g_error_free(err);
        } else if (!g_strcmp0(event->type, "object:state-changed:checked")
-                        && (get_objects_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_STATE)) {
+                        && (get_object_reading_info_type_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_STATE)) {
                char buf[256] = "\0";
                if (event->detail1) {
                        if (role == ATSPI_ROLE_TOGGLE_BUTTON)
@@ -455,7 +440,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                }
                tw_speak(buf, EINA_TRUE);
        } else if (!g_strcmp0(event->type, "object:state-changed:selected")
-                          && (get_objects_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_STATE)) {
+                          && (get_object_reading_info_type_attributes(event->source) & ACCESSIBLE_READING_INFO_TYPE_STATE)) {
                char buf[256] = "\0";
                gchar *name = atspi_accessible_get_name(event->source, NULL);
                if (!name) {
index 10923c75115850cee34bd1d83c67e54015a0796b..3f67adb9564376678b9ee4e53c694a8fed2c99d9 100644 (file)
@@ -2599,6 +2599,8 @@ TIZEN_PROD_STATIC void _view_content_changed(AtspiAccessible *root, AtspiRole ro
                return;
        }
 
+       tw_purge(EINA_TRUE);
+
        switch (role) {
        case ATSPI_ROLE_POPUP_MENU:
        case ATSPI_ROLE_PANEL:
@@ -2614,7 +2616,6 @@ TIZEN_PROD_STATIC void _view_content_changed(AtspiAccessible *root, AtspiRole ro
        }
 
        _check_app_gesture_support(nd, root);
-
        if (vc_get_sound_feedback())
                smart_notification(WINDOW_STATE_CHANGE_NOTIFICATION_EVENT, 0, 0);
        DEBUG("END");
index 06878a893f629855e87180055df245912b9e0af6..dea3fafa78a070eb25f55ae300273b8352c50875 100644 (file)
@@ -150,7 +150,7 @@ Eina_Bool cycle_detection_check_if_in_cycle(cycle_detection_data *data, const vo
        return EINA_FALSE;
 }
 
-unsigned short int get_objects_attributes(AtspiAccessible *obj)
+unsigned short int get_object_reading_info_type_attributes(AtspiAccessible *obj)
 {
        unsigned short int attribute = 0;
        gchar *reading_info = NULL;
index b5be929493644e86ef5b231082a5482dde218f49..b037851b7611af1ae9982b413600b980ff5d8c50 100644 (file)
@@ -33,7 +33,6 @@ struct WindowTrackerDataImpl
        AtspiEventListener *listener;
        AtspiAccessible *last_active_win;
        AtspiAccessible *top_win;
-       AtspiAccessible *subroot;
        Eina_List *window_infos;
        AtspiAccessible *keyboard_window;
 };
@@ -172,17 +171,6 @@ static void _window_stack_print(WindowTrackerData *wtd)
        }
 }
 
-static Eina_Bool _is_window_in_stack(WindowTrackerData *wtd, AtspiAccessible *window)
-{
-       Eina_List *l;
-       WindowInfo *wi;
-
-       EINA_LIST_FOREACH(wtd->window_infos, l, wi)
-               if(wi && atspi_accessible_is_equal(wi->window, window)) return EINA_TRUE;
-
-       return EINA_FALSE;
-}
-
 static void _window_append(WindowTrackerData *wtd, AtspiAccessible *window, Eina_Bool view_change_need,
                                                   Eina_Bool keyboard_window_is, WindowActivateInfoType window_activate_info_type)
 {
@@ -278,11 +266,6 @@ static void _window_remove(WindowTrackerData *wtd, AtspiAccessible *window)
                removed_index++;
        }
 
-       if (wtd->subroot && atspi_accessible_is_equal(window, wtd->subroot)) {
-               DEBUG("Remove subroot: %p ", wtd->subroot);
-               wtd->subroot = NULL;
-       }
-
        if (!window_removed) {
                gchar *id = atspi_accessible_get_unique_id(window, NULL);
                DEBUG("END - try to remove not appended window: %s", id);
@@ -362,7 +345,6 @@ static void _on_atspi_window_cb(AtspiEvent *event, void *user_data)
                        goto end;
                }
                _window_append(wtd, event->source, EINA_TRUE, EINA_FALSE, window_activate_info_type);
-               wtd->subroot = NULL; //No need to keep subroot if any window gets activated
        } else if (!g_strcmp0(event->type, "window:deactivate")) {
                DEBUG("Remove Window");
                _window_remove(wtd, event->source);
@@ -392,19 +374,6 @@ static void _on_atspi_window_cb(AtspiEvent *event, void *user_data)
                        else
                                _window_remove(wtd, event->source);
                }
-
-               if (role == ATSPI_ROLE_WINDOW) {
-                       if (event->detail1) { /* Visible */
-                               if (!_is_window_in_stack(wtd, event->source)) {
-                                       DEBUG("Store subroot window: %p", event->source);
-                                       wtd->subroot = event->source;
-                               }
-                       }
-                       else {
-                               DEBUG("delete subroot window: %p", event->source);
-                               wtd->subroot = NULL;
-                       }
-               }
        }
 end:
        g_free(name);
@@ -437,7 +406,6 @@ WindowTrackerData *window_tracker_init(void)
 
        wtd->last_active_win = NULL;
        wtd->top_win = NULL;
-       wtd->subroot = NULL;
        wtd->window_infos = NULL;
        wtd->keyboard_window = NULL;
 
@@ -610,8 +578,4 @@ AtspiAccessible* window_tracker_top_win_get(WindowTrackerData *wtd)
        return wtd ? wtd->top_win : NULL;
 }
 
-AtspiAccessible* window_tracker_subroot_get(WindowTrackerData *wtd)
-{
-       return wtd ? wtd->subroot : NULL;
-}
 
index da2fb3596c8ddbc278bd02aa03729b514b66a661..6a806fee6e06930a3619ca0da587ce7a2e697dc6 100644 (file)
@@ -91,7 +91,6 @@ IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_append, window_trac
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_remove, window_tracker_keyboard_window_remove, void(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK3(mock_window_tracker_register, window_tracker_register, void(WindowTrackerData *, WindowTrackerCb, void *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_shutdown, window_tracker_shutdown, void(WindowTrackerData *));
-IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_subroot_get, window_tracker_subroot_get, AtspiAccessible *(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_top_win_get, window_tracker_top_win_get, AtspiAccessible *(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_top_window_get, window_tracker_top_window_get, AtspiAccessible *(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_top_window_info_get, window_tracker_top_window_info_get, WindowInfo *(WindowTrackerData *));
index c90cf0983b34db1acfbafb4e7e919dd7690d08bd..c0f98d4b6a886a913ac23b541c645463e7f49188 100644 (file)
@@ -105,7 +105,6 @@ DECLARE_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_append, window_tracke
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_remove, window_tracker_keyboard_window_remove, void(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK3(mock_window_tracker_register, window_tracker_register, void(WindowTrackerData *, WindowTrackerCb, void *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_shutdown, window_tracker_shutdown, void(WindowTrackerData *));
-DECLARE_FUNCTION_MOCK1(mock_window_tracker_subroot_get, window_tracker_subroot_get, AtspiAccessible *(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_top_win_get, window_tracker_top_win_get, AtspiAccessible *(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_top_window_get, window_tracker_top_window_get, AtspiAccessible *(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_top_window_info_get, window_tracker_top_window_info_get, WindowInfo *(WindowTrackerData *));
index 552715465126702395d6aa702060ca66edabec2b..e22f5a842596ba3dc23c50d518d79e8a2250ee71 100644 (file)
@@ -53,7 +53,6 @@ IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_append, window_trac
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_remove, window_tracker_keyboard_window_remove, void(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK3(mock_window_tracker_register, window_tracker_register, void(WindowTrackerData *, WindowTrackerCb, void *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_shutdown, window_tracker_shutdown, void(WindowTrackerData *));
-IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_subroot_get, window_tracker_subroot_get, AtspiAccessible *(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_top_win_get, window_tracker_top_win_get, AtspiAccessible *(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_top_window_get, window_tracker_top_window_get, AtspiAccessible *(WindowTrackerData *));
 IMPLEMENT_FUNCTION_MOCK1(mock_window_tracker_top_window_info_get, window_tracker_top_window_info_get, WindowInfo *(WindowTrackerData *));
index 6dd301df129565dfa7065496f7029d4723e46de2..875a102318cf019ea7715ec8ba197a2dbe2428fe 100644 (file)
@@ -62,7 +62,6 @@ DECLARE_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_append, window_tracke
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_keyboard_window_remove, window_tracker_keyboard_window_remove, void(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK3(mock_window_tracker_register, window_tracker_register, void(WindowTrackerData *, WindowTrackerCb, void *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_shutdown, window_tracker_shutdown, void(WindowTrackerData *));
-DECLARE_FUNCTION_MOCK1(mock_window_tracker_subroot_get, window_tracker_subroot_get, AtspiAccessible *(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_top_win_get, window_tracker_top_win_get, AtspiAccessible *(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_top_window_get, window_tracker_top_window_get, AtspiAccessible *(WindowTrackerData *));
 DECLARE_FUNCTION_MOCK1(mock_window_tracker_top_window_info_get, window_tracker_top_window_info_get, WindowInfo *(WindowTrackerData *));