From: Woochan Lee Date: Thu, 4 Jan 2024 11:15:11 +0000 (+0900) Subject: libaurum: new interface applied to improve performance X-Git-Tag: accepted/tizen/unified/20240205.162750~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=29abbab4adac76a92bc994427864454c8bda3fed;p=platform%2Fcore%2Fuifw%2Faurum.git libaurum: new interface applied to improve performance 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 --- diff --git a/libaurum/inc/Impl/Accessibility/AtspiWrapper.h b/libaurum/inc/Impl/Accessibility/AtspiWrapper.h index fbca138..63ac89d 100644 --- a/libaurum/inc/Impl/Accessibility/AtspiWrapper.h +++ b/libaurum/inc/Impl/Accessibility/AtspiWrapper.h @@ -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; diff --git a/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc b/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc index a3a1dd6..df3b064 100644 --- a/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc +++ b/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc @@ -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{ + 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{ + 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{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{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{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{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 { diff --git a/libaurum/src/Impl/Accessibility/AtspiWrapper.cc b/libaurum/src/Impl/Accessibility/AtspiWrapper.cc index 4d78d75..10f98ff 100644 --- a/libaurum/src/Impl/Accessibility/AtspiWrapper.cc +++ b/libaurum/src/Impl/Accessibility/AtspiWrapper.cc @@ -247,4 +247,16 @@ GArray *AtspiWrapper::Atspi_collection_get_matches(AtspiCollection *obj, AtspiMa { std::unique_lock 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 lock(mMutex); + return atspi_accessible_get_node_info(obj, error); +} + +void AtspiWrapper::Atspi_accessible_free_node_info(AtspiAccessibleNodeInfo *node_info) +{ + std::unique_lock lock(mMutex); + atspi_accessible_free_node_info(node_info); +}