From: Hosang Kim Date: Thu, 10 Apr 2025 06:12:41 +0000 (+0900) Subject: libaurum: add methods for adding and clearing popup watchers X-Git-Tag: accepted/tizen/unified/20250509.120514~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=96e82d1e6c839d1746df212e4404137321b6df55;p=platform%2Fcore%2Fuifw%2Faurum.git libaurum: add methods for adding and clearing popup watchers Change-Id: I85e3aa12c8e0d6db32d785e7149ddb329d595bd2 --- diff --git a/libaurum/src/A11yEventHandler.cc b/libaurum/src/A11yEventHandler.cc index 9bf1a8f..f86c98d 100644 --- a/libaurum/src/A11yEventHandler.cc +++ b/libaurum/src/A11yEventHandler.cc @@ -20,7 +20,7 @@ using namespace Aurum; A11yEventHandler::A11yEventHandler(A11yEvent type, EventHandler cb, void *data) - : mType(type), mCb(cb), mData(data) + : mType(type), mCb(std::move(cb)), mData(data) { } A11yEvent A11yEventHandler::getType() const diff --git a/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc b/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc index e800e60..a0ee1f9 100644 --- a/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc +++ b/libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc @@ -602,14 +602,14 @@ bool AtspiAccessibleWatcher::addToWindowSet(AtspiAccessible *node) bool AtspiAccessibleWatcher::registerCallback(const A11yEvent type, EventHandler cb, void *data) { - auto handler = std::make_shared(type, cb, data); + auto handler = std::make_shared(type, std::move(cb), data); if (mHandlers.count(type)) { auto list = mHandlers[type]; - list.push_back(handler); + list.push_back(std::move(handler)); mHandlers[type] = list; } else { std::list> list; - list.push_back(handler); + list.push_back(std::move(handler)); mHandlers.insert(std::pair>>(type, list)); } return true; diff --git a/libaurum/src/UiDevice.cc b/libaurum/src/UiDevice.cc index 0873948..776e99c 100644 --- a/libaurum/src/UiDevice.cc +++ b/libaurum/src/UiDevice.cc @@ -437,7 +437,7 @@ bool UiDevice::getExternalAppLaunched() bool UiDevice::registerCallback(const A11yEvent type, EventHandler cb, void *data) const { - return AccessibleWatcher::getInstance()->registerCallback(type, cb, data); + return AccessibleWatcher::getInstance()->registerCallback(type, std::move(cb), data); } bool UiDevice::clearCallback() const diff --git a/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h b/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h index 85fb4aa..3d78211 100644 --- a/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h +++ b/org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h @@ -17,6 +17,8 @@ #pragma once +#include + #include "bootstrap.h" class aurumServiceImpl final : public aurum::Bootstrap::Service { @@ -165,6 +167,15 @@ public: ::grpc::Status getIncludeHidden(::grpc::ServerContext *context, const ::aurum::ReqGetIncludeHidden *request, ::aurum::RspGetIncludeHidden *response) override; + ::grpc::Status addWatcher(::grpc::ServerContext *context, + const ::aurum::ReqAddWatcher *request, + ::aurum::RspAddWatcher *response) override; + ::grpc::Status clearWatcher(::grpc::ServerContext *context, + const ::aurum::ReqClearWatcher *request, + ::aurum::RspClearWatcher *response) override; public: + std::mutex mLock; + std::condition_variable mCond; + bool mStopFlag; int WAIT_TIMEOUT_MS; }; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/AddWatcherCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/AddWatcherCommand.h new file mode 100644 index 0000000..749b9b8 --- /dev/null +++ b/org.tizen.aurum-bootstrap/inc/Commands/AddWatcherCommand.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 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 + +#include "bootstrap.h" + +class AddWatcherCommand : public Command { + +protected: + const ::aurum::ReqAddWatcher *mRequest; + ::aurum::RspAddWatcher *mResponse; + std::mutex &mLock; + std::condition_variable &mCond; + bool &mStopFlag; + +public: + AddWatcherCommand(const ::aurum::ReqAddWatcher *request, + ::aurum::RspAddWatcher *response, + std::mutex &m, + std::condition_variable &cond, + bool &stopFlag); + ::grpc::Status execute() override; +}; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/ClearWatcherCommand.h b/org.tizen.aurum-bootstrap/inc/Commands/ClearWatcherCommand.h new file mode 100644 index 0000000..260bcc0 --- /dev/null +++ b/org.tizen.aurum-bootstrap/inc/Commands/ClearWatcherCommand.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 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 ClearWatcherCommand : public Command { + +protected: + const ::aurum::ReqClearWatcher *mRequest; + ::aurum::RspClearWatcher *mResponse; + +public: + ClearWatcherCommand(const ::aurum::ReqClearWatcher *request, + ::aurum::RspClearWatcher *response); + ::grpc::Status execute() override; +}; diff --git a/org.tizen.aurum-bootstrap/inc/Commands/Commands.h b/org.tizen.aurum-bootstrap/inc/Commands/Commands.h index 5ecac85..8b82276 100644 --- a/org.tizen.aurum-bootstrap/inc/Commands/Commands.h +++ b/org.tizen.aurum-bootstrap/inc/Commands/Commands.h @@ -57,3 +57,5 @@ #include "Commands/MouseUpCommand.h" #include "Commands/SetIncludeHiddenCommand.h" #include "Commands/GetIncludeHiddenCommand.h" +#include "Commands/AddWatcherCommand.h" +#include "Commands/ClearWatcherCommand.h" diff --git a/org.tizen.aurum-bootstrap/meson.build b/org.tizen.aurum-bootstrap/meson.build index 4025cb4..1dd23a5 100644 --- a/org.tizen.aurum-bootstrap/meson.build +++ b/org.tizen.aurum-bootstrap/meson.build @@ -60,6 +60,8 @@ bootstrap_svr_src += [ files('src/Commands/MouseUpCommand.cc'), files('src/Commands/SetIncludeHiddenCommand.cc'), files('src/Commands/GetIncludeHiddenCommand.cc'), + files('src/Commands/AddWatcherCommand.cc'), + files('src/Commands/ClearWatcherCommand.cc'), ] bootstrap_svr_dep = [ diff --git a/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc b/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc index b504ec4..d2702ab 100644 --- a/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc +++ b/org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc @@ -25,7 +25,7 @@ using namespace grpc; using namespace aurum; aurumServiceImpl::aurumServiceImpl() - : WAIT_TIMEOUT_MS{0} + : mStopFlag{false}, WAIT_TIMEOUT_MS{0} { LOGI("creates watcher instance (start to look up at_spi server)"); AccessibleWatcher::getInstance(); @@ -33,6 +33,9 @@ aurumServiceImpl::aurumServiceImpl() ::grpc::Status aurumServiceImpl::execute(Command *cmd, bool clean) { + std::unique_lock lk(mLock); + mCond.wait(lk, [&] {return !mStopFlag;}); + mLock.unlock(); std::unique_ptr proxyPreCmd = std::make_unique(cmd); std::unique_ptr proxyPostCmd = std::make_unique(proxyPreCmd.get()); ::grpc::Status ret = proxyPostCmd->execute(); @@ -390,4 +393,20 @@ aurumServiceImpl::~aurumServiceImpl() { std::unique_ptr cmd = std::make_unique(request, response); return execute(cmd.get(), false); -} \ No newline at end of file +} + +::grpc::Status aurumServiceImpl::addWatcher(::grpc::ServerContext *context, + const ::aurum::ReqAddWatcher *request, + ::aurum::RspAddWatcher *response) +{ + std::shared_ptr cmd = std::make_shared(request, response, mLock, mCond, mStopFlag); + return execute(cmd.get(), false); +} + +::grpc::Status aurumServiceImpl::clearWatcher(::grpc::ServerContext *context, + const ::aurum::ReqClearWatcher *request, + ::aurum::RspClearWatcher *response) +{ + std::unique_ptr cmd = std::make_unique(request, response); + return execute(cmd.get(), false); +} diff --git a/org.tizen.aurum-bootstrap/src/Commands/AddWatcherCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/AddWatcherCommand.cc new file mode 100644 index 0000000..fb1d866 --- /dev/null +++ b/org.tizen.aurum-bootstrap/src/Commands/AddWatcherCommand.cc @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 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 +#include + +#include "AddWatcherCommand.h" +#include "UiObject.h" +#include "UiDevice.h" + +AddWatcherCommand::AddWatcherCommand(const ::aurum::ReqAddWatcher *request, + ::aurum::RspAddWatcher *response, + std::mutex &m, + std::condition_variable &cond, + bool &stopFlag) + : mRequest{request}, mResponse{response}, mLock{m}, mCond{cond}, mStopFlag{stopFlag} +{ +} + +::grpc::Status AddWatcherCommand::execute() +{ + LOGI("AddWatcher --------------- "); + std::shared_ptr mDevice = UiDevice::getInstance(); + ::aurum::ReqAddWatcher_Type watcherType = mRequest->type(); + std::string text = mRequest->text(); + std::string pkg = mRequest->pkg(); + std::string target = mRequest->target(); + std::string keycode = mRequest->xf86keycode(); + int duration = mRequest->durationms(); + + auto callback = [=, *this](void *data, A11yEvent type, std::shared_ptr node)->bool { + std::shared_ptr root = std::make_shared(mDevice, nullptr, node); + auto selector = std::make_shared(); + if (!text.empty()) selector->textPartialMatch(text); + if (!pkg.empty()) selector->pkg(pkg); + auto found = root->findObject(selector); + + if (found != nullptr) { + LOGI("Found object: %s", found->getText().c_str()); + std::lock_guard lock(mLock); + mStopFlag = true; + + if (watcherType == ::aurum::ReqAddWatcher_Type::ReqAddWatcher_Type_TAP) + { + LOGI("Tap found object"); + found->click(); + } + else if (watcherType == ::aurum::ReqAddWatcher_Type::ReqAddWatcher_Type_TAP_ON) + { + auto selector = std::make_shared(); + selector->textPartialMatch(target); + auto target = root->findObject(selector); + if (target != nullptr) { + LOGI("Tap target object %s", target->getText().c_str()); + target->click(); + } + } + else if (watcherType == ::aurum::ReqAddWatcher_Type::ReqAddWatcher_Type_PRESS) + { + LOGI("Press keycode %s", keycode.c_str()); + mDevice->pressKeyCode(keycode, KeyRequestType::STROKE); + } + else if (watcherType == ::aurum::ReqAddWatcher_Type::ReqAddWatcher_Type_SLEEP) + { + LOGI("Sleep for %d ms", duration); + std::this_thread::sleep_for(std::chrono::milliseconds{duration}); + } + mStopFlag = false; + mCond.notify_all(); + } + return true; + }; + mDevice->registerCallback(A11yEvent::EVENT_WINDOW_ACTIVATE, std::move(callback), nullptr); + mResponse->set_status(::aurum::RspStatus::OK); + return grpc::Status::OK; +} diff --git a/org.tizen.aurum-bootstrap/src/Commands/ClearWatcherCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/ClearWatcherCommand.cc new file mode 100644 index 0000000..a104e16 --- /dev/null +++ b/org.tizen.aurum-bootstrap/src/Commands/ClearWatcherCommand.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 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 "ClearWatcherCommand.h" +#include "UiObject.h" +#include "UiDevice.h" + +ClearWatcherCommand::ClearWatcherCommand(const ::aurum::ReqClearWatcher *request, + ::aurum::RspClearWatcher *response) + : mRequest{request}, mResponse{response} +{ +} + +::grpc::Status ClearWatcherCommand::execute() +{ + LOGI("ClearWatcher --------------- "); + std::shared_ptr mDevice = UiDevice::getInstance(); + + mDevice->clearCallback(); + + mResponse->set_status(::aurum::RspStatus::OK); + return grpc::Status::OK; +} diff --git a/protocol/aurum.proto b/protocol/aurum.proto index 177b414..1189cfe 100644 --- a/protocol/aurum.proto +++ b/protocol/aurum.proto @@ -49,6 +49,8 @@ service Bootstrap { rpc mouseUp(ReqMouseUp) returns (RspMouseUp) {} rpc setIncludeHidden(ReqSetIncludeHidden) returns (RspSetIncludeHidden) {} rpc getIncludeHidden(ReqGetIncludeHidden) returns (RspGetIncludeHidden) {} + rpc addWatcher(ReqAddWatcher) returns (RspAddWatcher) {} + rpc clearWatcher(ReqClearWatcher) returns (RspClearWatcher) {} } // ------------------------------------ // @@ -799,3 +801,32 @@ message RspGetIncludeHidden { RspStatus status = 1; bool enabled = 2; } + +message ReqAddWatcher { + enum Type { + TAP = 0; + TAP_ON = 1; + PRESS = 2; + SLEEP = 3; + } + Type type = 1; + string text = 2; + string pkg = 3; + + oneof params { + string target = 4; + string XF86keyCode = 5; + int32 durationMs = 6; + } +} + +message RspAddWatcher { + RspStatus status = 1; +} + +message ReqClearWatcher { +} + +message RspClearWatcher { + RspStatus status = 1; +}