From 02742cfc78bbb9b488c3006d0a64717a22a05b88 Mon Sep 17 00:00:00 2001 From: Wonki Kim Date: Fri, 27 Mar 2020 14:06:10 +0900 Subject: [PATCH] bootstrap/aurum: rework GetAttributeCommand to support GetAttributeCommand, this patch implements regarding stuffs. Change-Id: I8fa93837b0bc14899091b6a7e3b24af3a3d4905b --- .../server/inc/Commands/GetAttributeCommand.h | 69 +++++++-- bootstrap/server/src/AurumServiceImpl.cc | 2 +- .../server/src/Commands/GetAttributeCommand.cc | 172 ++++++++++++++++++--- libaurum/inc/AccessibleNode.h | 9 +- libaurum/src/AccessibleNode.cc | 114 ++++++++++++-- protocol/examples/python/sample02.py | 9 ++ 6 files changed, 325 insertions(+), 50 deletions(-) diff --git a/bootstrap/server/inc/Commands/GetAttributeCommand.h b/bootstrap/server/inc/Commands/GetAttributeCommand.h index bea4b92..a1cac0b 100644 --- a/bootstrap/server/inc/Commands/GetAttributeCommand.h +++ b/bootstrap/server/inc/Commands/GetAttributeCommand.h @@ -9,30 +9,77 @@ #include "config.h" class GetAttributeCommand : public Command { -private: +protected: const ::aurum::ReqGetAttribute* mRequest; ::aurum::RspGetAttribute* mResponse; + ObjectMapper* mObjMap; public: GetAttributeCommand(const ::aurum::ReqGetAttribute* request, ::aurum::RspGetAttribute* response); - ; ::grpc::Status execute() override; + static std::unique_ptr createCommand(const ::aurum::ReqGetAttribute* request, + ::aurum::RspGetAttribute* response); }; -class AttributeGetter { -private: +class GetVisibleAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; public: - virtual ~AttributeGetter(); - static AttributeGetter *Creator(::aurum::ReqGetAttribute_RequestType type); - virtual bool getPerform(UiObject *obj, ::aurum::RspGetAttribute* mResponse){return true;} + ::grpc::Status execute() override; +}; + +class GetFocusedAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; +}; + +class GetFocusableAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; +}; + +class GetCheckableAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; +}; + +class GetCheckedAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; }; -class VisibleGetter : public AttributeGetter{ -private: +class GetEnabledAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; public: - virtual ~VisibleGetter(); - bool getPerform(UiObject *obj, ::aurum::RspGetAttribute* rsp) override; + ::grpc::Status execute() override; +}; + +class GetClickableAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; +}; + +class GetScrollableAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; +}; + +class GetSelectableAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; +}; + +class GetSelectedAttributeCommand : public GetAttributeCommand { + using GetAttributeCommand::GetAttributeCommand; +public: + ::grpc::Status execute() override; }; #endif \ No newline at end of file diff --git a/bootstrap/server/src/AurumServiceImpl.cc b/bootstrap/server/src/AurumServiceImpl.cc index 4ac6763..89e7c60 100644 --- a/bootstrap/server/src/AurumServiceImpl.cc +++ b/bootstrap/server/src/AurumServiceImpl.cc @@ -72,7 +72,7 @@ aurumServiceImpl::~aurumServiceImpl() {} ::grpc::ServerContext* context, const ::aurum::ReqGetAttribute* request, ::aurum::RspGetAttribute* response) { - std::unique_ptr cmd = std::make_unique(request, response); + std::unique_ptr cmd = GetAttributeCommand::createCommand(request, response); return execute(cmd.get()); } ::grpc::Status aurumServiceImpl::getSize(::grpc::ServerContext* context, diff --git a/bootstrap/server/src/Commands/GetAttributeCommand.cc b/bootstrap/server/src/Commands/GetAttributeCommand.cc index eec2835..f844c54 100644 --- a/bootstrap/server/src/Commands/GetAttributeCommand.cc +++ b/bootstrap/server/src/Commands/GetAttributeCommand.cc @@ -6,44 +6,172 @@ GetAttributeCommand::GetAttributeCommand( const ::aurum::ReqGetAttribute* request, ::aurum::RspGetAttribute* response) - : mRequest{request}, mResponse{response} + : mRequest{request}, mResponse{response}, mObjMap{ObjectMapper::getInstance()} { } ::grpc::Status GetAttributeCommand::execute() { - LOG_SCOPE_F(INFO, "GetAttribute --------------- "); - ObjectMapper* mObjMap = ObjectMapper::getInstance(); - UiObject* obj = mObjMap->getElement(mRequest->elementid()); + return grpc::Status::CANCELLED; +} + +std::unique_ptr GetAttributeCommand::createCommand(const ::aurum::ReqGetAttribute* request, + ::aurum::RspGetAttribute* response) +{ + ::aurum::ReqGetAttribute_RequestType type = request->attribute(); + + LOG_SCOPE_F(INFO, "type : %d", type); + + if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_VISIBLE) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_FOCUSABLE) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_FOCUSED) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_ENABLED) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_CLICKABLE) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_SCROLLABLE) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_CHECKABLE) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_CHECKED) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_SELECTED) + return std::make_unique(request, response); + else if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_SELECTABLE) + return std::make_unique(request, response); + else + return std::make_unique(request, response); +} + +::grpc::Status GetVisibleAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isVisible()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} + +::grpc::Status GetFocusedAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isFocused()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} + +::grpc::Status GetFocusableAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isFocusable()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} - ::aurum::ReqGetAttribute_RequestType type = mRequest->attribute(); - AttributeGetter *getter = AttributeGetter::Creator(type); +::grpc::Status GetCheckableAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isCheckable()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} - if (getter) - getter->getPerform(obj, mResponse); +::grpc::Status GetCheckedAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isChecked()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} +::grpc::Status GetEnabledAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isEnabled()); + mResponse->set_status(aurum::RspStatus::OK); return grpc::Status::OK; } -AttributeGetter* AttributeGetter::Creator(::aurum::ReqGetAttribute_RequestType type) +::grpc::Status GetClickableAttributeCommand::execute() { - switch(type) - { - case ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_VISIBLE: - return new VisibleGetter(); - default: - return nullptr; + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; } + mResponse->set_boolvalue(obj->isClickable()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; } -bool VisibleGetter::getPerform(UiObject *obj, ::aurum::RspGetAttribute* rsp) +::grpc::Status GetScrollableAttributeCommand::execute() { - bool isVisible = obj->isVisible(); + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isScrollable()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} - rsp->set_boolvalue(isVisible); - rsp->set_status(aurum::RspStatus::OK); +::grpc::Status GetSelectableAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isSelectable()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; +} - return true; +::grpc::Status GetSelectedAttributeCommand::execute() +{ + UiObject* obj = mObjMap->getElement(mRequest->elementid()); + if (!obj) { + mResponse->set_boolvalue(false); + mResponse->set_status(aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + mResponse->set_boolvalue(obj->isSelected()); + mResponse->set_status(aurum::RspStatus::OK); + return grpc::Status::OK; } -AttributeGetter::~AttributeGetter(){} -VisibleGetter::~VisibleGetter(){} \ No newline at end of file diff --git a/libaurum/inc/AccessibleNode.h b/libaurum/inc/AccessibleNode.h index a9eddc1..a842881 100644 --- a/libaurum/inc/AccessibleNode.h +++ b/libaurum/inc/AccessibleNode.h @@ -41,7 +41,9 @@ enum class NodeFeatureProperties { SELECTABLE = 0X0100, SELECTED = 0X0200, - VISIBILITY = 0X0400, + VISIBLE = 0X0400, + SHOWING = 0X0800, + ACTIVE = 0X0800, }; template @@ -136,7 +138,8 @@ public: private: bool isSupporting(AccessibleNodeInterface thisIface) const; bool hasFeatureProperty(NodeFeatureProperties prop) const; - void setFeatureProperty(NodeFeatureProperties prop, bool has); + void setFeatureProperty(NodeFeatureProperties prop, bool has) const; + void setFeatureProperty(AtspiStateType type) const; static std::map mNodeMap; private: @@ -153,7 +156,7 @@ private: mutable Rect mBoundingBox; int mSupportingIfaces; - int mFeatureProperty; + mutable int mFeatureProperty; bool mIsAlive; }; diff --git a/libaurum/src/AccessibleNode.cc b/libaurum/src/AccessibleNode.cc index 0de1c62..0f75a2b 100644 --- a/libaurum/src/AccessibleNode.cc +++ b/libaurum/src/AccessibleNode.cc @@ -98,21 +98,30 @@ void AccessibleNode::refresh() const mRes = "Not_Supported"; #endif - /* - GHashTable *attributes = atspi_accessible_get_attributes(mNode, NULL); - char *t = (char*)g_hash_table_lookup(attributes, "type"); - char *s = (char*)g_hash_table_lookup(attributes, "style"); - //LOG_F(INFO, "%s %s", t, s); + GHashTable *attributes = atspi_accessible_get_attributes(mNode.get(), NULL); + char *t = (char*)g_hash_table_lookup(attributes, "type"); + char *s = (char*)g_hash_table_lookup(attributes, "style"); - if (t) mType = std::string(t); - if (s) mStyle = std::string(s); + if (t) mType = std::string(t); + if (s) mStyle = std::string(s); - free(t); - free(s); + free(t); + free(s); - g_hash_table_unref(attributes); - */ + g_hash_table_unref(attributes); + + AtspiStateSet *st = atspi_accessible_get_state_set(mNode.get()); + GArray *states = atspi_state_set_get_states(st); + + char *state_name = NULL; + AtspiStateType stat; + for (int i = 0; states && (i < states->len); ++i) { + stat = g_array_index(states, AtspiStateType, i); + setFeatureProperty(stat); + } + + if (states) g_array_free(states, 0); } int AccessibleNode::getChildCount() const @@ -175,7 +184,86 @@ bool AccessibleNode::hasFeatureProperty(NodeFeatureProperties prop) const return (mFeatureProperty & static_cast(prop)) != 0; } -void AccessibleNode::setFeatureProperty(NodeFeatureProperties prop, bool has) +void AccessibleNode::setFeatureProperty(AtspiStateType type) const +{ +/* + LONGCLICKABLE = 0X0040, + SCROLLABLE = 0X0080, +*/ + switch(type) { + case ATSPI_STATE_CHECKED: + setFeatureProperty(NodeFeatureProperties::CHECKED, true); + break; + case ATSPI_STATE_CHECKABLE: + setFeatureProperty(NodeFeatureProperties::CHECKABLE, true); + break; + case ATSPI_STATE_ENABLED: + setFeatureProperty(NodeFeatureProperties::ENABLED, true); + break; + case ATSPI_STATE_FOCUSABLE: + setFeatureProperty(NodeFeatureProperties::FOCUSABLE, true); + break; + case ATSPI_STATE_FOCUSED: + setFeatureProperty(NodeFeatureProperties::FOCUSED, true); + break; + case ATSPI_STATE_SELECTABLE: + setFeatureProperty(NodeFeatureProperties::SELECTABLE, true); + break; + case ATSPI_STATE_SELECTED: + setFeatureProperty(NodeFeatureProperties::SELECTED, true); + break; + case ATSPI_STATE_SHOWING: + setFeatureProperty(NodeFeatureProperties::SHOWING, true); + break; + case ATSPI_STATE_VISIBLE: + setFeatureProperty(NodeFeatureProperties::VISIBLE, true); + break; + case ATSPI_STATE_ACTIVE: + setFeatureProperty(NodeFeatureProperties::ACTIVE, true); + break; + case ATSPI_STATE_SENSITIVE: + setFeatureProperty(NodeFeatureProperties::CLICKABLE, true); + break; + + case ATSPI_STATE_TRANSIENT: + case ATSPI_STATE_TRUNCATED: + case ATSPI_STATE_ANIMATED: + case ATSPI_STATE_INVALID: + case ATSPI_STATE_ARMED: + case ATSPI_STATE_BUSY: + case ATSPI_STATE_COLLAPSED: + case ATSPI_STATE_DEFUNCT: + case ATSPI_STATE_EDITABLE: + case ATSPI_STATE_EXPANDABLE: + case ATSPI_STATE_EXPANDED: + case ATSPI_STATE_HAS_TOOLTIP: + case ATSPI_STATE_HORIZONTAL: + case ATSPI_STATE_ICONIFIED: + case ATSPI_STATE_MODAL: + case ATSPI_STATE_MULTI_LINE: + case ATSPI_STATE_MULTISELECTABLE: + case ATSPI_STATE_OPAQUE: + case ATSPI_STATE_PRESSED: + case ATSPI_STATE_RESIZABLE: + case ATSPI_STATE_SINGLE_LINE: + case ATSPI_STATE_STALE: + case ATSPI_STATE_VERTICAL: + case ATSPI_STATE_MANAGES_DESCENDANTS: + case ATSPI_STATE_INDETERMINATE: + case ATSPI_STATE_REQUIRED: + case ATSPI_STATE_INVALID_ENTRY: + case ATSPI_STATE_SUPPORTS_AUTOCOMPLETION: + case ATSPI_STATE_SELECTABLE_TEXT: + case ATSPI_STATE_IS_DEFAULT: + case ATSPI_STATE_VISITED: + case ATSPI_STATE_HAS_POPUP: + case ATSPI_STATE_READ_ONLY: + case ATSPI_STATE_LAST_DEFINED: + break; + } +} + +void AccessibleNode::setFeatureProperty(NodeFeatureProperties prop, bool has) const { if (has) mFeatureProperty |= static_cast(prop); @@ -281,7 +369,7 @@ bool AccessibleNode::isSelected() const bool AccessibleNode::isVisible() const { - return hasFeatureProperty(NodeFeatureProperties::VISIBILITY); + return hasFeatureProperty(NodeFeatureProperties::VISIBLE); } AtspiAccessible *AccessibleNode::getAccessible() const diff --git a/protocol/examples/python/sample02.py b/protocol/examples/python/sample02.py index e49b583..5c7d849 100644 --- a/protocol/examples/python/sample02.py +++ b/protocol/examples/python/sample02.py @@ -75,10 +75,19 @@ def clickById(stub, id): ) ) +def getAttrById(stub, id, attr): + rsp = stub.getAttribute(aurum_pb2.ReqGetAttribute(attribute=attr, elementId=id)) + print(rsp) + def run_memo(stub): foundId = findElementByText(stub, 'All apps') time.sleep(1) if foundId != None: + getAttrById(stub, foundId, 'VISIBLE') + getAttrById(stub, foundId, 'CLICKABLE') + getAttrById(stub, foundId, 'FOCUSED') + getAttrById(stub, foundId, 'ENABLED') + getAttrById(stub, foundId, 'CHECKED') clickById(stub, foundId) time.sleep(1) -- 2.7.4