Support null context 53/281953/5 accepted/tizen/6.0/unified/20220927.070331 accepted/tizen/6.0/unified/20221012.005822 submit/tizen_6.0/20220927.051249 submit/tizen_6.0/20221011.042023
authorArtur Świgoń <a.swigon@samsung.com>
Fri, 23 Sep 2022 10:47:50 +0000 (12:47 +0200)
committerArtur Świgoń <a.swigon@samsung.com>
Mon, 26 Sep 2022 14:33:24 +0000 (16:33 +0200)
Null context allows the Screen Reader to yield control to applications
whose existence it is not aware of, like DALi/NUI apps. The null context
is not actually a NULL pointer, but a special desktop object, because
the code expects a non-NULL pointer in so many places.

Change-Id: I41901899a84315cc92507c09e8471195b721ede3

include/app_tracker.h
src/app_tracker.c
src/navigator.c
src/window_tracker.c

index af58bb8f601a513362b84534c1a1120da89a88cd..178bdc469fa8d5866b10da4cdce94899c3284834 100644 (file)
@@ -73,4 +73,25 @@ AtspiAccessible* app_tracker_at_point_window_get(App_Tracker_Data *atd, int x, i
  */
 WindowInfo* app_tracker_top_window_info_get(App_Tracker_Data *atd);
 
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+AtspiAccessible* app_tracker_desktop_get(App_Tracker_Data *atd);
+
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+bool app_tracker_null_context_is(App_Tracker_Data *atd);
+
+/**
+ * @brief This function allows access to submodule functinality of app_tracker.
+ *
+ * @param atd internal data of app tracker module
+ */
+void app_tracker_null_context_switch(App_Tracker_Data *atd);
+
 #endif /* end of include guard: APP_TRACKER_H_ */
index ec0c142883fcd74ccaaadd5b14c6e795228cce4f..decd217d02752bbece9c8f5be82114ec3df6bb4a 100644 (file)
@@ -51,6 +51,7 @@ struct _App_Tracker_Data {
        AtspiAccessible *scroll_gesture_required_obj;
 #endif
        WindowTrackerData *window_tracker_data;
+       AtspiAccessible *desktop;
 };
 
 #ifndef SCREEN_READER_TV
@@ -657,6 +658,10 @@ app_tracker_init(AppTrackerEventWithDefaultLabelInfoCB view_content_changed_cb,
        */
 #endif
 
+       atd->desktop = atspi_get_desktop(0);
+       if (!atd->desktop)
+               ERROR("atspi_get_desktop() failed");
+
        atd->new_obj_highlighted_callback = NULL;
        atd->new_obj_highlighted_callback_user_data = NULL;
        atd->listener = atspi_event_listener_new(_on_atspi_event_cb, atd, NULL);
@@ -695,6 +700,8 @@ void app_tracker_shutdown(App_Tracker_Data *atd)
        g_object_unref(atd->listener);
        atd->listener = NULL;
 
+       g_object_unref(atd->desktop);
+
        atd->new_obj_highlighted_callback = NULL;
        if (atd->new_obj_highlighted_callback_user_data) {
                WARNING("You should deregister new_obj_highlighted_callback before shutdown!");
@@ -815,3 +822,23 @@ WindowInfo* app_tracker_top_window_info_get(App_Tracker_Data *atd)
        return atd ? window_tracker_top_window_info_get(atd->window_tracker_data) : NULL;
 }
 
+AtspiAccessible* app_tracker_desktop_get(App_Tracker_Data *atd)
+{
+       return atd ? atd->desktop : NULL;
+}
+
+bool app_tracker_null_context_is(App_Tracker_Data *atd)
+{
+       FlatNaviContext *ctx = navigator_get_flat_navi_context(atd->view_content_changed_ecd->user_data);
+
+       return flat_navi_context_root_get(ctx) == app_tracker_desktop_get(atd);
+}
+
+void app_tracker_null_context_switch(App_Tracker_Data *atd)
+{
+       FlatNaviContext *ctx = navigator_get_flat_navi_context(atd->view_content_changed_ecd->user_data);
+
+       DEBUG("Setting null context");
+
+       flat_navi_context_root_change(ctx, app_tracker_desktop_get(atd));
+}
index c6be2912724949fae0a6fd1e9cdab95ed921e55f..446d2ef7f2643176628c8c3ce8bab43fcfb12136 100644 (file)
@@ -555,7 +555,10 @@ TIZEN_PROD_STATIC void _window_at_point_check(NavigatorData *nd, int x, int y)
        touched_window = app_tracker_at_point_window_get(nd->app_tracker_data, x, y);
        context_root = flat_navi_context_root_get(nd->flat_navi_context);
 
-       if (!touched_window || !context_root) return;
+       if (!touched_window) {
+               app_tracker_null_context_switch(nd->app_tracker_data);
+               return;
+       }
 
        touched_window_bus_name = atspi_accessible_get_bus_name(touched_window, NULL);
        context_root_bus_name = atspi_accessible_get_bus_name(context_root, NULL);
@@ -2244,6 +2247,12 @@ TIZEN_PROD_STATIC void on_gesture_detected(void *data, const Eldbus_Message *msg
        DEBUG("Incoming gesture name is %s : %d %d %d %d %d", utils_enum_to_string(info->type),
                  info->x_beg, info->y_beg, info->x_end, info->y_end, info->state);
 
+       if (info->type != ONE_FINGER_SINGLE_TAP && app_tracker_null_context_is(nd->app_tracker_data)) {
+               DEBUG("Ignoring gesture because of null context");
+               g_free(info);
+               return;
+       }
+
        _on_auto_review_stop(nd);
 
        if (info->type == ONE_FINGER_SINGLE_TAP && info->state == 3) {
@@ -2807,4 +2816,3 @@ Eina_Bool navigator_get_is_text_selection_mode(NavigatorData *nd) {
        if (!nd) { ERROR("NavigatorData is NULL!"); }
        return nd ? nd->is_text_selection_mode : EINA_FALSE;
 }
-
index a0488f0d0d0bdb45de89a086a715b377cd0ef94a..9a86ec4fe61674cfb7040a3f680d1026ee59025c 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <string.h>
 
+#include <app_tracker.h>
 #include <logger.h>
 #include <screen_reader.h>
 #include <utils.h>
@@ -29,7 +30,7 @@
 struct WindowTrackerDataImpl
 {
        WindowTrackerCb user_cb;
-       void *user_data;
+       void *user_data; // App_Tracker_Data *
        AtspiEventListener *listener;
        AtspiAccessible *last_active_win;
        AtspiAccessible *top_win;
@@ -156,6 +157,9 @@ static void _purge_windows_list(WindowTrackerData *wtd)
                                wtd->user_cb(wtd->user_data, top_window);
                        }
                }
+
+               if (!wi_top)
+                       app_tracker_null_context_switch(wtd->user_data);
        }
 }
 
@@ -315,6 +319,10 @@ static void _window_remove(WindowTrackerData *wtd, AtspiAccessible *window)
                                if (top_window)
                                        wtd->user_cb(wtd->user_data, top_window);
                        }
+
+                       if (!top_window)
+                               app_tracker_null_context_switch(wtd->user_data);
+
                        gchar *id = atspi_accessible_get_unique_id(top_window, NULL);
                        DEBUG("top window: %s", id);
                        g_free(id);