atspi: add "GetReadingMaterial" interface method 59/131359/6
authorShinwoo Kim <cinoo.kim@samsung.com>
Fri, 26 May 2017 13:05:11 +0000 (22:05 +0900)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Wed, 28 Jun 2017 23:27:09 +0000 (23:27 +0000)
The atspi_accessible_get_reading_material of at-spi2-core calls this method to
get reading material to be used screen-reader side. This is for reducing IPC.
It seems that the number of IPC is changed from 30 to 1.

Related patch set:
https://review.tizen.org/gerrit/#/c/131358/ (at-spi2-core)
https://review.tizen.org/gerrit/#/c/131359/ (this one, elementary)
https://review.tizen.org/gerrit/#/c/131511/ (at-spi2-atk)
https://review.tizen.org/gerrit/#/c/131714/ (screen-reader)

@tizen_only

Change-Id: Ib17d34fd8af7b5856908692c617938116d02305e

src/lib/elm_atspi_bridge.c

index 9923a0e8428bf4a0dc3462f5deecc0afc3ca814c..5192ae4ee423243c77e1f6a540c24bdc001639f3 100644 (file)
@@ -1027,6 +1027,311 @@ _accessible_get_navigable_at_point(const Eldbus_Service_Interface *iface EINA_UN
 }
 //
 
