libaurum: add methods for adding and clearing popup watchers 20/322720/7
authorHosang Kim <hosang12.kim@samsung.com>
Thu, 10 Apr 2025 06:12:41 +0000 (15:12 +0900)
committerHosang Kim <hosang12.kim@samsung.com>
Thu, 24 Apr 2025 06:31:40 +0000 (15:31 +0900)
Change-Id: I85e3aa12c8e0d6db32d785e7149ddb329d595bd2

12 files changed:
libaurum/src/A11yEventHandler.cc
libaurum/src/Impl/Accessibility/AtspiAccessibleWatcher.cc
libaurum/src/UiDevice.cc
org.tizen.aurum-bootstrap/inc/AurumServiceImpl.h
org.tizen.aurum-bootstrap/inc/Commands/AddWatcherCommand.h [new file with mode: 0644]
org.tizen.aurum-bootstrap/inc/Commands/ClearWatcherCommand.h [new file with mode: 0644]
org.tizen.aurum-bootstrap/inc/Commands/Commands.h
org.tizen.aurum-bootstrap/meson.build
org.tizen.aurum-bootstrap/src/AurumServiceImpl.cc
org.tizen.aurum-bootstrap/src/Commands/AddWatcherCommand.cc [new file with mode: 0644]
org.tizen.aurum-bootstrap/src/Commands/ClearWatcherCommand.cc [new file with mode: 0644]
protocol/aurum.proto

index 9bf1a8fbd4f1a22c75e8ab12b53ec1665fcce6c1..f86c98d3e4c437b80a5f8772ba15e36b7e72bd1b 100644 (file)
@@ -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
index e800e60318b6960b33435f9b0666cf0910576d2c..a0ee1f9e08f489609cff61233cf2a6ef3ac56823 100644 (file)
@@ -602,14 +602,14 @@ bool AtspiAccessibleWatcher::addToWindowSet(AtspiAccessible *node)
 
 bool AtspiAccessibleWatcher::registerCallback(const A11yEvent type, EventHandler cb, void *data)
 {
-    auto handler = std::make_shared<A11yEventHandler>(type, cb, data);
+    auto handler = std::make_shared<A11yEventHandler>(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<std::shared_ptr<A11yEventHandler>> list;
-        list.push_back(handler);
+        list.push_back(std::move(handler));
         mHandlers.insert(std::pair<const A11yEvent, std::list<std::shared_ptr<A11yEventHandler>>>(type, list));
     }
     return true;
index 0873948820a99ab6e136aa245553a92182f370f8..776e99c4d38a1363af3da8eb9bc4329f0a45f3af 100644 (file)
@@ -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
index 85fb4aa76712e3970c9f90c0d767cf0130c5bef4..3d78211e9ac59351b4f3e3e63a9942bd304fdcd9 100644 (file)
@@ -17,6 +17,8 @@
 
 #pragma once
 
+#include <mutex>
+
 #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 (file)
index 0000000..749b9b8
--- /dev/null
@@ -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 <mutex>
+
+#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 (file)
index 0000000..260bcc0
--- /dev/null
@@ -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;
+};
index 5ecac85a032bb6ece7b67b90f1f4c3c79a3f278b..8b8227678aeb889af2002b0fff8be8ce7b42485c 100644 (file)
@@ -57,3 +57,5 @@
 #include "Commands/MouseUpCommand.h"
 #include "Commands/SetIncludeHiddenCommand.h"
 #include "Commands/GetIncludeHiddenCommand.h"
+#include "Commands/AddWatcherCommand.h"
+#include "Commands/ClearWatcherCommand.h"
index 4025cb457518fb9ced8d82887bddf629225eeaf1..1dd23a5560c14a56609197036075f36ee6582609 100644 (file)
@@ -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 = [
index b504ec4e21421df02eefb6da551fc9bcfb8c9aa5..d2702abf51d4479e97bbba5abbdc274a9c4d8baf 100644 (file)
@@ -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<std::mutex> lk(mLock);
+    mCond.wait(lk, [&] {return !mStopFlag;});
+    mLock.unlock();
     std::unique_ptr<PreCommand>  proxyPreCmd  = std::make_unique<PreCommand>(cmd);
     std::unique_ptr<PostCommand> proxyPostCmd = std::make_unique<PostCommand>(proxyPreCmd.get());
     ::grpc::Status ret = proxyPostCmd->execute();
@@ -390,4 +393,20 @@ aurumServiceImpl::~aurumServiceImpl()
 {
     std::unique_ptr<GetIncludeHiddenCommand> cmd = std::make_unique<GetIncludeHiddenCommand>(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<AddWatcherCommand> cmd = std::make_shared<AddWatcherCommand>(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<ClearWatcherCommand> cmd = std::make_unique<ClearWatcherCommand>(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 (file)
index 0000000..fb1d866
--- /dev/null
@@ -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 <chrono>
+#include <thread>
+
+#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<UiDevice> 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<AccessibleNode> node)->bool {
+                                    std::shared_ptr<UiObject> root = std::make_shared<UiObject>(mDevice, nullptr, node);
+                                    auto selector = std::make_shared<UiSelector>();
+                                    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<std::mutex> 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<UiSelector>();
+                                            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 (file)
index 0000000..a104e16
--- /dev/null
@@ -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<UiDevice> mDevice = UiDevice::getInstance();
+
+    mDevice->clearCallback();
+
+    mResponse->set_status(::aurum::RspStatus::OK);
+    return grpc::Status::OK;
+}
index 177b41472a6ed42b1269ef6cfeb8b59940c75d2b..1189cfe6220c1412e2376b2b37fef0550bbb87a2 100644 (file)
@@ -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;
+}