Add "GetReadingMaterial" interface method 40/136240/1
authorShinwoo Kim <cinoo.kim@samsung.com>
Mon, 29 May 2017 11:43:25 +0000 (20:43 +0900)
committerShinwoo Kim <cinoo.kim@samsung.com>
Thu, 29 Jun 2017 00:04:16 +0000 (09:04 +0900)
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/ (elementary)
https://review.tizen.org/gerrit/#/c/131511/ (this one, at-spi2-atk)
https://review.tizen.org/gerrit/#/c/131714/ (screen-reader)

Change-Id: I6e5b64c5e7d6a3c448f9b108dc5b36bc824621c7

atk-adaptor/adaptors/accessible-adaptor.c
atk-adaptor/introspection.c

index b0a7d8b..ce719ce 100644 (file)
@@ -667,6 +667,311 @@ impl_GetNavigableAtPoint (DBusConnection * bus, DBusMessage * message,
 
   return reply;
 }
+
+static int
+_list_children_count_check(AtkObject * object)
+{
+   gint role;
+   gint i;
+   gint list_count = 0;
+
+   if (!object)
+     return 0;
+
+  role = atk_object_get_role (object);
+  if (role == ATK_ROLE_LIST)
+    {
+      gint children_count = 0;
+      children_count = atk_object_get_n_accessible_children (object);
+      for (i = 0; i < children_count; i++)
+        {
+          AtkObject *child = atk_object_ref_accessible_child (object, i);
+          role = atk_object_get_role (child);
+          if (role == ATK_ROLE_LIST_ITEM)
+            list_count++;
+          if (child)
+            g_object_unref (child);
+        }
+    }
+
+   return list_count;
+}
+
+static gint
+_list_children_count (AtkObject * object)
+{
+  gint list_items_count = 0;
+  gint count = 0;
+  gint i;
+
+  list_items_count = _list_children_count_check(object);
+  if (list_items_count > 0)
+    {
+       return list_items_count;
+    }
+
+  count = atk_object_get_n_accessible_children (object);
+  for (i = 0; i < count; i++)
+    {
+      AtkObject *child = atk_object_ref_accessible_child (object, i);
+      list_items_count = _list_children_count(child);
+      if (child)
+        g_object_unref (child);
+      if (list_items_count > 0)
+        {
+           return list_items_count;
+        }
+    }
+
+  return 0;
+}
+
+static DBusMessage *
+impl_GetReadingMaterial (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+  AtkObject *object = (AtkObject *) user_data;
+  AtkObject *parent;
+  AtkAttributeSet *attributes;
+  const char *name;
+  AtkRelationSet *set;
+  gint count, i;
+  AtkObject *rel_object = NULL;
+  unsigned int size = 0;
+  gint role;
+  dbus_uint32_t rv_role;
+  dbus_int32_t rv_index;
+  dbus_uint32_t states[2];
+  dbus_bool_t rv_is_selected = 0;
+  DBusMessage *reply = NULL;
+  DBusMessageIter iter;
+  DBusMessageIter iter_variant;
+
+  g_return_val_if_fail (ATK_IS_OBJECT (user_data),
+                        droute_not_yet_handled_error (message));
+
+  reply = dbus_message_new_method_return (message);
+  dbus_message_iter_init_append (reply, &iter);
+
+  /* attributes */
+  attributes = atk_object_get_attributes (object);
+  spi_object_append_attribute_set (&iter, attributes);
+  atk_attribute_set_free (attributes);
+
+  /* name */
+  name = atk_object_get_name (object);
+  if (!name)
+    name = "";
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
+
+  /* name - LABELED_BY relation */
+  name = NULL;
+  set = atk_object_ref_relation_set (object);
+  count = atk_relation_set_get_n_relations (set);
+  for (i = 0; i < count; i++)
+  {
+    AtkRelation *r = atk_relation_set_get_relation (set, i);
+    if (!r)
+      continue;
+    AtkRelationType rt = atk_relation_get_relation_type (r);
+    if (rt == ATK_RELATION_LABELLED_BY)
+    {
+      GPtrArray *target = atk_relation_get_target (r);
+      if (target && target->len > 0)
+      {
+        rel_object = target->pdata[target->len - 1];
+        name = atk_object_get_name (rel_object);
+        break;
+      }
+    }
+  }
+  if (!name)
+    name = "";
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
+
+  /* name - text interface */
+  AtkText *text = (AtkText *) object;
+  size = atk_text_get_character_count (text);
+  name = atk_text_get_text (text, 0, size);
+  if (!name)
+    name = "";
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
+
+  /* role */
+  role = atk_object_get_role (object);
+  rv_role = spi_accessible_role_from_atk_role (role);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &rv_role);
+
+  /* states */
+  spi_atk_state_to_dbus_array (object, states);
+  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_variant);
+  for (count = 0; count < 2; count++)
+    {
+      dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_UINT32,
+                                      &states[count]);
+    }
+  dbus_message_iter_close_container (&iter, &iter_variant);
+
+  /* localized role name */
+  name = atk_role_get_localized_name (role);
+  if (!name)
+    name = "";
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
+
+  /* child count */
+  count = atk_object_get_n_accessible_children (object);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count);
+
+  /* current value, increment, max, min */
+  AtkValue *value = (AtkValue *) object;
+  gdouble current_value = 0;
+  gdouble increment = 0;
+  gdouble min_value = 0;
+  gdouble max_value = 0;
+  if (ATK_IS_VALUE(value))
+  {
+    gchar *desc = NULL;
+    atk_value_get_value_and_text (value, &current_value, &desc);
+
+    increment = atk_value_get_increment (value);
+
+    AtkRange *range = atk_value_get_range(value);
+    if (range)
+      {
+        min_value = atk_range_get_lower_limit (range);
+        max_value = atk_range_get_upper_limit (range);
+        atk_range_free (range);
+      }
+  }
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &current_value);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &increment);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &max_value);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &min_value);
+
+  /* description */
+  name = atk_object_get_description (object);
+  if (!name)
+    name = "";
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
+
+  /* index in parent */
+  rv_index = atk_object_get_index_in_parent (object);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &rv_index);
+
+  /* is selected in parent */
+  parent = atk_object_get_parent (object);
+  if (parent)
+    {
+      AtkSelection *selection = (AtkSelection *) parent;
+      if (ATK_IS_SELECTION(selection))
+        {
+          rv_is_selected = atk_selection_is_child_selected (selection, rv_index);
+        }
+    }
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &rv_is_selected);
+
+  /* has checkbox child */
+  rv_is_selected = 0;
+  count = atk_object_get_n_accessible_children (object);
+  for (i = 0; i < count; i++)
+    {
+      AtkObject *child = atk_object_ref_accessible_child (object, i);
+      gint _role = atk_object_get_role (child);
+      if (child)
+        g_object_unref (child);
+      if (_role == ATK_ROLE_CHECK_BOX)
+        {
+          rv_is_selected = 1;
+          break;
+        }
+    }
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &rv_is_selected);
+
+  /* list children count */
+  count = 0;
+  if (role == ATK_ROLE_DIALOG)
+    {
+      count = _list_children_count(object);
+    }
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count);
+
+  /* first selected child index */
+  /* it is too UX dependent, this is not necessary */
+  rv_index = 0;
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &rv_index);
+
+  /* parent */
+  if (!parent)
+    {
+      /* does it have to handle PLUG, APPLICATION? */
+      spi_object_append_null_reference (&iter);
+    }
+  else
+    {
+      spi_object_append_reference (&iter, parent);
+    }
+
+  /* parent - states */
+  spi_atk_state_to_dbus_array (parent, states);
+  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_variant);
+  for (count = 0; count < 2; count++)
+    {
+      dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_UINT32,
+                                      &states[count]);
+    }
+  dbus_message_iter_close_container (&iter, &iter_variant);
+
+  /* parent - child count */
+  count = atk_object_get_n_accessible_children (parent);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count);
+
+  /* parent role */
+  role = atk_object_get_role (parent);
+  rv_role = spi_accessible_role_from_atk_role (role);
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &rv_role);
+
+  /* parent selected child count */
+  count = 0;
+  if (parent)
+    {
+      AtkSelection *selection = (AtkSelection *) parent;
+      if (ATK_IS_SELECTION(selection))
+        {
+          count = atk_selection_get_selection_count (selection);
+        }
+    }
+  dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &count);
+
+  /* relation object - DESCRIBED_BY */
+  rel_object = NULL;
+  set = atk_object_ref_relation_set (object);
+  count = atk_relation_set_get_n_relations (set);
+  for (i = 0; i < count; i++)
+  {
+    AtkRelation *r = atk_relation_set_get_relation (set, i);
+    if (!r)
+      continue;
+    AtkRelationType rt = atk_relation_get_relation_type (r);
+    if (rt == ATK_RELATION_DESCRIBED_BY)
+    {
+      GPtrArray *target = atk_relation_get_target (r);
+      if (target && target->len > 0)
+      {
+        rel_object = target->pdata[target->len - 1];
+        break;
+      }
+    }
+  }
+  if (!rel_object)
+    {
+      spi_object_append_null_reference (&iter);
+    }
+  else
+    {
+      spi_object_append_reference (&iter, rel_object);
+    }
+
+  return reply;
+}
 //
 
 static dbus_bool_t
@@ -1163,6 +1468,7 @@ static DRouteMethod methods[] = {
 // TIZEN_ONLY(20170310) - implementation of get object under coordinates for accessibility
   {impl_GetNavigableAtPoint, "GetNavigableAtPoint"},
   {impl_GetNeighbor, "GetNeighbor"},
+  {impl_GetReadingMaterial, "GetReadingMaterial"},
 //
   {impl_GetChildAtIndex, "GetChildAtIndex"},
   {impl_GetChildren, "GetChildren"},
index bc1f332..800bff2 100644 (file)
@@ -25,6 +25,10 @@ const char *spi_org_a11y_atspi_Accessible =
 ""
 "  <property access=\"read\" name=\"Locale\" type=\"s\" />"
 ""
+"  <method name=\"impl_GetReadingMaterial\">"
+"    <arg direction=\"out\" type=\"a{ss}sssuausiddddsibbii(so)auiui(so)\" />"
+"  </method>"
+""
 "  <method name=\"GetChildAtIndex\">"
 "    <arg direction=\"in\" name=\"index\" type=\"i\" />"
 "    <arg direction=\"out\" type=\"(so)\" />"