From 1ff7142706cf170b02ffd6fc021ad75c2271ebda Mon Sep 17 00:00:00 2001 From: Hosang Kim Date: Thu, 18 Apr 2024 20:09:44 +0900 Subject: [PATCH] libaurum: Introduce next/prev/first/last API Change-Id: Icbf4fda7c3bdf799bc02c5f332ca32bdb7fa5e57 --- libaurum/inc/Accessibility/AccessibleNode.h | 20 ++++ .../Impl/Accessibility/AtspiAccessibleNode.h | 20 ++++ .../inc/Impl/Accessibility/AtspiWrapper.h | 1 + .../Impl/Accessibility/MockAccessibleNode.h | 20 ++++ libaurum/inc/UiObject.h | 36 ++++++ .../Impl/Accessibility/AtspiAccessibleNode.cc | 66 +++++++++++ .../src/Impl/Accessibility/AtspiWrapper.cc | 7 ++ .../Impl/Accessibility/MockAccessibleNode.cc | 20 ++++ libaurum/src/UiObject.cc | 32 ++++++ .../inc/AurumServiceImpl.h | 12 ++ .../inc/Commands/Commands.h | 4 + .../inc/Commands/FirstCommand.h | 29 +++++ .../inc/Commands/LastCommand.h | 29 +++++ .../inc/Commands/NextCommand.h | 29 +++++ .../inc/Commands/PrevCommand.h | 29 +++++ org.tizen.aurum-bootstrap/meson.build | 4 + .../src/AurumServiceImpl.cc | 31 +++++ .../src/Commands/FirstCommand.cc | 108 ++++++++++++++++++ .../src/Commands/LastCommand.cc | 108 ++++++++++++++++++ .../src/Commands/NextCommand.cc | 108 ++++++++++++++++++ .../src/Commands/PrevCommand.cc | 108 ++++++++++++++++++ protocol/aurum.proto | 40 +++++++ 22 files changed, 861 insertions(+) create mode 100644 org.tizen.aurum-bootstrap/inc/Commands/FirstCommand.h create mode 100644 org.tizen.aurum-bootstrap/inc/Commands/LastCommand.h create mode 100644 org.tizen.aurum-bootstrap/inc/Commands/NextCommand.h create mode 100644 org.tizen.aurum-bootstrap/inc/Commands/PrevCommand.h create mode 100644 org.tizen.aurum-bootstrap/src/Commands/FirstCommand.cc create mode 100644 org.tizen.aurum-bootstrap/src/Commands/LastCommand.cc create mode 100644 org.tizen.aurum-bootstrap/src/Commands/NextCommand.cc create mode 100644 org.tizen.aurum-bootstrap/src/Commands/PrevCommand.cc diff --git a/libaurum/inc/Accessibility/AccessibleNode.h b/libaurum/inc/Accessibility/AccessibleNode.h index 9a8766d..bee5e66 100644 --- a/libaurum/inc/Accessibility/AccessibleNode.h +++ b/libaurum/inc/Accessibility/AccessibleNode.h @@ -141,6 +141,26 @@ public: */ virtual std::vector> getMatchesInMatches(const std::shared_ptr firstSelector, const std::shared_ptr secondSelector, const bool ealryReturn) const = 0; + /** + * @copydoc UiObject::next() + */ + virtual std::shared_ptr next() const = 0; + + /** + * @copydoc UiObject::prev() + */ + virtual std::shared_ptr prev() const = 0; + + /** + * @copydoc UiObject::first() + */ + virtual std::shared_ptr first() const = 0; + + /** + * @copydoc UiObject::last() + */ + virtual std::shared_ptr last() const = 0; + /** * @brief Called by @AccessibleWatcher::notifyAll. * Changes Node property If it's @EventType, @ObjectEventType are matches. diff --git a/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h b/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h index 33d03d2..98b1bf7 100644 --- a/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h +++ b/libaurum/inc/Impl/Accessibility/AtspiAccessibleNode.h @@ -80,6 +80,26 @@ public: */ std::vector> getMatchesInMatches(const std::shared_ptr firstSelector, const std::shared_ptr secondSelector, const bool ealryReturn) const override; + /** + * @copydoc UiObject::next() + */ + std::shared_ptr next() const override; + + /** + * @copydoc UiObject::prev() + */ + std::shared_ptr prev() const override; + + /** + * @copydoc UiObject::first() + */ + std::shared_ptr first() const override; + + /** + * @copydoc UiObject::last() + */ + std::shared_ptr last() const override; + /** * @copydoc AccessibleNode::isValid() */ diff --git a/libaurum/inc/Impl/Accessibility/AtspiWrapper.h b/libaurum/inc/Impl/Accessibility/AtspiWrapper.h index 38022ea..764c7d3 100644 --- a/libaurum/inc/Impl/Accessibility/AtspiWrapper.h +++ b/libaurum/inc/Impl/Accessibility/AtspiWrapper.h @@ -78,6 +78,7 @@ public: static GArray *Atspi_collection_get_matches_in_matches(AtspiCollection *obj, AtspiMatchRule *first_rule, AtspiMatchRule *second_rule, AtspiCollectionSortOrder sortby, gint first_count, gint second_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); + static AtspiAccessible *Atspi_accessible_get_neighbor(AtspiAccessible *root, AtspiAccessible *start, AtspiNeighborSearchDirection direction, GError **error); private: static std::recursive_mutex mMutex; diff --git a/libaurum/inc/Impl/Accessibility/MockAccessibleNode.h b/libaurum/inc/Impl/Accessibility/MockAccessibleNode.h index 8c13710..3a0714a 100644 --- a/libaurum/inc/Impl/Accessibility/MockAccessibleNode.h +++ b/libaurum/inc/Impl/Accessibility/MockAccessibleNode.h @@ -79,6 +79,26 @@ public: */ std::vector> getMatchesInMatches(const std::shared_ptr firstSelector, const std::shared_ptr secondSelector, const bool ealryReturn) const override; + /** + * @copydoc UiObject::next() + */ + std::shared_ptr next() const override; + + /** + * @copydoc UiObject::prev() + */ + std::shared_ptr prev() const override; + + /** + * @copydoc UiObject::first() + */ + std::shared_ptr first() const override; + + /** + * @copydoc UiObject::last() + */ + std::shared_ptr last() const override; + public: /** * @brief TBD diff --git a/libaurum/inc/UiObject.h b/libaurum/inc/UiObject.h index 51f58a9..18046da 100644 --- a/libaurum/inc/UiObject.h +++ b/libaurum/inc/UiObject.h @@ -723,6 +723,42 @@ public: */ std::shared_ptr getAccessibleNode() const; + /** + * @brief Gets object's next. + * + * @return UiObject pointer + * + * @since_tizen 9.0 + */ + std::shared_ptr next() const; + + /** + * @brief Gets object's prev. + * + * @return UiObject pointer + * + * @since_tizen 9.0 + */ + std::shared_ptr prev() const; + + /** + * @brief Gets object's first. + * + * @return UiObject pointer + * + * @since_tizen 9.0 + */ + std::shared_ptr first() const; + + /** + * @brief Gets object's last. + * + * @return UiObject pointer + * + * @since_tizen 9.0 + */ + std::shared_ptr last() const; + private: std::shared_ptr mDevice; std::shared_ptr mSelector; diff --git a/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc b/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc index 451946b..1152510 100644 --- a/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc +++ b/libaurum/src/Impl/Accessibility/AtspiAccessibleNode.cc @@ -680,3 +680,69 @@ std::vector> AtspiAccessibleNode::getMatchesInMa return ret; } + +std::shared_ptr AtspiAccessibleNode::next() const +{ + if (!isValid()) { + return nullptr; + } + AtspiAccessible *app = AtspiWrapper::Atspi_accessible_get_application(mNode, NULL); + if (app) { + AtspiAccessible *next = AtspiWrapper::Atspi_accessible_get_neighbor(app, mNode, ATSPI_NEIGHBOR_SEARCH_FORWARD, NULL); + if (!next) { + next = AtspiWrapper::Atspi_accessible_get_neighbor(app, NULL, ATSPI_NEIGHBOR_SEARCH_FORWARD, NULL); + } + g_object_unref(app); + if (next) return std::make_shared(next); + } + + return nullptr; +} + +std::shared_ptr AtspiAccessibleNode::prev() const +{ + if (!isValid()) { + return nullptr; + } + AtspiAccessible *app = AtspiWrapper::Atspi_accessible_get_application(mNode, NULL); + if (app) { + AtspiAccessible *prev = AtspiWrapper::Atspi_accessible_get_neighbor(app, mNode, ATSPI_NEIGHBOR_SEARCH_BACKWARD, NULL); + if (!prev) { + prev = AtspiWrapper::Atspi_accessible_get_neighbor(app, NULL, ATSPI_NEIGHBOR_SEARCH_BACKWARD, NULL); + } + g_object_unref(app); + if (prev) return std::make_shared(prev); + } + + return nullptr; +} + +std::shared_ptr AtspiAccessibleNode::first() const +{ + if (!isValid()) { + return nullptr; + } + AtspiAccessible *app = AtspiWrapper::Atspi_accessible_get_application(mNode, NULL); + if (app) { + AtspiAccessible *first = AtspiWrapper::Atspi_accessible_get_neighbor(app, NULL, ATSPI_NEIGHBOR_SEARCH_FORWARD, NULL); + g_object_unref(app); + if (first) return std::make_shared(first); + } + + return nullptr; +} + +std::shared_ptr AtspiAccessibleNode::last() const +{ + if (!isValid()) { + return nullptr; + } + AtspiAccessible *app = AtspiWrapper::Atspi_accessible_get_application(mNode, NULL); + if (app) { + AtspiAccessible *last = AtspiWrapper::Atspi_accessible_get_neighbor(app, NULL, ATSPI_NEIGHBOR_SEARCH_BACKWARD, NULL); + g_object_unref(app); + if (last) return std::make_shared(last); + } + + return nullptr; +} \ No newline at end of file diff --git a/libaurum/src/Impl/Accessibility/AtspiWrapper.cc b/libaurum/src/Impl/Accessibility/AtspiWrapper.cc index d1b3b62..4b06ccb 100644 --- a/libaurum/src/Impl/Accessibility/AtspiWrapper.cc +++ b/libaurum/src/Impl/Accessibility/AtspiWrapper.cc @@ -278,3 +278,10 @@ void AtspiWrapper::Atspi_accessible_free_node_info(AtspiAccessibleNodeInfo *node std::unique_lock lock(mMutex); atspi_accessible_free_node_info(node_info); } + +AtspiAccessible *AtspiWrapper::Atspi_accessible_get_neighbor(AtspiAccessible *root, AtspiAccessible *start, AtspiNeighborSearchDirection direction, GError **error) +{ + std::unique_lock lock(mMutex); + return atspi_accessible_get_neighbor(root, start, direction, error); +} + diff --git a/libaurum/src/Impl/Accessibility/MockAccessibleNode.cc b/libaurum/src/Impl/Accessibility/MockAccessibleNode.cc index e8aa1d5..aa136cf 100644 --- a/libaurum/src/Impl/Accessibility/MockAccessibleNode.cc +++ b/libaurum/src/Impl/Accessibility/MockAccessibleNode.cc @@ -316,3 +316,23 @@ void MockAccessibleNode::clearActions(void) { mActionSet.clear(); } + +std::shared_ptr MockAccessibleNode::next() const +{ + return nullptr; +} + +std::shared_ptr MockAccessibleNode::prev() const +{ + return nullptr; +} + +std::shared_ptr MockAccessibleNode::first() const +{ + return nullptr; +} + +std::shared_ptr MockAccessibleNode::last() const +{ + return nullptr; +} \ No newline at end of file diff --git a/libaurum/src/UiObject.cc b/libaurum/src/UiObject.cc index a1f6e0c..fc18345 100644 --- a/libaurum/src/UiObject.cc +++ b/libaurum/src/UiObject.cc @@ -494,3 +494,35 @@ std::shared_ptr UiObject::getAccessibleNode() const // mDevice->waitForIdle(); return mNode; } + +std::shared_ptr UiObject::next() const { + auto nextNode = mNode->next(); + if (nextNode) { + return std::make_shared(mDevice, mSelector, nextNode); + } + return nullptr; +} + +std::shared_ptr UiObject::prev() const { + auto prevNode = mNode->prev(); + if (prevNode) { + return std::make_shared(mDevice, mSelector, prevNode); + } + return nullptr; +} + +std::shared_ptr UiObject::first() const { + auto firstNode = mNode->first(); + if (firstNode) { + return std::make_shared(mDevice, mSelector, firstNode); + } + return nullptr; +} + +std::shared_ptr UiObject::last() const { + auto lastNode = mNode->last(); + if (lastNode) { + return std::make_shared(mDevice, mSelector, lastNode); + } + return nullptr; +} \ No newline at end of file diff --git a/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h b/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h index 04159cc..584ef7b 100644 --- a/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h +++ b/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h @@ -135,6 +135,18 @@ public: ::grpc::Status moveTo(::grpc::ServerContext *context, const ::aurum::ReqMoveTo *request, ::aurum::RspMoveTo *response) override; + ::grpc::Status next(::grpc::ServerContext *context, + const ::aurum::ReqNext *request, + ::aurum::RspNext *response) override; + ::grpc::Status prev(::grpc::ServerContext *context, + const ::aurum::ReqPrev *request, + ::aurum::RspPrev *response) override; + ::grpc::Status first(::grpc::ServerContext *context, + const ::aurum::ReqFirst *request, + ::aurum::RspFirst *response) override; + ::grpc::Status last(::grpc::ServerContext *context, + const ::aurum::ReqLast *request, + ::aurum::RspLast *response) override; public: int WAIT_TIMEOUT_MS; }; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/Commands.h b/org.tizen.aurum-bootstrap/inc/Commands/Commands.h index bedd096..21f37a8 100644 --- a/org.tizen.aurum-bootstrap/inc/Commands/Commands.h +++ b/org.tizen.aurum-bootstrap/inc/Commands/Commands.h @@ -47,3 +47,7 @@ #include "Commands/GetTextMinBoundingRectCommand.h" #include "Commands/SetXMLSyncCommand.h" #include "Commands/GetAngleCommand.h" +#include "Commands/NextCommand.h" +#include "Commands/PrevCommand.h" +#include "Commands/FirstCommand.h" +#include "Commands/LastCommand.h" diff --git a/org.tizen.aurum-bootstrap/inc/Commands/FirstCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/FirstCommand.h new file mode 100644 index 0000000..5bb5280 --- /dev/null +++ b/org.tizen.aurum-bootstrap/inc/Commands/FirstCommand.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "bootstrap.h" + +class FirstCommand : public Command { +protected: + const ::aurum::ReqFirst *mRequest; + ::aurum::RspFirst *mResponse; + +public: + FirstCommand(const ::aurum::ReqFirst *request, + ::aurum::RspFirst *response); + ::grpc::Status execute() override; +}; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/LastCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/LastCommand.h new file mode 100644 index 0000000..c5ca10f --- /dev/null +++ b/org.tizen.aurum-bootstrap/inc/Commands/LastCommand.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "bootstrap.h" + +class LastCommand : public Command { +protected: + const ::aurum::ReqLast *mRequest; + ::aurum::RspLast *mResponse; + +public: + LastCommand(const ::aurum::ReqLast *request, + ::aurum::RspLast *response); + ::grpc::Status execute() override; +}; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/NextCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/NextCommand.h new file mode 100644 index 0000000..5b1fc81 --- /dev/null +++ b/org.tizen.aurum-bootstrap/inc/Commands/NextCommand.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "bootstrap.h" + +class NextCommand : public Command { +protected: + const ::aurum::ReqNext *mRequest; + ::aurum::RspNext *mResponse; + +public: + NextCommand(const ::aurum::ReqNext *request, + ::aurum::RspNext *response); + ::grpc::Status execute() override; +}; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/PrevCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/PrevCommand.h new file mode 100644 index 0000000..b4d335d --- /dev/null +++ b/org.tizen.aurum-bootstrap/inc/Commands/PrevCommand.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "bootstrap.h" + +class PrevCommand : public Command { +protected: + const ::aurum::ReqPrev *mRequest; + ::aurum::RspPrev *mResponse; + +public: + PrevCommand(const ::aurum::ReqPrev *request, + ::aurum::RspPrev *response); + ::grpc::Status execute() override; +}; diff --git a/org.tizen.aurum-bootstrap/meson.build b/org.tizen.aurum-bootstrap/meson.build index 9a9b29b..f945c55 100644 --- a/org.tizen.aurum-bootstrap/meson.build +++ b/org.tizen.aurum-bootstrap/meson.build @@ -50,6 +50,10 @@ bootstrap_svr_src += [ files('src/Commands/GetTextMinBoundingRectCommand.cc'), files('src/Commands/SetXMLSyncCommand.cc'), files('src/Commands/GetAngleCommand.cc'), + files('src/Commands/NextCommand.cc'), + files('src/Commands/PrevCommand.cc'), + files('src/Commands/FirstCommand.cc'), + files('src/Commands/LastCommand.cc'), ] bootstrap_svr_dep = [ diff --git a/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc b/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc index 1b3fa2f..dd94866 100644 --- a/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc +++ b/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc @@ -311,4 +311,35 @@ aurumServiceImpl::~aurumServiceImpl() { std::unique_ptr cmd = std::make_unique(request, response); return execute(cmd.get(), true); +} + +::grpc::Status aurumServiceImpl::next(::grpc::ServerContext *context, + const ::aurum::ReqNext *request, + ::aurum::RspNext *response) +{ + std::unique_ptr cmd = std::make_unique(request, response); + return execute(cmd.get(), true); +} + +::grpc::Status aurumServiceImpl::prev(::grpc::ServerContext *context, + const ::aurum::ReqPrev *request, + ::aurum::RspPrev *response) +{ + std::unique_ptr cmd = std::make_unique(request, response); + return execute(cmd.get(), true); +} + +::grpc::Status aurumServiceImpl::first(::grpc::ServerContext *context, + const ::aurum::ReqFirst *request, + ::aurum::RspFirst *response) +{ + std::unique_ptr cmd = std::make_unique(request, response); + return execute(cmd.get(), true); +} +::grpc::Status aurumServiceImpl::last(::grpc::ServerContext *context, + const ::aurum::ReqLast *request, + ::aurum::RspLast *response) +{ + std::unique_ptr cmd = std::make_unique(request, response); + return execute(cmd.get(), true); } \ No newline at end of file diff --git a/org.tizen.aurum-bootstrap/src/Commands/FirstCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/FirstCommand.cc new file mode 100644 index 0000000..43e21fb --- /dev/null +++ b/org.tizen.aurum-bootstrap/src/Commands/FirstCommand.cc @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "FirstCommand.h" +#include "UiObject.h" + +FirstCommand::FirstCommand(const ::aurum::ReqFirst *request, + ::aurum::RspFirst *response) + : mRequest{request}, mResponse{response} +{ +} + +::grpc::Status FirstCommand::execute() +{ + LOGI("First --------------- "); + + ObjectMapper *mObjMap = ObjectMapper::getInstance(); + std::shared_ptr base = mObjMap->getElement(mRequest->elementid()); + + if (!base) { + mResponse->set_status(::aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + + auto found = base->first(); + + if (found != nullptr) { + UiObject *obj = found.get(); + obj->refresh(); + if (mObjMap->getElement(obj->getId()) == nullptr) + mObjMap->addElement(std::move(found)); + + LOGI("found object : %p elementId:%s", obj, obj->getId().c_str()); + + ::aurum::Element *elm = mResponse->mutable_element(); + elm->set_elementid(obj->getId()); + elm->set_package(obj->getApplicationPackage()); + + ::aurum::Rect *rect = elm->mutable_geometry(); + const Rect &size = obj->getScreenBoundingBox(); + rect->set_x(size.mTopLeft.x); + rect->set_y(size.mTopLeft.y); + rect->set_width(size.width()); + rect->set_height(size.height()); + + ::aurum::Rect *windowRect = elm->mutable_windowrelativegeometry(); + const Rect &windowRelativeSize = obj->getWindowBoundingBox(); + windowRect->set_x(windowRelativeSize.mTopLeft.x); + windowRect->set_y(windowRelativeSize.mTopLeft.y); + windowRect->set_width(windowRelativeSize.width()); + windowRect->set_height(windowRelativeSize.height()); + + elm->set_widgettype(obj->getType()); + elm->set_widgetstyle(obj->getElementStyle()); + + elm->set_text(obj->getText()); + elm->set_xpath(obj->getXPath()); + elm->set_ocrtext(obj->getOcrText()); + elm->set_automationid(obj->getAutomationId()); + elm->set_package(obj->getApplicationPackage()); + elm->set_role(obj->getRole()); + + elm->set_ischecked(obj->isChecked()); + elm->set_ischeckable(obj->isCheckable()); + elm->set_isclickable(obj->isClickable()); + elm->set_isenabled(obj->isEnabled()); + elm->set_isfocused(obj->isFocused()); + elm->set_isfocusable(obj->isFocusable()); + elm->set_isscrollable(obj->isScrollable()); + elm->set_isselected(obj->isSelected()); + elm->set_isshowing(obj->isShowing()); + elm->set_isactive(obj->isActive()); + elm->set_isvisible(obj->isVisible()); + elm->set_isselectable(obj->isSelectable()); + elm->set_ishighlightable(obj->isHighlightable()); + + elm->set_minvalue(obj->getMinValue()); + elm->set_maxvalue(obj->getMaxValue()); + elm->set_value(obj->getValue()); + elm->set_increment(obj->getIncrement()); + + elm->set_windowangle(obj->getWindowAngle()); + elm->set_targetangle(obj->getTargetAngle()); + + elm->set_interface(obj->getInterface()); + elm->set_description(obj->getDescription()); + + mResponse->set_status(::aurum::RspStatus::OK); + } else { + mResponse->set_status(::aurum::RspStatus::ERROR); + } + + return grpc::Status::OK; +} diff --git a/org.tizen.aurum-bootstrap/src/Commands/LastCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/LastCommand.cc new file mode 100644 index 0000000..ada839a --- /dev/null +++ b/org.tizen.aurum-bootstrap/src/Commands/LastCommand.cc @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "LastCommand.h" +#include "UiObject.h" + +LastCommand::LastCommand(const ::aurum::ReqLast *request, + ::aurum::RspLast *response) + : mRequest{request}, mResponse{response} +{ +} + +::grpc::Status LastCommand::execute() +{ + LOGI("Last --------------- "); + + ObjectMapper *mObjMap = ObjectMapper::getInstance(); + std::shared_ptr base = mObjMap->getElement(mRequest->elementid()); + + if (!base) { + mResponse->set_status(::aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + + auto found = base->last(); + + if (found != nullptr) { + UiObject *obj = found.get(); + obj->refresh(); + if (mObjMap->getElement(obj->getId()) == nullptr) + mObjMap->addElement(std::move(found)); + + LOGI("found object : %p elementId:%s", obj, obj->getId().c_str()); + + ::aurum::Element *elm = mResponse->mutable_element(); + elm->set_elementid(obj->getId()); + elm->set_package(obj->getApplicationPackage()); + + ::aurum::Rect *rect = elm->mutable_geometry(); + const Rect &size = obj->getScreenBoundingBox(); + rect->set_x(size.mTopLeft.x); + rect->set_y(size.mTopLeft.y); + rect->set_width(size.width()); + rect->set_height(size.height()); + + ::aurum::Rect *windowRect = elm->mutable_windowrelativegeometry(); + const Rect &windowRelativeSize = obj->getWindowBoundingBox(); + windowRect->set_x(windowRelativeSize.mTopLeft.x); + windowRect->set_y(windowRelativeSize.mTopLeft.y); + windowRect->set_width(windowRelativeSize.width()); + windowRect->set_height(windowRelativeSize.height()); + + elm->set_widgettype(obj->getType()); + elm->set_widgetstyle(obj->getElementStyle()); + + elm->set_text(obj->getText()); + elm->set_xpath(obj->getXPath()); + elm->set_ocrtext(obj->getOcrText()); + elm->set_automationid(obj->getAutomationId()); + elm->set_package(obj->getApplicationPackage()); + elm->set_role(obj->getRole()); + + elm->set_ischecked(obj->isChecked()); + elm->set_ischeckable(obj->isCheckable()); + elm->set_isclickable(obj->isClickable()); + elm->set_isenabled(obj->isEnabled()); + elm->set_isfocused(obj->isFocused()); + elm->set_isfocusable(obj->isFocusable()); + elm->set_isscrollable(obj->isScrollable()); + elm->set_isselected(obj->isSelected()); + elm->set_isshowing(obj->isShowing()); + elm->set_isactive(obj->isActive()); + elm->set_isvisible(obj->isVisible()); + elm->set_isselectable(obj->isSelectable()); + elm->set_ishighlightable(obj->isHighlightable()); + + elm->set_minvalue(obj->getMinValue()); + elm->set_maxvalue(obj->getMaxValue()); + elm->set_value(obj->getValue()); + elm->set_increment(obj->getIncrement()); + + elm->set_windowangle(obj->getWindowAngle()); + elm->set_targetangle(obj->getTargetAngle()); + + elm->set_interface(obj->getInterface()); + elm->set_description(obj->getDescription()); + + mResponse->set_status(::aurum::RspStatus::OK); + } else { + mResponse->set_status(::aurum::RspStatus::ERROR); + } + + return grpc::Status::OK; +} diff --git a/org.tizen.aurum-bootstrap/src/Commands/NextCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/NextCommand.cc new file mode 100644 index 0000000..038acd5 --- /dev/null +++ b/org.tizen.aurum-bootstrap/src/Commands/NextCommand.cc @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "NextCommand.h" +#include "UiObject.h" + +NextCommand::NextCommand(const ::aurum::ReqNext *request, + ::aurum::RspNext *response) + : mRequest{request}, mResponse{response} +{ +} + +::grpc::Status NextCommand::execute() +{ + LOGI("Next --------------- "); + + ObjectMapper *mObjMap = ObjectMapper::getInstance(); + std::shared_ptr base = mObjMap->getElement(mRequest->elementid()); + + if (!base) { + mResponse->set_status(::aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + + auto found = base->next(); + + if (found != nullptr) { + UiObject *obj = found.get(); + obj->refresh(); + if (mObjMap->getElement(obj->getId()) == nullptr) + mObjMap->addElement(std::move(found)); + + LOGI("found object : %p elementId:%s", obj, obj->getId().c_str()); + + ::aurum::Element *elm = mResponse->mutable_element(); + elm->set_elementid(obj->getId()); + elm->set_package(obj->getApplicationPackage()); + + ::aurum::Rect *rect = elm->mutable_geometry(); + const Rect &size = obj->getScreenBoundingBox(); + rect->set_x(size.mTopLeft.x); + rect->set_y(size.mTopLeft.y); + rect->set_width(size.width()); + rect->set_height(size.height()); + + ::aurum::Rect *windowRect = elm->mutable_windowrelativegeometry(); + const Rect &windowRelativeSize = obj->getWindowBoundingBox(); + windowRect->set_x(windowRelativeSize.mTopLeft.x); + windowRect->set_y(windowRelativeSize.mTopLeft.y); + windowRect->set_width(windowRelativeSize.width()); + windowRect->set_height(windowRelativeSize.height()); + + elm->set_widgettype(obj->getType()); + elm->set_widgetstyle(obj->getElementStyle()); + + elm->set_text(obj->getText()); + elm->set_xpath(obj->getXPath()); + elm->set_ocrtext(obj->getOcrText()); + elm->set_automationid(obj->getAutomationId()); + elm->set_package(obj->getApplicationPackage()); + elm->set_role(obj->getRole()); + + elm->set_ischecked(obj->isChecked()); + elm->set_ischeckable(obj->isCheckable()); + elm->set_isclickable(obj->isClickable()); + elm->set_isenabled(obj->isEnabled()); + elm->set_isfocused(obj->isFocused()); + elm->set_isfocusable(obj->isFocusable()); + elm->set_isscrollable(obj->isScrollable()); + elm->set_isselected(obj->isSelected()); + elm->set_isshowing(obj->isShowing()); + elm->set_isactive(obj->isActive()); + elm->set_isvisible(obj->isVisible()); + elm->set_isselectable(obj->isSelectable()); + elm->set_ishighlightable(obj->isHighlightable()); + + elm->set_minvalue(obj->getMinValue()); + elm->set_maxvalue(obj->getMaxValue()); + elm->set_value(obj->getValue()); + elm->set_increment(obj->getIncrement()); + + elm->set_windowangle(obj->getWindowAngle()); + elm->set_targetangle(obj->getTargetAngle()); + + elm->set_interface(obj->getInterface()); + elm->set_description(obj->getDescription()); + + mResponse->set_status(::aurum::RspStatus::OK); + } else { + mResponse->set_status(::aurum::RspStatus::ERROR); + } + + return grpc::Status::OK; +} diff --git a/org.tizen.aurum-bootstrap/src/Commands/PrevCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/PrevCommand.cc new file mode 100644 index 0000000..3447b2c --- /dev/null +++ b/org.tizen.aurum-bootstrap/src/Commands/PrevCommand.cc @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "PrevCommand.h" +#include "UiObject.h" + +PrevCommand::PrevCommand(const ::aurum::ReqPrev *request, + ::aurum::RspPrev *response) + : mRequest{request}, mResponse{response} +{ +} + +::grpc::Status PrevCommand::execute() +{ + LOGI("Prev --------------- "); + + ObjectMapper *mObjMap = ObjectMapper::getInstance(); + std::shared_ptr base = mObjMap->getElement(mRequest->elementid()); + + if (!base) { + mResponse->set_status(::aurum::RspStatus::ERROR); + return grpc::Status::OK; + } + + auto found = base->prev(); + + if (found != nullptr) { + UiObject *obj = found.get(); + obj->refresh(); + if (mObjMap->getElement(obj->getId()) == nullptr) + mObjMap->addElement(std::move(found)); + + LOGI("found object : %p elementId:%s", obj, obj->getId().c_str()); + + ::aurum::Element *elm = mResponse->mutable_element(); + elm->set_elementid(obj->getId()); + elm->set_package(obj->getApplicationPackage()); + + ::aurum::Rect *rect = elm->mutable_geometry(); + const Rect &size = obj->getScreenBoundingBox(); + rect->set_x(size.mTopLeft.x); + rect->set_y(size.mTopLeft.y); + rect->set_width(size.width()); + rect->set_height(size.height()); + + ::aurum::Rect *windowRect = elm->mutable_windowrelativegeometry(); + const Rect &windowRelativeSize = obj->getWindowBoundingBox(); + windowRect->set_x(windowRelativeSize.mTopLeft.x); + windowRect->set_y(windowRelativeSize.mTopLeft.y); + windowRect->set_width(windowRelativeSize.width()); + windowRect->set_height(windowRelativeSize.height()); + + elm->set_widgettype(obj->getType()); + elm->set_widgetstyle(obj->getElementStyle()); + + elm->set_text(obj->getText()); + elm->set_xpath(obj->getXPath()); + elm->set_ocrtext(obj->getOcrText()); + elm->set_automationid(obj->getAutomationId()); + elm->set_package(obj->getApplicationPackage()); + elm->set_role(obj->getRole()); + + elm->set_ischecked(obj->isChecked()); + elm->set_ischeckable(obj->isCheckable()); + elm->set_isclickable(obj->isClickable()); + elm->set_isenabled(obj->isEnabled()); + elm->set_isfocused(obj->isFocused()); + elm->set_isfocusable(obj->isFocusable()); + elm->set_isscrollable(obj->isScrollable()); + elm->set_isselected(obj->isSelected()); + elm->set_isshowing(obj->isShowing()); + elm->set_isactive(obj->isActive()); + elm->set_isvisible(obj->isVisible()); + elm->set_isselectable(obj->isSelectable()); + elm->set_ishighlightable(obj->isHighlightable()); + + elm->set_minvalue(obj->getMinValue()); + elm->set_maxvalue(obj->getMaxValue()); + elm->set_value(obj->getValue()); + elm->set_increment(obj->getIncrement()); + + elm->set_windowangle(obj->getWindowAngle()); + elm->set_targetangle(obj->getTargetAngle()); + + elm->set_interface(obj->getInterface()); + elm->set_description(obj->getDescription()); + + mResponse->set_status(::aurum::RspStatus::OK); + } else { + mResponse->set_status(::aurum::RspStatus::ERROR); + } + + return grpc::Status::OK; +} diff --git a/protocol/aurum.proto b/protocol/aurum.proto index 9ee7ae4..9bba1ff 100644 --- a/protocol/aurum.proto +++ b/protocol/aurum.proto @@ -39,6 +39,10 @@ service Bootstrap { rpc setXMLSync(ReqSetXMLSync) returns (RspSetXMLSync) {} rpc getAngle(ReqGetAngle) returns (RspGetAngle) {} rpc moveTo(ReqMoveTo) returns (RspMoveTo) {} + rpc next(ReqNext) returns (RspNext) {} + rpc prev(ReqPrev) returns (RspPrev) {} + rpc first(ReqFirst) returns (RspFirst) {} + rpc last(ReqLast) returns (RspLast) {} } // ------------------------------------ // @@ -683,3 +687,39 @@ message RspGetAngle { int32 windowAngle = 2; int32 targetAngle = 3; } + +message ReqNext { + string elementId = 1; +} + +message RspNext { + RspStatus status = 1; + Element element = 2; +} + +message ReqPrev { + string elementId = 1; +} + +message RspPrev { + RspStatus status = 1; + Element element = 2; +} + +message ReqFirst { + string elementId = 1; +} + +message RspFirst { + RspStatus status = 1; + Element element = 2; +} + +message ReqLast { + string elementId = 1; +} + +message RspLast { + RspStatus status = 1; + Element element = 2; +} -- 2.34.1