Screen Reader refactor
authorPatryk Kaczmarek <patryk.k@samsung.com>
Tue, 19 May 2015 16:31:42 +0000 (18:31 +0200)
committerPatryk Kaczmarek <patryk.k@samsung.com>
Mon, 25 May 2015 17:19:45 +0000 (19:19 +0200)
   * Change focus highlight frame to accessibility highlight
   * Grab focus changed to grab highlight in navigator
   * Text to say generated in navigator on highlight( before on state-changed:focused )
   * application window tracker now based children-changed event from desktop
   * More logging
   * Other refactor

Change-Id: I9c27bff2bfa19a577b2613727099ca0aee616267
Signed-off-by: Patryk Kaczmarek <patryk.k@samsung.com>
15 files changed:
include/screen_reader.h
src/app_tracker.c
src/flat_navi.c
src/gesture_tracker.c
src/main.c [changed mode: 0755->0644]
src/navigator.c
src/object_cache.c
src/screen_reader.c [changed mode: 0755->0644]
src/screen_reader_spi.c
src/screen_reader_tts.c
src/screen_reader_vconf.c
src/window_tracker.c
tests/atspi/atspi.c
tests/atspi/atspi.h
tests/smart_navi_suite.c

index 907e4ee..e0e7bca 100644 (file)
@@ -12,9 +12,7 @@
 #define MAX_POS_REACHED ", end of text reached"
 #define MIN_POS_REACHED ", begin of text reached"
 
-#define FOCUS_SIG "focused"
-
-#define FOCUS_CHANGED_SIG "object:state-changed:focused"
+#define HIGHLIGHT_CHANGED_SIG "object:state-change:highlighted"
 #define VALUE_CHANGED_SIG "object:property-change:accessible-value"
 #define CARET_MOVED_SIG "object:text-caret-moved"
 
index 17355a3..15fbcdd 100644 (file)
@@ -38,6 +38,7 @@ _is_descendant(AtspiAccessible *ancestor, AtspiAccessible *descendant)
 static void
 _subtree_callbacks_call(AppTrackerEventType event, SubTreeRootData *std)
 {
+   DEBUG("START");
    GList *l;
    EventCallbackData *ecd;
 
@@ -49,23 +50,29 @@ _subtree_callbacks_call(AppTrackerEventType event, SubTreeRootData *std)
              ecd->func(event, ecd->user_data);
           }
      }
+   DEBUG("END");
 }
 
 static gboolean
 _on_timeout_cb(gpointer user_data)
 {
+   DEBUG("START");
    SubTreeRootData *std = user_data;
 
    _subtree_callbacks_call(APP_TRACKER_EVENT_VIEW_CHANGED, std);
 
    std->timer = 0;
-
+   DEBUG("END");
    return FALSE;
 }
 
