libaurum: new interface applied to improve performance 64/303764/2
authorWoochan Lee <wc0917.lee@samsung.com>
Thu, 4 Jan 2024 11:15:11 +0000 (20:15 +0900)
committerWoochan Lee <wc0917.lee@samsung.com>
Mon, 8 Jan 2024 07:46:52 +0000 (16:46 +0900)
Use GetNodeInfo interface brings each node's information into a single call
rather than individual API calls, resulting in a huge performance improvement.

Change-Id: Ib76151157f7e750548bdba2f9374188b084aefe7

libaurum/inc/Impl/Accessibility/AtspiWrapper.h
libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc
libaurum/src/Impl/Accessibility/AtspiWrapper.cc

index fbca138b683f081b5e6b9416ea448d773392cba4..63ac89d2b38456cc8f5dc8267852d7d8a74cedf4 100644 (file)
@@ -73,6 +73,8 @@ public:
     static void Atspi_accessible_set_listen_post_render(AtspiAccessible *obj, gboolean enabled, GError **error);
     static AtspiCollection *Atspi_accessible_get_collection_iface(AtspiAccessible *node);
     static GArray *Atspi_collection_get_matches(AtspiCollection *obj, AtspiMatchRule *rule, AtspiCollectionSortOrder sortby, gint count, gboolean traverse, GError **error);
+    static AtspiAccessibleNodeInfo *Atspi_accessible_get_node_info(AtspiAccessible *obj, GError **error);
+    static void Atspi_accessible_free_node_info(AtspiAccessibleNodeInfo *node_info);
 
 private:
     static std::recursive_mutex mMutex;
