static const unsigned int LOGNCLICK_INTERVAL = 50;
};
-#endif
\ No newline at end of file
+#endif
}
return ret;
-}
\ No newline at end of file
+}
std::vector<std::shared_ptr<UiObject>> UiObject::getChildren() const
{
- auto sel = std::make_shared<UiSelector>();
- sel->depth(1);
- sel->isShowing(true);
- return this->findObjects(sel);
+ return this->findObjects(Sel::depth(1));
}
std::string UiObject::getApplicationPackage() const
// mDevice->waitForIdle();
mNode->refresh();
return mNode;
-}
\ No newline at end of file
+}
#include "Commands/SendKeyCommand.h"
#include "Commands/TakeScreenshotCommand.h"
-#endif
\ No newline at end of file
+#include "Commands/DumpObjectTreeCommand.h"
+#endif
--- /dev/null
+#pragma once
+#include <gio/gio.h>
+#include <grpcpp/grpcpp.h>
+#include "Commands/Command.h"
+#include "ObjectMapper.h"
+#include <aurum.grpc.pb.h>
+#include "config.h"
+
+class DumpObjectTreeCommand: public Command {
+protected:
+ const ::aurum::ReqDumpObjectTree* mRequest;
+ ::aurum::RspDumpObjectTree* mResponse;
+
+protected:
+ ObjectMapper* mObjMap;
+
+public:
+ DumpObjectTreeCommand(const ::aurum::ReqDumpObjectTree* request,
+ ::aurum::RspDumpObjectTree* response);
+ ::grpc::Status execute() override;
+protected:
+ void traverse(::aurum::Element *el, std::string key, int depth);
+};
files('src/Commands/Command.cc'),
files('src/Commands/PreCommand.cc'),
files('src/Commands/PostCommand.cc'),
+ files('src/Commands/DumpObjectTreeCommand.cc'),
]
bootstrap_svr_dep = [
pie:true,
)
-install_data('org.tizen.aurum-bootstrap.xml', install_dir: get_option('tzpackage_path'))
\ No newline at end of file
+install_data('org.tizen.aurum-bootstrap.xml', install_dir: get_option('tzpackage_path'))
{
std::unique_ptr<TakeScreenshotCommand> cmd = std::make_unique<TakeScreenshotCommand>(request, writer);
return execute(cmd.get());
-}
\ No newline at end of file
+}
+
+::grpc::Status aurumServiceImpl::dumpObjectTree(::grpc::ServerContext *context,
+ const ::aurum::ReqDumpObjectTree *request,
+ ::aurum::RspDumpObjectTree * response)
+{
+ std::unique_ptr<DumpObjectTreeCommand> cmd = std::make_unique<DumpObjectTreeCommand>(request, response);
+ return execute(cmd.get());
+}
--- /dev/null
+#include "DumpObjectTreeCommand.h"
+
+#include "ISearchable.h"
+
+#include "Sel.h"
+#include "UiDevice.h"
+#include "UiObject.h"
+#include "UiSelector.h"
+
+#include <loguru.hpp>
+
+
+DumpObjectTreeCommand::DumpObjectTreeCommand(const ::aurum::ReqDumpObjectTree* request,
+ ::aurum::RspDumpObjectTree* response)
+ : mRequest{request}, mResponse{response}
+{
+ mObjMap = ObjectMapper::getInstance();
+}
+
+void populateElement(::aurum::Element *el, std::shared_ptr<UiObject> obj)
+{
+}
+
+void DumpObjectTreeCommand::traverse(::aurum::Element *el, std::string key, int depth)
+{
+ LOG_SCOPE_F(INFO, "traverse depth:%d el:%p key:%s", depth, el, key.c_str());
+
+ auto obj = mObjMap->getElement(key);
+ auto children = obj->getChildren();
+
+ ::aurum::Rect *rect = el->mutable_geometry();
+ const Rect<int> &size = obj->getBoundingBox();
+ rect->set_x(size.mTopLeft.x);
+ rect->set_y(size.mTopLeft.y);
+ rect->set_width(size.width());
+ rect->set_height(size.height());
+
+ el->set_widget_type(obj->getElementType());
+ el->set_widget_style(obj->getElementStyle());
+ el->set_value(obj->getText());
+
+ el->set_isshowing(obj->isShowing());
+ el->set_isvisible(obj->isVisible());
+ el->set_isenabled(obj->isEnabled());
+ el->set_isselected(obj->isSelected());
+ el->set_ischecked(obj->isChecked());
+
+ for (auto&& child : children) {
+ if (!(child->isShowing() && child->isVisible())) continue;
+ ::aurum::Element *childEl = el->add_child();
+ std::string key2 = mObjMap->addElement(std::move(child));
+ childEl->set_elementid(key2);
+ traverse(childEl, key2, depth+1);
+ }
+}
+
+::grpc::Status DumpObjectTreeCommand::execute()
+{
+ LOG_SCOPE_F(INFO, "DumpObjectTree --------------- ");
+ LOG_F(INFO, "elementid : %s", mRequest->elementid().c_str());
+ if (mRequest->elementid().length()) {
+ ::aurum::Element* root = mResponse->add_roots();
+ root->set_elementid(mRequest->elementid());
+ traverse(root, mRequest->elementid(), 0);
+ } else {
+ ;
+ }
+ return grpc::Status::OK;
+}
\ No newline at end of file
rpc getLocation(ReqGetLocation) returns (RspGetLocation) {}
rpc sendKey(ReqKey) returns (RspKey) {}
rpc takeScreenshot(ReqTakeScreenshot) returns (stream RspTakeScreenshot) {}
+ rpc dumpObjectTree(ReqDumpObjectTree) returns (RspDumpObjectTree) {}
}
// ------------------------------------ //
message Element {
string elementId = 1;
+ repeated Element child = 2;
+ Rect geometry = 3;
+ string widget_type = 4;
+ string widget_style = 5;
+ string value = 6;
+ bool isShowing = 7;
+ bool isEnabled = 8;
+ bool isSelected = 9;
+ bool isChecked = 10;
+ bool isVisible = 11;
}
message Point {
}
message RspEmpty {
}
+
+// ------------------------------------ //
+
+message ReqDumpObjectTree {
+ string elementId = 1;
+}
+
+message RspDumpObjectTree {
+ RspStatus status = 1;
+ repeated Element roots = 2;
+}
\ No newline at end of file
import logging
import grpc
import time
+from tkinter import *
+from PIL import ImageTk,Image
+
def touchTest(stub):
stub.touchUp(ReqTouchUp(coordination=Point(x=160,y=30), seqId=0))
stub.touchUp(ReqTouchUp(coordination=Point(x=160,y=30), seqId=1))
return True
+global img
+
+def traverse(node, canvas, depth):
+ print('traverse', depth)
+ print('size:',node.geometry)
+
+ #//canvas.pack()
+ rect = canvas.create_rectangle(node.geometry.x, node.geometry.y, node.geometry.x+node.geometry.width, node.geometry.y+node.geometry.height, outline='red')
+ for child in node.child:
+ traverse(child, canvas, depth+1)
+
+def dumpTest(stub, tkroot):
+ response = stub.findElement(ReqFindElement(maxDepth=1, minDepth=1, isShowing=True))
+ print(response)
+ for i in response.elements:
+ response = stub.dumpObjectTree(ReqDumpObjectTree(elementId=i.elementId))
+ print(response.roots)
+
+ responses = stub.takeScreenshot(ReqTakeScreenshot())
+ image = open("screenshot.png", "wb")
+ for res in responses:
+ image.write(res.image)
+ image.close()
+
+ canvas = Canvas(tkroot, width=360, height=360)
+ canvas.pack()
+
+ img = ImageTk.PhotoImage(Image.open("./screenshot.png"))
+ print(img)
+ canvas.create_image(0, 0, anchor=NW, image=img)
+ canvas.img = img
+ traverse(response.roots[0], canvas, 0)
+
+def test(arg=None):
+ print(test, arg)
def run():
with grpc.insecure_channel('127.0.0.1:50051') as channel:
stub = aurum_pb2_grpc.BootstrapStub(channel)
- touchTest(stub)
+ root = Tk()
+ root.geometry('360x360')
+
+ dumpTest(stub, root)
+
+ root.mainloop()
+
+# touchTest(stub)
# print(stub.getLocation(ReqGetLocation()).status)
# print(stub.sync(ReqEmpty()))