+//TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method
+static int
+_list_children_count_check(Eo *obj)
+{
+   int i;
+   int list_count = 0;
+   Eina_List *children;
+   Eo *child = NULL;
+   Elm_Atspi_Role role;
+
+   if (!obj)
+     return 0;
+
+   eo_do(obj, role = elm_interface_atspi_accessible_role_get());
+   if (role == ELM_ATSPI_ROLE_LIST)
+     {
+        int children_count = 0;
+        eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+        children_count = eina_list_count(children);
+
+        for (i = 0; i < children_count; i++)
+          {
+             child = eina_list_nth(children, i);
+             eo_do(child, role = elm_interface_atspi_accessible_role_get());
+             if (role == ELM_ATSPI_ROLE_LIST_ITEM)
+               list_count++;
+          }
+        eina_list_free(children);
+     }
+
+   return list_count;
+}
+
+static int
+_list_children_count(Eo *obj)
+{
+   Eina_List *children;
+   int list_items_count = 0;
+   int children_count = 0;
+
+   eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+   children_count = eina_list_count(children);
+
+   int i;
+   Eo *child = NULL;
+
+   list_items_count = _list_children_count_check(obj);
+   if (list_items_count > 0)
+     {
+        eina_list_free(children);
+        return list_items_count;
+     }
+
+   for (i = 0; i < children_count; i++)
+     {
+        child = eina_list_nth(children, i);
+        list_items_count = _list_children_count(child);
+        if (list_items_count > 0)
+          {
+             eina_list_free(children);
+             return list_items_count;
+          }
+     }
+
+   return 0;
+}
+
+static Eldbus_Message *
+_accessible_reading_material_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
+{
+   Eldbus_Message *ret;
+   Eldbus_Message_Iter *iter, *iter_array, *iter_dict, *iter_entry;
+   Eina_List *attrs, *l, *children;
+   const char *name = NULL;
+   unsigned int s1, s2;
+   double value = 0;
+   double increment = 0;
+   double max_value = 0;
+   double min_value = 0;
+   int idx = 0;
+   int child_count = 0;
+   int selected_child_count = 0;
+   uint64_t atspi_states = 0;
+   Elm_Atspi_Role role;
+   Elm_Atspi_Attribute *attr;
+   Elm_Atspi_State_Set states;
+   Elm_Atspi_Relation_Set rels = NULL;
+   Elm_Atspi_Relation *rel;
+   Eo *relation_obj = NULL;
+   Eo *parent = NULL;
+   Eo *child = NULL;
+   Eina_Bool is_selected = EINA_FALSE;
+   AtspiRole atspi_role = ATSPI_ROLE_INVALID;
+
+   const char *obj_path = eldbus_message_path_get(msg);
+   Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
+   Eo *obj = _bridge_object_from_path(bridge, obj_path);
+
+   ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN, msg);
+
+   ret = eldbus_message_method_return_new(msg);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
+
+   iter = eldbus_message_iter_get(ret);
+   /* attributes */
+   eo_do(obj, attrs = elm_interface_atspi_accessible_attributes_get());
+   iter_dict = eldbus_message_iter_container_new(iter, 'a', "{ss}");
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iter_dict, NULL);
+   EINA_LIST_FOREACH(attrs, l, attr)
+     {
+        iter_entry = eldbus_message_iter_container_new(iter_dict, 'e', NULL);
+        EINA_SAFETY_ON_NULL_RETURN_VAL(iter_entry, NULL);
+        eldbus_message_iter_arguments_append(iter_entry, "ss", attr->key, attr->value);
+        eldbus_message_iter_container_close(iter_dict, iter_entry);
+     }
+
+   eldbus_message_iter_container_close(iter, iter_dict);
+   elm_atspi_attributes_list_free(attrs);
+
+   /* name */
+   eo_do(obj, name = elm_interface_atspi_accessible_name_get());
+   if (!name)
+     name = "";
+   eldbus_message_iter_basic_append(iter, 's', name);
+
+   /* name - LABELED_BY relation */
+   eo_do(obj, rels = elm_interface_atspi_accessible_relation_set_get());
+   EINA_LIST_FOREACH(rels, l, rel)
+     {
+        if (rel->type == ELM_ATSPI_RELATION_LABELLED_BY)
+          {
+             int last_index = eina_list_count(rel->objects) - 1;
+             relation_obj = eina_list_nth(rel->objects, last_index);
+             break;
+          }
+     }
+   eo_do(relation_obj, name = elm_interface_atspi_accessible_name_get());
+   if (!name)
+     name = "";
+   eldbus_message_iter_basic_append(iter, 's', name);
+
+   /* name - text interface */
+   name = NULL;
+   if (eo_isa(obj, ELM_INTERFACE_ATSPI_TEXT_INTERFACE))
+     {
+        int val;
+        eo_do(obj, val = elm_interface_atspi_text_character_count_get());
+        eo_do(obj, name = elm_interface_atspi_text_get(0, val));
+     }
+   if (!name)
+     name = "";
+   eldbus_message_iter_basic_append(iter, 's', name);
+
+   /* role */
+   eo_do(obj, role = elm_interface_atspi_accessible_role_get());
+   atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
+   eldbus_message_iter_basic_append(iter, 'u', atspi_role);
+
+   /* states */
+   iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
+   EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
+   eo_do(obj, states = elm_interface_atspi_accessible_state_set_get());
+   atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
+   s1 = atspi_states & 0xFFFFFFFF;
+   s2 = (atspi_states >> 32) & 0xFFFFFFFF;
+   eldbus_message_iter_basic_append(iter_array, 'u', s1);
+   eldbus_message_iter_basic_append(iter_array, 'u', s2);
+   eldbus_message_iter_container_close(iter, iter_array);
+
+   /* localized role name */
+   eo_do(obj, name = elm_interface_atspi_accessible_localized_role_name_get());
+   if (!name)
+     name = "";
+   eldbus_message_iter_basic_append(iter, 's', name);
+
+   /* child count */
+   eo_do(obj, l = elm_interface_atspi_accessible_children_get());
+   eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
+   eina_list_free(l);
+
+   /* current value, increment, max, min */
+   value = 0;
+   increment = 0;
+   max_value = 0;
+   min_value = 0;
+   if (eo_isa(obj, ELM_INTERFACE_ATSPI_VALUE_INTERFACE))
+     {
+        eo_do(obj, elm_interface_atspi_value_and_text_get(&value, NULL));
+        eo_do(obj, increment = elm_interface_atspi_value_increment_get());
+        eo_do(obj, elm_interface_atspi_value_range_get(&min_value, &max_value, NULL));
+     }
+   eldbus_message_iter_basic_append(iter, 'd', value);
+   eldbus_message_iter_basic_append(iter, 'd', increment);
+   eldbus_message_iter_basic_append(iter, 'd', max_value);
+   eldbus_message_iter_basic_append(iter, 'd', min_value);
+
+   /* description */
+   eo_do(obj, name = elm_interface_atspi_accessible_description_get());
+   if (!name)
+     name = "";
+   eldbus_message_iter_basic_append(iter, 's', name);
+
+   /* index in parent */
+   eo_do(obj, idx = elm_interface_atspi_accessible_index_in_parent_get());
+   eldbus_message_iter_basic_append(iter, 'i', idx);
+
+   /* is selected in parent */
+   eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
+   eo_do(parent, is_selected = elm_interface_atspi_selection_is_child_selected(idx));
+   eldbus_message_arguments_append(ret, "b", is_selected);
+
+   /* has checkbox child */
+   is_selected = EINA_FALSE;
+   eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+   EINA_LIST_FOREACH(children, l, child)
+     {
+        if (eo_isa(child, ELM_CHECK_CLASS))
+          {
+             is_selected = EINA_TRUE;
+             break;
+          }
+     }
+   eldbus_message_iter_basic_append(iter, 'b', is_selected);
+   eina_list_free(children);
+
+   /* list children count */
+   child_count = 0;
+   if (role == ELM_ATSPI_ROLE_DIALOG)
+     {
+        child_count = _list_children_count(obj);
+     }
+   eldbus_message_iter_basic_append(iter, 'i', child_count);
+
+   /* first selected child index */
+   idx = 0;
+   if (eo_isa(obj, ELM_INDEX_CLASS))
+     {
+        eo_do(obj, children = elm_interface_atspi_accessible_children_get());
+        EINA_LIST_FOREACH(children, l, child)
+          {
+             eo_do(child, states = elm_interface_atspi_accessible_state_set_get());
+             if (STATE_TYPE_GET(states, ELM_ATSPI_STATE_SELECTED))
+               break;
+             idx++;
+          }
+        eina_list_free(children);
+     }
+   eldbus_message_iter_basic_append(iter, 'i', idx);
+
+   /* parent */
+   role = ELM_ATSPI_ROLE_INVALID;
+   eo_do(obj, role = elm_interface_atspi_accessible_role_get());
+   if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
+     _object_desktop_reference_append(iter);
+   else
+     _bridge_iter_object_reference_append(bridge, iter, parent);
+
+   /* parent - states */
+   iter_array = eldbus_message_iter_container_new(iter, 'a', "u");
+   EINA_SAFETY_ON_NULL_GOTO(iter_array, fail);
+   eo_do(parent, states = elm_interface_atspi_accessible_state_set_get());
+   atspi_states = _elm_atspi_state_set_to_atspi_state_set(states);
+   s1 = atspi_states & 0xFFFFFFFF;
+   s2 = (atspi_states >> 32) & 0xFFFFFFFF;
+   eldbus_message_iter_basic_append(iter_array, 'u', s1);
+   eldbus_message_iter_basic_append(iter_array, 'u', s2);
+   eldbus_message_iter_container_close(iter, iter_array);
+
+   /* parent - child count */
+   eo_do(parent, l = elm_interface_atspi_accessible_children_get());
+   eldbus_message_iter_basic_append(iter, 'i', eina_list_count(l));
+   eina_list_free(l);
+
+   /* parent - role */
+   eo_do(parent, role = elm_interface_atspi_accessible_role_get());
+   atspi_role = role > ELM_ATSPI_ROLE_LAST_DEFINED ? ATSPI_ROLE_LAST_DEFINED : elm_roles_to_atspi_roles[role][1];
+   eldbus_message_iter_basic_append(iter, 'u', atspi_role);
+
+   /* parent - child count */
+   eo_do(parent, selected_child_count = elm_interface_atspi_selection_selected_children_count_get());
+   eldbus_message_iter_basic_append(iter, 'i', selected_child_count);
+
+   /* relation object - DESCRIBED_BY */
+   relation_obj = NULL;
+   EINA_LIST_FOREACH(rels, l, rel)
+     {
+        if (rel->type == ELM_ATSPI_RELATION_DESCRIBED_BY)
+          {
+             int last_index = eina_list_count(rel->objects) - 1;
+             relation_obj = eina_list_nth(rel->objects, last_index);
+             break;
+          }
+     }
+   _bridge_iter_object_reference_append(bridge, iter, relation_obj);
+   elm_atspi_relation_set_free(&rels);
+
+   return ret;
+
+fail:
+   if (rels) elm_atspi_relation_set_free(&rels);
+   if (ret) eldbus_message_unref(ret);
+   return NULL;
+}
+//
+
 static const Eldbus_Method accessible_methods[] = {
 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
    { "GetNavigableAtPoint", ELDBUS_ARGS({"i", "x"}, {"i", "y"}, {"u", "coord_type"}), ELDBUS_ARGS({"(so)y", "accessible"}), _accessible_get_navigable_at_point, 0 },
@@ -1048,7 +1353,26 @@ static const Eldbus_Method accessible_methods[] = {
      ELDBUS_ARGS({"i", "type"}, {"i", "x_beg"}, {"i", "y_beg"},
                  {"i", "x_end"}, {"i", "y_end"}, {"i", "state"},
                  {"u", "event_time"}),
-     ELDBUS_ARGS({"b", "result"}), _accessible_gesture_do, 0 },
+     ELDBUS_ARGS({"b", "result"}), _accessible_gesture_do, 0},
+   //
+   //TIZEN_ONLY(20170531): add "GetReadingMaterial" interface method
+   { "GetReadingMaterial",
+     NULL,
+     ELDBUS_ARGS({"a{ss}", "attributes"}, {"s", "name"},
+                 {"s", "labledByName"},{"s", "textIfceName"},
+                 {"u", "role"}, {"au", "stateSet"},
+                 {"s", "localizedName"}, {"i", "childCount"},
+                 {"d", "currentValue"},{"d", "minimumIncrement"},
+                 {"d", "maximumValue"},{"d", "minimumValue"},
+                 {"s", "description"}, {"i", "indexInParent"},
+                 {"b", "isSelectedInParent"}, {"b", "hasCheckboxChild"},
+                 {"i", "listChildrenCount"},
+                 {"i", "firstSelectedChildIndex"},
+                 {"(so)", "parent"}, {"au", "parentStateSet"},
+                 {"i", "parentChildCount"}, {"u", "parentRole"},
+                 {"i", "selectedChildCount"},
+                 {"(so)", "describecByObject"}),
+     _accessible_reading_material_get, 0},
    //
    { NULL, NULL, NULL, NULL, 0 }
 };