index a3a1dd6138d84fd4bb48201ff36398c156d671b2..df3b06427252e2b30d1b613ba6be5a2b3ff439c7 100644 (file)
@@ -342,126 +342,179 @@ void AtspiAccessibleNode::refresh(bool updateAll)
     AtspiWrapper::Atspi_accessible_clear_cache(mNode);
 
     if (isValid()) {
-        if (mRole.empty()) {
-            gchar *rolename = AtspiWrapper::Atspi_accessible_get_role_name(mNode, NULL);
-            if (rolename) {
-                mRole = rolename;
-                g_free(rolename);
-            }
-        }
-    #ifdef TIZEN
-        if (mId.empty()) {
-            gchar *uID = AtspiWrapper::Atspi_accessible_get_unique_id(mNode, NULL);
-            if (uID) {
-                mId = uID;
-                g_free(uID);
+        AtspiAccessibleNodeInfo *ni = AtspiWrapper::Atspi_accessible_get_node_info(mNode, NULL);
+        if (ni) {
+            if (mRole.empty()) mRole = ni->role_name;
+            mText = ni->name;
+            if (mToolkitName.empty()) mToolkitName = ni->toolkit_name;
+            if (mType.empty()) {
+                GHashTable *attributes = ni->attributes;
+                if (attributes) {
+                    char *t = (char *)g_hash_table_lookup(attributes, "type");
+                    if (!t) t = (char *)g_hash_table_lookup(attributes, "t");
+                    if (!t) t = (char *)g_hash_table_lookup(attributes, "class");
+                    char *s = (char *)g_hash_table_lookup(attributes, "style");
+                    char *a = (char *)g_hash_table_lookup(attributes, "automationId");
+
+                    if (t) mType = std::string(t);
+                    else mType = mRole;
+                    if (s) mStyle = std::string(s);
+                    if (a) mAutomationId = std::string(a);
+
+                    g_hash_table_unref(attributes);
+                }
             }
-        }
-    #else
-        mId = std::string{"N/A"};
-    #endif
-        gchar *name = AtspiWrapper::Atspi_accessible_get_name(mNode, NULL);
-        if (name) {
-            mText = name;
-            g_free(name);
-        }
+            if (ni->states) {
+                gint i = 0;
+                guint64 val = 1;
+                GArray *ret;
+
+                ret = g_array_new(TRUE, TRUE, sizeof(int));
+                if (!ret) {
+                    LOGE("Fail to alloc array for states");
+                    return;
+                }
 
-        if (mToolkitName.empty()) {
-            gchar *toolkitName = AtspiWrapper::Atspi_accessible_get_toolkit_name(mNode, NULL);
-            if (toolkitName) {
-                mToolkitName = toolkitName;
-                g_free(toolkitName);
-            }
-        }
+                for (i = 0; i < 64; i++) {
+                    if (ni->states & val) ret = g_array_append_val(ret, i);
+                    val <<= 1;
+                }
 
-        if (mPkg.empty()) {
-            AtspiAccessible *app = AtspiWrapper::Atspi_accessible_get_application(mNode, NULL);
-            if (app) {
-                gchar *pkg = AtspiWrapper::Atspi_accessible_get_name(app, NULL);
-                if (pkg) {
-                    mPkg = pkg;
-                    g_free(pkg);
+                if (ret) {
+                    AtspiStateType stat;
+                    for (unsigned int i = 0; ret && (i < ret->len); ++i) {
+                        stat = g_array_index(ret, AtspiStateType, i);
+                        setFeatureProperty(stat);
+                    }
+                    g_array_free(ret, 1);
                 }
-                g_object_unref(app);
             }
-        }
-
-        if (mType.empty()) {
-            GHashTable *attributes = AtspiWrapper::Atspi_accessible_get_attributes(mNode, NULL);
-            if (attributes) {
-                char *t = (char*)g_hash_table_lookup(attributes, "type");
-                if (!t) t = (char*)g_hash_table_lookup(attributes, "t");
-                if (!t) t = (char*)g_hash_table_lookup(attributes, "class");
-                char *s = (char*)g_hash_table_lookup(attributes, "style");
-                char *a = (char*)g_hash_table_lookup(attributes, "automationId");
-
-                if (t) mType =  std::string(t);
-                else mType = mRole;
-                if (s) mStyle = std::string(s);
-                if (a) mAutomationId = std::string(a);
-
-                g_hash_table_unref(attributes);
+            if (ni->screen_extents)
+                mScreenBoundingBox = Rect<int>{
+                    ni->screen_extents->x, ni->screen_extents->y,
+                    ni->screen_extents->x + ni->screen_extents->width,
+                    ni->screen_extents->y + ni->screen_extents->height};
+            if (ni->window_extents)
+                mWindowBoundingBox = Rect<int>{
+                    ni->window_extents->x, ni->window_extents->y,
+                    ni->window_extents->x + ni->window_extents->width,
+                    ni->window_extents->y + ni->window_extents->height};
+
+            mMinValue = ni->lower;
+            mMaxValue = ni->upper;
+            mValue = ni->value;
+            mIncrement = ni->increment;
+
+            AtspiWrapper::Atspi_accessible_free_node_info(ni);
+        } else {
+            // TODO: Add Atspi_accessible_get_node_info() for efl.
+            //       In case of efl, there are not many objects nomally so its not big advantage for performance though
+            //       need to add interface for consistency.
+            if (mRole.empty()) {
+                gchar *rolename = AtspiWrapper::Atspi_accessible_get_role_name(mNode, NULL);
+                if (rolename) {
+                    mRole = rolename;
+                    g_free(rolename);
+                }
+            }
+            #ifdef TIZEN
+            if (mId.empty()) {
+                gchar *uID = AtspiWrapper::Atspi_accessible_get_unique_id(mNode, NULL);
+                if (uID) {
+                    mId = uID;
+                    g_free(uID);
+                }
+            }
+            #else
+            mId = std::string{"N/A"};
+            #endif
+            gchar *name = AtspiWrapper::Atspi_accessible_get_name(mNode, NULL);
+            if (name) {
+                mText = name;
+                g_free(name);
             }
-        }
 
-        AtspiStateSet *st = AtspiWrapper::Atspi_accessible_get_state_set(mNode);
-        if (st) {
-            GArray *states = AtspiWrapper::Atspi_state_set_get_states(st);
-            if (states) {
-                AtspiStateType stat;
-                for (unsigned int i = 0; states && (i < states->len); ++i) {
-                    stat = g_array_index(states, AtspiStateType, i);
-                    setFeatureProperty(stat);
+            if (mToolkitName.empty()) {
+                gchar *toolkitName = AtspiWrapper::Atspi_accessible_get_toolkit_name(mNode, NULL);
+                if (toolkitName) {
+                    mToolkitName = toolkitName;
+                    g_free(toolkitName);
                 }
-                g_array_free(states, 1);
             }
-            g_object_unref(st);
-        }
-        AtspiComponent *component = AtspiWrapper::Atspi_accessible_get_component_iface(mNode);
-        if (component) {
-            AtspiRect *screenExtent = AtspiWrapper::Atspi_component_get_extents(
-                component, ATSPI_COORD_TYPE_SCREEN, NULL);
-            if (screenExtent) {
-                mScreenBoundingBox =
-                    Rect<int>{screenExtent->x, screenExtent->y, screenExtent->x + screenExtent->width,
-                            screenExtent->y + screenExtent->height};\
-                g_free(screenExtent);
+
+            if (mPkg.empty()) {
+                AtspiAccessible *app = AtspiWrapper::Atspi_accessible_get_application(mNode, NULL);
+                if (app) {
+                    gchar *pkg = AtspiWrapper::Atspi_accessible_get_name(app, NULL);
+                    if (pkg) {
+                        mPkg = pkg;
+                        g_free(pkg);
+                    }
+                    g_object_unref(app);
+                }
             }
 
-            AtspiRect *windowExtent = AtspiWrapper::Atspi_component_get_extents(
-                component, ATSPI_COORD_TYPE_WINDOW, NULL);
-            if (windowExtent) {
-                mWindowBoundingBox =
-                    Rect<int>{windowExtent->x, windowExtent->y, windowExtent->x + windowExtent->width,
-                            windowExtent->y + windowExtent->height};\
-                g_free(windowExtent);
+            if (mType.empty()) {
+                GHashTable *attributes = AtspiWrapper::Atspi_accessible_get_attributes(mNode, NULL);
+                if (attributes) {
+                    char *t = (char *)g_hash_table_lookup(attributes, "type");
+                    if (!t) t = (char *)g_hash_table_lookup(attributes, "t");
+                    if (!t) t = (char *)g_hash_table_lookup(attributes, "class");
+                    char *s = (char *)g_hash_table_lookup(attributes, "style");
+                    char *a = (char *)g_hash_table_lookup(attributes, "automationId");
+
+                    if (t) mType = std::string(t);
+                    else mType = mRole;
+                    if (s) mStyle = std::string(s);
+                    if (a) mAutomationId = std::string(a);
+
+                    g_hash_table_unref(attributes);
+                }
             }
-            g_object_unref(component);
-        }
 
-        AtspiValue *value = AtspiWrapper::Atspi_accessible_get_value(mNode);
-        if (value) {
-            mMinValue= AtspiWrapper::Atspi_value_get_minimum_value(value, NULL);
-            mMaxValue= AtspiWrapper::Atspi_value_get_maximum_value(value, NULL);
-            mValue= AtspiWrapper::Atspi_value_get_current_value(value, NULL);
-            mIncrement= AtspiWrapper::Atspi_value_get_minimum_increment(value, NULL);
-            g_object_unref(value);
-        }
+            AtspiStateSet *st = AtspiWrapper::Atspi_accessible_get_state_set(mNode);
+            if (st) {
+                GArray *states = AtspiWrapper::Atspi_state_set_get_states(st);
+                if (states) {
+                    AtspiStateType stat;
+                    for (unsigned int i = 0; states && (i < states->len); ++i) {
+                        stat = g_array_index(states, AtspiStateType, i);
+                        setFeatureProperty(stat);
+                    }
+                    g_array_free(states, 1);
+                }
+                g_object_unref(st);
+            }
+            AtspiComponent *component = AtspiWrapper::Atspi_accessible_get_component_iface(mNode);
+            if (component) {
+                AtspiRect *screenExtent = AtspiWrapper::Atspi_component_get_extents(component, ATSPI_COORD_TYPE_SCREEN, NULL);
+                if (screenExtent) {
+                    mScreenBoundingBox = Rect<int>{screenExtent->x, screenExtent->y, screenExtent->x + screenExtent->width, screenExtent->y + screenExtent->height};
+                    g_free(screenExtent);
+                }
 
-        GArray *interfaces = AtspiWrapper::Atspi_accessible_get_interfaces(mNode);
-        if (interfaces)
-        {
-            for (unsigned int i = 0; i < interfaces->len; i++)
-            {
-                gchar *interface = g_array_index(interfaces, gchar *, i);
-                if (g_strcmp0(interface, "EditableText") == 0 || g_strcmp0(interface, "Value") == 0)
-                {
-                    mInterface = interface;
+                AtspiRect *windowExtent = AtspiWrapper::Atspi_component_get_extents(component, ATSPI_COORD_TYPE_WINDOW, NULL);
+                if (windowExtent) {
+                    mWindowBoundingBox =
+                        Rect<int>{windowExtent->x, windowExtent->y, windowExtent->x + windowExtent->width, windowExtent->y + windowExtent->height};
+                    g_free(windowExtent);
                 }
+                g_object_unref(component);
+            }
+
+            AtspiValue *value = AtspiWrapper::Atspi_accessible_get_value(mNode);
+            if (value) {
+                mMinValue = AtspiWrapper::Atspi_value_get_minimum_value(value, NULL);
+                mMaxValue = AtspiWrapper::Atspi_value_get_maximum_value(value, NULL);
+                mValue = AtspiWrapper::Atspi_value_get_current_value(value, NULL);
+                mIncrement = AtspiWrapper::Atspi_value_get_minimum_increment(value, NULL);
+                g_object_unref(value);
             }
-            g_array_free(interfaces, true);
         }
 
+        //FIXME: It should be belongs into Atspi_accessible_get_node_info()
+        updateInterface();
+
         if (updateAll) updateXPath();
 
     } else {
index 4d78d750a30c366a05cca3232764afd487ed2362..10f98ff943265c11cf1755fbfd4f04676c4aefc0 100644 (file)
@@ -247,4 +247,16 @@ GArray *AtspiWrapper::Atspi_collection_get_matches(AtspiCollection *obj, AtspiMa
 {
     std::unique_lock<std::recursive_mutex> lock(mMutex);
     return atspi_collection_get_matches(obj, rule, sortby, count, traverse, error);
-}
\ No newline at end of file
+}
+
+AtspiAccessibleNodeInfo *AtspiWrapper::Atspi_accessible_get_node_info(AtspiAccessible *obj, GError **error)
+{
+    std::unique_lock<std::recursive_mutex> lock(mMutex);
+    return atspi_accessible_get_node_info(obj, error);
+}
+
+void AtspiWrapper::Atspi_accessible_free_node_info(AtspiAccessibleNodeInfo *node_info)
+{
+    std::unique_lock<std::recursive_mutex> lock(mMutex);
+    atspi_accessible_free_node_info(node_info);
+}