Fix for toast popup reading 53/284453/1
authorLukasz Oleksak <l.oleksak@samsung.com>
Thu, 10 Nov 2022 10:30:36 +0000 (11:30 +0100)
committerLukasz Oleksak <l.oleksak@samsung.com>
Thu, 17 Nov 2022 09:04:49 +0000 (09:04 +0000)
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 7d5efe7fa46823b4b584ee3541a7dfcf65788729..7820b2dcd5c80218691211353c64a79d328af8b2 100644 (file)
@@ -119,7 +119,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 9e327f1909f6463da3570eb16a73c1ff3fb32cb3..629e313ed5e41e2744c40264e626e2e6aef15f9d 100644 (file)
@@ -89,6 +89,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 a31460b79d5639a0128dacccaefa53337d4876cd..e68ef2f768f8dae9d004f3d548b04c1dccea1267 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);
@@ -324,28 +321,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) {
@@ -355,9 +342,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");
@@ -401,7 +386,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");
@@ -412,7 +397,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);
@@ -424,7 +409,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);
@@ -435,7 +420,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)) {
                Eina_Strbuf *buf = eina_strbuf_new();
                if (event->detail1) {
                        if (role == ATSPI_ROLE_TOGGLE_BUTTON)
@@ -454,7 +439,7 @@ static void _on_atspi_event_cb(AtspiEvent *event, void *user_data)
                }
                tw_speak_and_free(eina_strbuf_release(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)) {
                gchar *name = atspi_accessible_get_name(event->source, NULL);
                if (!name) {
                        ERROR("name is null");
index 989db794b70e1d9e6091928675c58d6e4f234478..27e4f2b652655e25b66c75d56ffea26b18c0aab1 100644 (file)
@@ -2582,6 +2582,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:
@@ -2597,7 +2599,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 420fd0064579f5b5bd9c0f19c2709c450d5b5e61..df4337788de9e5f48ceef6e41f9b20c2d4376a31 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 15ff37179f3754f6835ead6827bcb387a490cf8d..945c9d098f1333e45596e0dfbcbec73267afa994 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 uint32_t _window_resource_id_get(AtspiAccessible *window)
 {
        uint32_t resource_id = 0;
@@ -295,11 +283,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);
@@ -382,7 +365,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("object:state-changed:visible", event->type)
                           && name && (!g_strcmp0(name, "Quickpanel Window") || !g_strcmp0(name, "volume") || !g_strcmp0(name, "Keyboard"))) {
 
@@ -409,19 +391,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);
@@ -545,7 +514,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;
 
@@ -745,8 +713,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 *));