-static void 
+static void
 _on_atspi_event_cb(const AtspiEvent *event)
 {
+   DEBUG("START");
+   DEBUG("signal:%s", event->type);
+   if (!event->source)
+     ERROR("empty event source");
    GList *l;
    SubTreeRootData *std;
 
@@ -89,6 +96,7 @@ _on_atspi_event_cb(const AtspiEvent *event)
 static int
 _app_tracker_init_internal(void)
 {
+   DEBUG("START");
    _listener = atspi_event_listener_new_simple(_on_atspi_event_cb, NULL);
 
    atspi_event_listener_register(_listener, "object:state-changed:showing", NULL);
@@ -134,6 +142,7 @@ _app_tracker_shutdown_internal(void)
 
 int app_tracker_init(void)
 {
+   DEBUG("START");
    if (!_init_count)
      if (_app_tracker_init_internal()) return -1;
    return ++_init_count;
@@ -148,6 +157,7 @@ void app_tracker_shutdown(void)
 
 void app_tracker_callback_register(AtspiAccessible *app, AppTrackerEventType event, AppTrackerEventCB cb, void *user_data)
 {
+   DEBUG("START");
    SubTreeRootData *rd = NULL;
    EventCallbackData *cd;
    GList *l;
@@ -180,10 +190,12 @@ void app_tracker_callback_register(AtspiAccessible *app, AppTrackerEventType eve
    cd->user_data = user_data;
 
    rd->callbacks = g_list_append(rd->callbacks, cd);
+   DEBUG("END");
 }
 
 void app_tracker_callback_unregister(AtspiAccessible *app, AppTrackerEventType event, AppTrackerEventCB cb, void *user_data)
 {
+   DEBUG("START");
    GList *l;
    EventCallbackData *ecd;
    SubTreeRootData *std = NULL;
index 849977e..d843ced 100644 (file)
@@ -12,6 +12,9 @@ struct _FlatNaviContext {
 };
 
 static const AtspiStateType required_states[] = {
+     ATSPI_STATE_SHOWING,
+     ATSPI_STATE_VISIBLE,
+     ATSPI_STATE_FOCUSABLE,
      ATSPI_STATE_LAST_DEFINED
 };
 
@@ -102,8 +105,6 @@ typedef struct {
 static FilterResult
 _accessible_list_split_with_filter(Eina_List *list, Eina_Each_Cb cb, void *user_data)
 {
-
-   DEBUG("START");
    FilterResult ret = { NULL, NULL};
    Eina_List *l, *ln;
    AtspiAccessible *obj;
@@ -117,40 +118,39 @@ _accessible_list_split_with_filter(Eina_List *list, Eina_Each_Cb cb, void *user_
           eina_list_move_list(&ret.failure, &list, l);
      }
 
-   DEBUG("END");
    return ret;
 }
 
 static Eina_Bool
 _filter_state_cb(const void *container, void *data, void *fdata)
 {
-   DEBUG("START");
-
    AtspiStateType *state = data;
+
    Eina_Bool ret = EINA_TRUE;
    AtspiAccessible *obj = fdata;
+
    AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
 
+   if (atspi_accessible_get_role(obj, NULL) == ATSPI_ROLE_LIST_ITEM)
+     return EINA_TRUE;
+
    while (*state != ATSPI_STATE_LAST_DEFINED)
      {
         if (!atspi_state_set_contains(ss, *state))
           {
              ret = EINA_FALSE;
-             DEBUG("BREAK, NO STATES SUIABLE FOR OBJ");
              break;
           }
         state++;
      }
 
    g_object_unref(ss);
-   DEBUG("END");
    return ret;
 }
 
 static Eina_Bool
 _filter_role_cb(const void *container, void *data, void *fdata)
 {
-   DEBUG("START");
    AtspiRole *role = data;
    Eina_Bool ret = EINA_FALSE;
    AtspiAccessible *obj = fdata;
@@ -160,34 +160,27 @@ _filter_role_cb(const void *container, void *data, void *fdata)
         if (atspi_accessible_get_role(obj, NULL) == *role)
           {
              ret = EINA_TRUE;
-             DEBUG("END");
              break;
           }
         role++;
      }
-   DEBUG("END WITH FALSE");
    return ret;
 }
 
-static inline Eina_Bool
-_rectangle_intersect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
-{
-   return !(((y1 + h1) <= y2) || (y1 >= (y2 + h2)) || ((x1 + w1) <= x2) || (x1 >= (x2 + w2)));
-}
-
 static Eina_Bool
 _filter_viewport_cb(const void *container, void *data, void *fdata)
 {
-   const ObjectCache *oc, *ocr = data;
+   const ObjectCache *oc = data;
    AtspiAccessible *obj = fdata;
 
    oc = object_cache_get(obj);
    if (!oc || !oc->bounds || (oc->bounds->height < 0) || (oc->bounds->width < 0))
      return EINA_FALSE;
 
-   // at least one pixel of child have to be in viewport
-   return _rectangle_intersect(ocr->bounds->x, ocr->bounds->y, ocr->bounds->width, ocr->bounds->height,
-                               oc->bounds->x, oc->bounds->y, oc->bounds->width, oc->bounds->height);
+   if (((oc->bounds->x + oc->bounds->width) < 0) || ((oc->bounds->y + oc->bounds->height) < 0))
+     return EINA_FALSE;
+
+   return EINA_TRUE;
 }
 
 static Eina_List*
@@ -201,11 +194,9 @@ _flat_review_candidates_get(AtspiAccessible *root)
    DEBUG("All descendants: %d", eina_list_count(desc));
    Eina_List *l, *ln;
    AtspiAccessible *obj;
-   AtspiStateSet *st = NULL;
-   GArray *states = NULL;
-   int a;
 
    // remove object that are not in root's viewport
+
    const ObjectCache *oc = object_cache_get(root);
    if (!oc || !oc->bounds || (oc->bounds->height < 0) || (oc->bounds->width < 0))
      {
@@ -227,14 +218,9 @@ _flat_review_candidates_get(AtspiAccessible *root)
    ret = eina_list_merge(ret, fr2.success);
    _accessible_list_free(fr2.failure);
 
-   DEBUG("Candidates: %d", eina_list_count(ret));
+   DEBUG("Candidates after filters count: %d", eina_list_count(ret));
    EINA_LIST_FOREACH_SAFE(ret, l, ln, obj) {
-     DEBUG("Role: %s, Name:%s", atspi_accessible_get_name(obj, NULL), atspi_accessible_get_role_name(obj, NULL));
-     st = atspi_accessible_get_state_set (obj);
-     states = atspi_state_set_get_states (st);
-     DEBUG("Has states:%d", states->len);
-     for (a = 0; a < states->len; ++a)
-       DEBUG("%d", g_array_index (states, AtspiStateType, a));
+     DEBUG("Name:[%s] Role:[%s]", atspi_accessible_get_name(obj, NULL), atspi_accessible_get_role_name(obj, NULL));
    }
 
    return ret;
index 711f09b..411020d 100644 (file)
@@ -73,6 +73,7 @@ static Gesture gesture_name_to_enum (const char *gesture_name)
 
 static void on_gesture_detected(void *context EINA_UNUSED, const Eldbus_Message *msg)
 {
+    DEBUG("START");
     const char *gesture_name;
     int x_s, y_s, x_e, y_e, state;
 
old mode 100755 (executable)
new mode 100644 (file)
index 4bd9872..e510888
@@ -1,4 +1,5 @@
 #include <appcore-efl.h>
+#include <Elementary.h>
 #include <eldbus-1/Eldbus.h>
 #include "navigator.h"
 #include "window_tracker.h"
@@ -15,7 +16,7 @@ Eldbus_Connection *a11y_conn;
 
 static void _init_modules(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
 {
-   printf("START:%s", __func__);
+   DEBUG("START");
    const char *a11y_bus_address = NULL;
 
    logger_init();
@@ -29,7 +30,7 @@ static void _init_modules(void *data, const Eldbus_Message *msg, Eldbus_Pending
 
 static int app_create(void *data)
 {
-    printf("START:%s", __func__);
+    DEBUG("START");
     eldbus_init();
     elm_init(0, NULL);
 
@@ -45,7 +46,7 @@ static int app_create(void *data)
 
 static int app_terminate(void *data)
 {
-    printf("START:%s", __func__);
+    DEBUG("START");
     screen_reader_terminate_service(data);
 
     eldbus_connection_unref(a11y_conn);
@@ -69,7 +70,6 @@ int main(int argc, char **argv)
         .resume = NULL,
         .reset = NULL
     };
-
     ops.data = get_pointer_to_service_data_struct();
 
     return appcore_efl_main("Smart Navigation", &argc, &argv, &ops);
index 423caf6..62b1589 100644 (file)
@@ -15,6 +15,7 @@
 #include "smart_notification.h"
 #include "screen_reader_system.h"
 #include "screen_reader_haptic.h"
+#include "screen_reader_tts.h"
 
 #define QUICKPANEL_DOWN TRUE
 #define QUICKPANEL_UP FALSE
@@ -43,6 +44,217 @@ static AtspiAccessible *top_window;
 static Eina_Bool _window_cache_builded;
 static FlatNaviContext *context;
 
+char *
+state_to_char(AtspiStateType state)
+{
+    switch(state)
+    {
+    case ATSPI_STATE_INVALID:
+        return strdup("ATSPI_STATE_INVALID");
+    case ATSPI_STATE_ACTIVE:
+        return strdup("ATSPI_STATE_ACTIVE");
+    case ATSPI_STATE_ARMED:
+        return strdup("ATSPI_STATE_ARMED");
+    case ATSPI_STATE_BUSY:
+        return strdup("ATSPI_STATE_BUSY");
+    case ATSPI_STATE_CHECKED:
+        return strdup("ATSPI_STATE_CHECKED");
+    case ATSPI_STATE_COLLAPSED:
+        return strdup("ATSPI_STATE_COLLAPSED");
+    case ATSPI_STATE_DEFUNCT:
+        return strdup("ATSPI_STATE_DEFUNCT");
+    case ATSPI_STATE_EDITABLE:
+        return strdup("ATSPI_STATE_EDITABLE");
+    case ATSPI_STATE_ENABLED:
+        return strdup("ATSPI_STATE_ENABLED");
+    case ATSPI_STATE_EXPANDABLE:
+        return strdup("ATSPI_STATE_EXPANDABLE");
+    case ATSPI_STATE_EXPANDED:
+        return strdup("ATSPI_STATE_EXPANDED");
+    case ATSPI_STATE_FOCUSABLE:
+        return strdup("ATSPI_STATE_FOCUSABLE");
+    case ATSPI_STATE_FOCUSED:
+        return strdup("ATSPI_STATE_FOCUSED");
+    case ATSPI_STATE_HAS_TOOLTIP:
+        return strdup("ATSPI_STATE_HAS_TOOLTIP");
+    case ATSPI_STATE_HORIZONTAL:
+        return strdup("ATSPI_STATE_HORIZONTAL");
+    case ATSPI_STATE_ICONIFIED:
+        return strdup("ATSPI_STATE_ICONIFIED");
+    case ATSPI_STATE_MULTI_LINE:
+        return strdup("ATSPI_STATE_MULTI_LINE");
+    case ATSPI_STATE_MULTISELECTABLE:
+        return strdup("ATSPI_STATE_MULTISELECTABLE");
+    case ATSPI_STATE_OPAQUE:
+        return strdup("ATSPI_STATE_OPAQUE");
+    case ATSPI_STATE_PRESSED:
+        return strdup("ATSPI_STATE_PRESSED");
+    case ATSPI_STATE_RESIZABLE:
+        return strdup("ATSPI_STATE_RESIZABLE");
+    case ATSPI_STATE_SELECTABLE:
+        return strdup("ATSPI_STATE_SELECTABLE");
+    case ATSPI_STATE_SELECTED:
+        return strdup("ATSPI_STATE_SELECTED");
+    case ATSPI_STATE_SENSITIVE:
+        return strdup("ATSPI_STATE_SENSITIVE");
+    case ATSPI_STATE_SHOWING:
+        return strdup("ATSPI_STATE_SHOWING");
+    case ATSPI_STATE_SINGLE_LINE:
+        return strdup("ATSPI_STATE_SINGLE_LINE");
+    case ATSPI_STATE_STALE:
+        return strdup("ATSPI_STATE_STALE");
+    case ATSPI_STATE_TRANSIENT:
+        return strdup("ATSPI_STATE_TRANSIENT");
+    case ATSPI_STATE_VERTICAL:
+        return strdup("ATSPI_STATE_VERTICAL");
+    case ATSPI_STATE_VISIBLE:
+        return strdup("ATSPI_STATE_VISIBLE");
+    case ATSPI_STATE_MANAGES_DESCENDANTS:
+        return strdup("ATSPI_STATE_MANAGES_DESCENDANTS");
+    case ATSPI_STATE_INDETERMINATE:
+        return strdup("ATSPI_STATE_INDETERMINATE");
+    case ATSPI_STATE_REQUIRED:
+        return strdup("ATSPI_STATE_REQUIRED");
+    case ATSPI_STATE_TRUNCATED:
+        return strdup("ATSPI_STATE_TRUNCATED");
+    case ATSPI_STATE_ANIMATED:
+        return strdup("ATSPI_STATE_ANIMATED");
+    case ATSPI_STATE_INVALID_ENTRY:
+        return strdup("ATSPI_STATE_INVALID_ENTRY");
+    case ATSPI_STATE_SUPPORTS_AUTOCOMPLETION:
+        return strdup("ATSPI_STATE_SUPPORTS_AUTOCOMPLETION");
+    case ATSPI_STATE_SELECTABLE_TEXT:
+        return strdup("ATSPI_STATE_SELECTABLE_TEXT");
+    case ATSPI_STATE_IS_DEFAULT:
+        return strdup("ATSPI_STATE_IS_DEFAULT");
+    case ATSPI_STATE_VISITED:
+        return strdup("ATSPI_STATE_VISITED");
+    case ATSPI_STATE_CHECKABLE:
+        return strdup("ATSPI_STATE_CHECKABLE");
+    case ATSPI_STATE_HAS_POPUP:
+        return strdup("ATSPI_STATE_HAS_POPUP");
+    case ATSPI_STATE_READ_ONLY:
+        return strdup("ATSPI_STATE_READ_ONLY");
+    case ATSPI_STATE_LAST_DEFINED:
+        return strdup("ATSPI_STATE_LAST_DEFINED");
+
+    default:
+       return strdup("\0");
+    }
+
+}
+
+static void
+display_info_about_object(AtspiAccessible *obj)
+{
+    DEBUG("START");
+    DEBUG("------------------------");
+    const char *name = atspi_accessible_get_name(obj, NULL);
+    const char *role = atspi_accessible_get_role_name(obj, NULL);
+    const char *description = atspi_accessible_get_description(obj, NULL);
+    char *state_name = NULL;
+    AtspiStateSet *st = atspi_accessible_get_state_set (obj);
+    GArray *states = atspi_state_set_get_states (st);
+
+    DEBUG("NAME:%s", name);
+    DEBUG("ROLE:%s", role)
+    DEBUG("DESCRIPTION:%s", description);
+    DEBUG("CHILDS:%d", atspi_accessible_get_child_count(obj, NULL));
+    DEBUG("STATES:");
+    int a;
+    AtspiStateType stat;
+    for (a = 0; a < states->len; ++a) {
+        stat = g_array_index (states, AtspiStateType, a);
+        state_name = state_to_char(stat);
+        DEBUG("   %s", state_name);
+        free(state_name);
+    }
+
+    DEBUG("------------------------");
+    DEBUG("END");
+}
+
+char *
+generate_description_for_subtrees(AtspiAccessible *obj)
+{
+    DEBUG("START");
+    if (!obj)
+        return strdup("");
+    int child_count = atspi_accessible_get_child_count(obj, NULL);
+
+    DEBUG("There is %d children inside this filler", child_count);
+    if (!child_count)
+        return strdup("");
+
+    int i;
+    char *name = NULL;
+    char *below = NULL;
+    char ret[256] = "\0";
+    AtspiAccessible *child = NULL;
+    for (i=0; i < child_count; i++) {
+        child = atspi_accessible_get_child_at_index(obj, i, NULL);
+        name = atspi_accessible_get_name(child, NULL);
+        DEBUG("%d child name:%s", i, name);
+        if (strncmp(name, "\0", 1)) {
+            strncat(ret, name, sizeof(ret) - strlen(ret) - 1);
+        }
+        strncat(ret, " ", 1);
+        below = generate_description_for_subtrees(child);
+        DEBUG("%s from below", below);
+        if (strncmp(below, "\0", 1)) {
+            strncat(ret, below, sizeof(ret) - strlen(ret) - 1);
+        }
+        g_object_unref(child);
+        free(below);
+        free(name);
+    }
+    return strdup(ret);
+}
+
+static char *
+generate_what_to_read(AtspiAccessible *obj)
+{
+    char *name;
+    char *names = NULL;
+    char *description;
+    char *role_name;
+    char *other;
+    char ret[256] = "\0";
+
+    description = atspi_accessible_get_description(obj, NULL);
+    name = atspi_accessible_get_name(obj, NULL);
+    role_name = atspi_accessible_get_role_name(obj, NULL);
+    other = generate_description_for_subtrees(obj);
+
+    DEBUG("->->->->->-> WIDGET GAINED HIGHLIGHT: %s <-<-<-<-<-<-<-", name);
+    DEBUG("->->->->->-> FROM SUBTREE HAS NAME:  %s <-<-<-<-<-<-<-", other);
+
+    display_info_about_object(obj);
+
+    if (strncmp(name, "\0", 1))
+        names = strdup(name);
+    else if (strncmp(other, "\0", 1))
+        names = strdup(other);
+
+    if (names) {
+      strncat(ret, names, sizeof(ret) - strlen(ret) - 1);
+      strncat(ret, ", ", 2);
+    }
+
+    strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1);
+    if (strncmp(description, "\0", 1))
+      strncat(ret, ", ", 2);
+    strncat(ret, description, sizeof(ret) - strlen(ret) - 1);
+
+    free(name);
+    free(description);
+    free(role_name);
+    free(other);
+
+    return strdup(ret);
+
+}
+
 static void
 _current_highlight_object_set(AtspiAccessible *obj)
 {
@@ -50,19 +262,19 @@ _current_highlight_object_set(AtspiAccessible *obj)
    GError *err = NULL;
    if (!obj)
      {
-        DEBUG("Clearing focus object");
+        DEBUG("Clearing highlight object");
         current_obj = NULL;
         return;
      }
    if (current_obj == obj)
      {
-        DEBUG("Object already focuseded");
+        DEBUG("Object already highlighted");
         DEBUG("Object name:%s", atspi_accessible_get_name(obj, NULL));
         return;
      }
     if (obj && ATSPI_IS_COMPONENT(obj))
       {
-         DEBUG("OBJ && IS COMPONENT");
+         DEBUG("OBJ WITH COMPONENT");
          AtspiComponent *comp = atspi_accessible_get_component(obj);
          if (!comp)
            {
@@ -73,7 +285,7 @@ _current_highlight_object_set(AtspiAccessible *obj)
              g_free(role);
              return;
            }
-         atspi_component_grab_focus(comp, &err);
+         atspi_component_grab_highlight(comp, &err);
          GERROR_CHECK(err)
          gchar *name;
          gchar *role;
@@ -82,32 +294,36 @@ _current_highlight_object_set(AtspiAccessible *obj)
          const ObjectCache *oc = object_cache_get(obj);
 
          if (oc) {
-             name = atspi_accessible_get_name(obj, &err);
-             GERROR_CHECK(err)
-             role = atspi_accessible_get_role_name(obj, &err);
-             GERROR_CHECK(err)
-             DEBUG("New focused object: %s, role: %s, (%d %d %d %d)",
-               name,
-               role,
-               oc->bounds->x, oc->bounds->y, oc->bounds->width, oc->bounds->height);
-             haptic_vibrate_start();
+           name = atspi_accessible_get_name(obj, &err);
+           GERROR_CHECK(err)
+           role = atspi_accessible_get_role_name(obj, &err);
+           GERROR_CHECK(err)
+           DEBUG("New highlighted object: %s, role: %s, (%d %d %d %d)",
+             name,
+             role,
+             oc->bounds->x, oc->bounds->y, oc->bounds->width, oc->bounds->height);
+           haptic_vibrate_start();
          }
          else {
            name = atspi_accessible_get_name(obj, &err);
            GERROR_CHECK(err)
            role = atspi_accessible_get_role_name(obj, &err);
            GERROR_CHECK(err)
-           DEBUG("New focused object: %s, role: %s",
-               name,
-               role
-               );
+           DEBUG("New highlighted object: %s, role: %s",
+             name,
+             role);
            haptic_vibrate_start();
-               }
+         }
+         char *text_to_speak = NULL;
+         text_to_speak = generate_what_to_read(obj);
+         DEBUG("SPEAK:%s", text_to_speak);
+         tts_speak(text_to_speak, EINA_TRUE);
          g_free(role);
          g_free(name);
+         g_free(text_to_speak);
       }
     else
-       DEBUG("Unable to focus on object");
+       DEBUG("Unable to highlight on object");
    DEBUG("END");
 }
 
@@ -495,14 +711,14 @@ static void _activate_widget(void)
     gchar *actionName;
     roleName = atspi_accessible_get_role_name(current_widget, &err);
     GERROR_CHECK(err)
-    ERROR("Widget role prev: %s\n", roleName);
+    DEBUG("Widget role prev: %s\n", roleName);
 
     if(!strcmp(roleName, "entry"))
     {
         focus_component = atspi_accessible_get_component(current_widget);
         if (focus_component != NULL)
         {
-            if (atspi_component_grab_focus(focus_component, &err) == TRUE)
+            if (atspi_component_grab_highlight(focus_component, &err) == TRUE)
               {
                 ERROR("Entry activated\n");
                 GERROR_CHECK(err)
@@ -526,28 +742,33 @@ static void _activate_widget(void)
         return;
       }
     number = atspi_action_get_n_actions(action, &err);
-    ERROR("Number of available action = %d\n", number);
+    DEBUG("Number of available action = %d\n", number);
     GERROR_CHECK(err)
-        GArray *array = atspi_accessible_get_interfaces(current_widget);
-        ERROR("TAB LEN = %d \n", array->len);
+    GArray *array = atspi_accessible_get_interfaces(current_widget);
+    DEBUG("TAB LEN = %d \n", array->len);
 
-        for (k=0; k < array->len; k++)
-            ERROR("Interface = %s\n", g_array_index( array, gchar *, k ));
+    for (k=0; k < array->len; k++)
+      ERROR("Interface = %s\n", g_array_index( array, gchar *, k ));
 
-        for (i=0; i<number; i++)
-        {
-            actionName = atspi_action_get_name(action, i, &err);
-            ERROR("Action name = %s\n", actionName);
-            GERROR_CHECK(err)
-
-            if (actionName && !strcmp("click", actionName))
-            {
-                atspi_action_do_action(action, 0, &err);
-                GERROR_CHECK(err)
-            }
-            g_free(actionName);
-        }
+    for (i=0; i<number; i++)
+      {
+        actionName = atspi_action_get_name(action, i, &err);
+        DEBUG("Action name = %s\n", actionName);
+        GERROR_CHECK(err)
 
+        if (actionName && !strcmp("activate", actionName))
+          {
+            DEBUG("PERFORMING ATSPI ACTION NO.%d and name:%s", i, actionName);
+            atspi_action_do_action(action, i, &err);
+            GERROR_CHECK(err)
+          }
+        else if (actionName) {
+            DEBUG("PERFORMING ATSPI DEFAULT ACTION");
+            atspi_action_do_action(action, 0, &err);
+            GERROR_CHECK(err)
+         }
+        g_free(actionName);
+     }
 }
 
 static void _quickpanel_change_state(gboolean quickpanel_switch)
@@ -802,7 +1023,7 @@ static void on_gesture_detected(void *data, Gesture_Info *info)
 static void
 _on_cache_builded(void *data)
 {
-   DEBUG("Cache building");
+   DEBUG("START");
    _window_cache_builded = EINA_TRUE;
    AtspiAccessible *pivot = NULL;
    if (context)
@@ -817,40 +1038,39 @@ _on_cache_builded(void *data)
      _current_highlight_object_set(pivot);
    else
      _current_highlight_object_set(flat_navi_context_current_get(context));
-   DEBUG("Cache building finished");
+   DEBUG("END");
 }
 
 static void
 _view_content_changed(AppTrackerEventType type, void *user_data)
 {
-   DEBUG("View content changed");
+   DEBUG("START");
    _window_cache_builded = EINA_FALSE;
    if (top_window)
       object_cache_build_async(top_window, 5, _on_cache_builded, NULL);
+   DEBUG("END");
 }
 
 static void on_window_activate(void *data, AtspiAccessible *window)
 {
-  gchar *name;
-      ERROR("... on window activate ...");
+   DEBUG("START");
 
-      app_tracker_callback_unregister(top_window, APP_TRACKER_EVENT_VIEW_CHANGED, _view_content_changed, NULL);
+   app_tracker_callback_unregister(top_window, APP_TRACKER_EVENT_VIEW_CHANGED, _view_content_changed, NULL);
 
-      if(window)
-      {
-         app_tracker_callback_register(window, APP_TRACKER_EVENT_VIEW_CHANGED, _view_content_changed, NULL);
-         name = atspi_accessible_get_name(window, NULL);
-         ERROR("Window name: %s", name);
-         _window_cache_builded = EINA_FALSE;
-         object_cache_build_async(window, 5, _on_cache_builded, NULL);
-         g_free(name);
-      }
-      else
-      {
-          ERROR("No top window found!");
-//          scrolled_obj = NULL;
-      }
-      top_window = window;
+   if(window)
+     {
+       DEBUG("Window name: %s", atspi_accessible_get_name(window, NULL));
+       app_tracker_callback_register(window, APP_TRACKER_EVENT_VIEW_CHANGED, _view_content_changed, NULL);
+       _window_cache_builded = EINA_FALSE;
+       object_cache_build_async(window, 5, _on_cache_builded, NULL);
+     }
+   else
+     {
+       ERROR("No top window found!");
+//     scrolled_obj = NULL;
+     }
+   top_window = window;
+   DEBUG("END");
 }
 
 void kb_tracker (void *data, Key k)
@@ -892,6 +1112,7 @@ void navigator_shutdown(void)
        AtspiComponent *comp = atspi_accessible_get_component(current_obj);
        if (comp)
          {
+           atspi_component_clear_highlight(comp, &err);
            GERROR_CHECK(err);
          }
      }
index 39a37c4..8eddd5b 100644 (file)
@@ -55,6 +55,13 @@ _object_cache_free_internal(void)
 static Eina_List*
 _cache_candidates_list_prepare(AtspiAccessible *root)
 {
+   DEBUG("START");
+   AtspiAccessible *r = atspi_accessible_get_parent(root, NULL);
+   if (r)
+      DEBUG("From application:%s [%s]", atspi_accessible_get_name(r, NULL), atspi_accessible_get_role_name(r, NULL));
+   DEBUG("Preparing candidates from root window: %s [%s]", atspi_accessible_get_name(root, NULL), atspi_accessible_get_role_name(root, NULL));
+
+
    Eina_List *toprocess = NULL, *ret = NULL;
    int n, i;
 
@@ -68,8 +75,11 @@ _cache_candidates_list_prepare(AtspiAccessible *root)
      {
         AtspiAccessible *obj = eina_list_data_get(toprocess);
         toprocess = eina_list_remove_list(toprocess, toprocess);
-        if (!obj)
-          continue;
+        if (!obj) 
+          {
+            DEBUG("NO OBJ");
+            continue;
+          }
         n = atspi_accessible_get_child_count(obj, NULL);
         for (i = 0; i < n; i++)
           {
@@ -79,6 +89,7 @@ _cache_candidates_list_prepare(AtspiAccessible *root)
           }
         ret = eina_list_append(ret, obj);
      }
+   DEBUG("END");
 
    return ret;
 }
@@ -90,7 +101,10 @@ _cache_item_construct(AtspiAccessible *obj)
    AtspiComponent *comp;
 
    if (!obj)
-     return NULL;
+     {
+        ERROR("object is NULL");
+        return NULL;
+     }
 
    ret = calloc(1, sizeof(ObjectCache));
    if (!ret)
@@ -143,6 +157,7 @@ _object_cache_new(void)
 void
 object_cache_build(AtspiAccessible *root)
 {
+   DEBUG("START");
    Eina_List *objs;
 
    _object_cache_free_internal();
@@ -175,6 +190,7 @@ _do_cache(void *data)
 void
 object_cache_build_async(AtspiAccessible *root, int bulk_size, ObjectCacheReadyCb cb, void *ud)
 {
+   DEBUG("START");
    _object_cache_free_internal();
 
    callback = cb;
@@ -188,9 +204,12 @@ object_cache_build_async(AtspiAccessible *root, int bulk_size, ObjectCacheReadyC
         return;
      }
 
+   DEBUG("will be preparing async candidates from:[%s] with role:[%s]\n",
+            atspi_accessible_get_name(root, NULL),
+            atspi_accessible_get_role_name(root, NULL));
    toprocess = _cache_candidates_list_prepare(root);
    idler = ecore_idler_add(_do_cache, NULL);
-
+   DEBUG("END");
    return;
 }
 
@@ -223,10 +242,10 @@ object_cache_get(AtspiAccessible *obj)
    ret = eina_hash_find(cache, &obj);
    if (!ret)
      {
+        DEBUG("EMPTY");
         // fallback to blocking d-bus call
         ret = _cache_item_construct(obj);
         eina_hash_add(cache, &obj, ret);
      }
-
    return ret;
 }
old mode 100755 (executable)
new mode 100644 (file)
index 0b7279b..28e67ab
@@ -18,7 +18,7 @@ Service_Data service_data = {
                .language = "en_US",
                .voice_type = TTS_VOICE_TYPE_FEMALE,
                .reading_speed = 2,
-               .tracking_signal_name = FOCUS_CHANGED_SIG,
+               .tracking_signal_name = HIGHLIGHT_CHANGED_SIG,
 
 
                //Set by tts
@@ -38,12 +38,14 @@ Service_Data *get_pointer_to_service_data_struct()
 
 int screen_reader_create_service(void *data)
 {
-       printf("\n\n\nService Create:%s\n\n\n", __func__);
-
+       int vconf_ret = vconf_set_bool("db/setting/accessibility/atspi", EINA_TRUE);
+       if(vconf_ret != 0)
+       {
+               ERROR("Gesture fail layer set to false with error:%d", vconf_ret);
+       }
        Service_Data *service_data = data;
 
        vconf_init(service_data);
-       spi_init(service_data);
        tts_init(service_data);
 
 
@@ -54,6 +56,7 @@ int screen_reader_create_service(void *data)
                test_suite_init();
        #endif
 
+
        return 0;
 }
 
@@ -73,15 +76,14 @@ int screen_reader_terminate_service(void *data)
                DEBUG("COULD NOT SET tts key to 0");
        }
 
-       
-       vconf_ret = vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, EINA_FALSE);
+       vconf_ret = vconf_set_bool("db/setting/accessibility/atspi", EINA_FALSE);
        if(vconf_ret == 0)
        {
-               DEBUG("TTS key set to false");
+               DEBUG("Gesture layer set to false");
        }
        else
        {
-               DEBUG("COULD NOT SET tts key to 0");
+               DEBUG("Gesture fail layer set to false");
        }
 
        tts_stop(service_data->tts);
index 0aaa941..b62d0cb 100644 (file)
@@ -114,7 +114,7 @@ static char *spi_on_state_changed_get_text(AtspiEvent *event, void *user_data)
     role_name = atspi_accessible_get_role_name(sd->currently_focused, NULL);
     other = generate_description_for_subtree(sd->currently_focused);
 
-    DEBUG("->->->->->-> WIDGET GAINED FOCUS: %s <-<-<-<-<-<-<-", name);
+    DEBUG("->->->->->-> WIDGET GAINED HIGHLIGHT: %s <-<-<-<-<-<-<-", name);
     DEBUG("->->->->->-> FROM SUBTREE HAS NAME:  %s <-<-<-<-<-<-<-", other);
 
     if (strncmp(name, "\0", 1))
@@ -308,7 +308,6 @@ void spi_init(Service_Data *sd)
         ERROR("Invalid parameter");
         return;
     }
-
     DEBUG( "--------------------- SPI_init START ---------------------");
     service_data = sd;
 
index 7f146a1..0b901f4 100644 (file)
@@ -114,7 +114,6 @@ static void __tts_test_utt_completed_cb(tts_h tts, int utt_id, void* user_data)
 
 bool tts_init(void *data)
 {
-    printf( "--------------------- TTS_init START ---------------------");
     DEBUG( "--------------------- TTS_init START ---------------------");
     Service_Data *sd = data;
 
index 9132d56..957d2f4 100644 (file)
@@ -57,52 +57,6 @@ bool set_langauge(Service_Data *sd, const char *new_language, int new_voice)
        return false;
 }
 
-char *fold_tracker_signal(const char *signal_name)
-{
-       if(strcmp(signal_name, FOCUS_SIG) == 0)
-       {
-               return FOCUS_CHANGED_SIG;
-       }
-       return NULL;
-}
-
-bool set_tracking_listener(Service_Data *sd, const char *signal_name)
-{
-       DEBUG("START");
-
-       char *new_tracking_signal;
-
-       new_tracking_signal = fold_tracker_signal(signal_name);
-
-       if(strcmp(sd->tracking_signal_name, new_tracking_signal) == 0)
-       {
-               DEBUG("No need to change accessibility tracking signal: %s == %s",
-                               sd->tracking_signal_name, new_tracking_signal);
-
-               return true;
-       }
-
-       gboolean ret = atspi_event_listener_deregister(sd->spi_listener, sd->tracking_signal_name, NULL);
-       if(ret == false)
-       {
-               DEBUG("Tracking signal listerner deregister successful");
-       }
-
-       sd->tracking_signal_name = strdup(new_tracking_signal);
-
-       gboolean ret1 = atspi_event_listener_register(sd->spi_listener, sd->tracking_signal_name, NULL);
-       if(ret1 == false)
-       {
-               DEBUG("FAILED TO REGISTER spi focus/highlight listener");
-               return false;
-       }
-       else
-       {
-               DEBUG("Tracking listener register for new signal");
-       }
-       return true;
-}
-
 // ------------------------------ vconf callbacks----------------------
 
 void information_level_cb(keynode_t *node, void *user_data)
@@ -171,16 +125,6 @@ void reading_speed_cb(keynode_t *node, void *user_data)
        DEBUG("END");
 }
 
-void tracking_signal_changed_cb(keynode_t *node, void *user_data)
-{
-       DEBUG("START");
-       DEBUG("Tracking signal set to: %s", node->value.s);
-
-       Service_Data *sd = user_data;
-       const char *tracking_signal = vconf_get_str("db/setting/accessibility/tracking_signal");
-       set_tracking_listener(sd, tracking_signal);
-}
-
 // --------------------------------------------------------------------
 
 int get_key_values(Service_Data *sd)
@@ -232,20 +176,8 @@ int get_key_values(Service_Data *sd)
 bool vconf_init(Service_Data *service_data)
 {
        DEBUG( "--------------------- VCONF_init START ---------------------");
-       printf( "--------------------- VCONF_init START ---------------------");
        int ret = 0;
 
-       //TODO: Remove when adequate keys in the settings(control?) panel are added
-       // -----------------------  TEST ONLY -----------------------------------------------
-       DEBUG("TESTS START");
-       keys = vconf_keylist_new();
-       vconf_keylist_add_int(keys, "db/setting/accessibility/information_level", 2);
-       vconf_keylist_add_str(keys, "db/setting/accessibility/language", "en_US");
-       vconf_keylist_add_int(keys, "db/setting/accessibility/voice", 1);
-       vconf_keylist_add_str(keys, "db/setting/accessibility/tracking_signal",  FOCUS_CHANGED_SIG);
-    //-----------------------------------------------------------------------------------
-       //vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, EINA_TRUE);
-
        if(vconf_set(keys))
        {
                DEBUG("nothing is written\n");
@@ -306,13 +238,6 @@ bool vconf_init(Service_Data *service_data)
                return false;
        }
 
-       ret = vconf_notify_key_changed("db/setting/accessibility/tracking_signal", tracking_signal_changed_cb, service_data);
-       if(ret != 0)
-       {
-               DEBUG("Could not add reading speed callback callback");
-               return false;
-       }
-
        DEBUG("ALL CALBACKS ADDED");
 
        DEBUG( "---------------------- VCONF_init END ----------------------\n\n");
index 313bbb8..a9a2f15 100644 (file)
@@ -7,44 +7,72 @@ static void *user_data;
 static AtspiEventListener *listener;
 static AtspiAccessible *last_active_win;
 
+static AtspiAccessible*
+_get_window_object_from_given(AtspiAccessible *obj)
+{
+   if (!obj)
+      return NULL;
+
+   if (atspi_accessible_get_role(obj, NULL) != ATSPI_ROLE_DESKTOP_FRAME)
+      return NULL;
+
+   AtspiAccessible *win = NULL;
+   AtspiAccessible *app = NULL;
+   AtspiAccessible *ret = NULL;
+   AtspiStateSet *st = NULL;
+   int desktop_childs;
+   int app_childs;
+   int i,j;
+
+   desktop_childs = atspi_accessible_get_child_count(obj, NULL);
+
+   for (i=0; i < desktop_childs; i++) {
+      app = atspi_accessible_get_child_at_index(obj, i, NULL);
+      if (atspi_accessible_get_role(app, NULL) == ATSPI_ROLE_APPLICATION) {
+         app_childs = atspi_accessible_get_child_count(app, NULL);
+         for (j=0; j < app_childs; j++) {
+            win = atspi_accessible_get_child_at_index(app, j, NULL);
+            st = atspi_accessible_get_state_set (win);
+            if (atspi_state_set_contains(st, ATSPI_STATE_ACTIVE))
+               ret = win;
+         }
+      }
+   }
+
+   return ret;
+}
+
 static void
 _on_atspi_window_cb(const AtspiEvent *event)
 {
-   DEBUG("START");
-   DEBUG("%s", event->type);
-   if (!strcmp(event->type, "window:activate") ||
-       !strcmp(event->type, "window:restore") ||
-       !strcmp(event->type, "window:create"))
-     {
-        if (last_active_win != event->source)
-            {
-              if (user_cb) user_cb(user_data, event->source);
-              last_active_win = event->source;
-            }
-     }
-   else if (!strcmp(event->type, "window:deactivate") ||
-            !strcmp(event->type, "window:destroy"))
+   if (!strcmp(event->type, "window:restore") ||
+       !strcmp(event->type, "window:activate"))
      {
-        if ((last_active_win == event->source) &&
-            user_cb)
-          user_cb(user_data, NULL);
-        last_active_win = NULL;
+       if (user_cb) user_cb(user_data, event->source);
+         last_active_win = event->source;
      }
+   else {
+      AtspiAccessible *obj = NULL;
+      obj = _get_window_object_from_given(event->source);
+
+      if (obj) {
+        if (!strcmp(event->type, "object:children-changed:add")) {
+            if (user_cb) user_cb(user_data, obj);
+               last_active_win = obj;
+        }
+      }
+   }
 }
 
 static AtspiAccessible*
 _get_active_win(void)
 {
+   DEBUG("START");
    int i, j;
    last_active_win = NULL;
    AtspiAccessible *desktop = atspi_get_desktop(0);
-   DEBUG("START");
-   if (desktop) {
-       DEBUG("DESKTOP FOUND");
-   }
-   else {
+   if (!desktop)
        ERROR("DESKTOP NOT FOUND");
-   }
 
    for (i = 0; i < atspi_accessible_get_child_count(desktop, NULL); i++) {
        AtspiAccessible *app = atspi_accessible_get_child_at_index(desktop, i, NULL);
@@ -62,6 +90,7 @@ _get_active_win(void)
           g_object_unref(states);
        }
    }
+   DEBUG("END");
    return last_active_win;
 }
 
@@ -69,20 +98,19 @@ void window_tracker_init(void)
 {
    DEBUG("START");
    listener = atspi_event_listener_new_simple(_on_atspi_window_cb, NULL);
-   atspi_event_listener_register(listener, "window:activate", NULL);
-   atspi_event_listener_register(listener, "window:create", NULL);
+   atspi_event_listener_register(listener, "object:children-changed", NULL);
    atspi_event_listener_register(listener, "window:deactivate", NULL);
+   atspi_event_listener_register(listener, "window:activate", NULL);
    atspi_event_listener_register(listener, "window:restore", NULL);
-   atspi_event_listener_register(listener, "window:destroy", NULL);
 }
 
 void window_tracker_shutdown(void)
 {
-   atspi_event_listener_deregister(listener, "window:activate", NULL);
-   atspi_event_listener_deregister(listener, "window:create", NULL);
+   DEBUG("START");
+   atspi_event_listener_deregister(listener, "object:children-changed", NULL);
    atspi_event_listener_deregister(listener, "window:deactivate", NULL);
+   atspi_event_listener_deregister(listener, "window:activate", NULL);
    atspi_event_listener_deregister(listener, "window:restore", NULL);
-   atspi_event_listener_deregister(listener, "window:destroy", NULL);
    g_object_unref(listener);
    listener = NULL;
    user_cb = NULL;
@@ -92,6 +120,7 @@ void window_tracker_shutdown(void)
 
 void window_tracker_register(Window_Tracker_Cb cb, void *data)
 {
+   DEBUG("START");
    user_cb = cb;
    user_data = data;
 }
index 80bd00c..4b0a163 100644 (file)
@@ -301,6 +301,7 @@ AtspiAccessible *atspi_create_accessible()
     AtspiStateType s[] = {
          ATSPI_STATE_VISIBLE,
          ATSPI_STATE_SHOWING,
+         ATSPI_STATE_FOCUSABLE,
          ATSPI_STATE_LAST_DEFINED
     };
     int i;
@@ -400,6 +401,11 @@ AtspiAccessible * atspi_relation_get_target (AtspiRelation *obj, gint i)
     return NULL;
 }
 
+AtspiAccessible * atspi_accessible_get_parent (AtspiAccessible *obj, GError **error)
+{
+    return obj->accessible_parent;
+}
+
 int atspi_exit(void)
 {
    return 1;
index 089f68f..0853084 100644 (file)
@@ -395,6 +395,7 @@ GArray * atspi_accessible_get_relation_set (AtspiAccessible *obj, GError **error
 AtspiRelationType atspi_relation_get_relation_type (AtspiRelation *obj);
 gint atspi_relation_get_n_targets (AtspiRelation *obj);
 AtspiAccessible * atspi_relation_get_target (AtspiRelation *obj, gint i);
+AtspiAccessible * atspi_accessible_get_parent (AtspiAccessible *obj, GError **error);
 int atspi_exit(void);
 
 #endif /*__ATSPI_H__*/
index 62feddc..d3f8f8d 100644 (file)
@@ -20,7 +20,7 @@ void setup(void)
     data->run_service = 1;
     data->voice_type = TTS_VOICE_TYPE_FEMALE;
     data->reading_speed = 2;
-    data->tracking_signal_name = FOCUS_CHANGED_SIG;
+    data->tracking_signal_name = HIGHLIGHT_CHANGED_SIG;
 
     //Set by tts
     data->tts = NULL;
@@ -366,6 +366,29 @@ Suite *screen_reader_suite(void)
     tcase_add_test(tc_spi_screen_reader_on_caret_move, spi_on_caret_move);
     tcase_add_test(tc_spi_screen_reader_on_access_value, spi_on_value_changed);
 
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_create_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_create_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_get_current_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_get_current_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_next_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_next_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_prev_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_prev_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_last_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_last_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_first_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_first_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_current_set_null_parameters);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_current_set_valid_parameters);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_prev_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_prev_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_next_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_next_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_first_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_first_valid_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_last_null_parameter);
+   tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_line_last_valid_parameter);
+
     suite_add_tcase(s, tc_spi_screen_reader_init);
     suite_add_tcase(s, tc_spi_screen_reader_on_state_changed);
     suite_add_tcase(s, tc_spi_screen_reader_on_caret_move);