From 5a6e796deb3b874ac029db4f9f4612d8accfe662 Mon Sep 17 00:00:00 2001 From: RinaYou Date: Thu, 10 May 2018 15:52:53 +0900 Subject: [PATCH] Init UIAutomator Change-Id: I1c00b55cd7091adb71c800015e9065727c8c5bb0 --- LICENSE | 202 ++++++++++++++++++++++++++ UIAutomator/CMakeLists.txt | 64 ++++++++ UIAutomator/dbus.cpp | 138 ++++++++++++++++++ UIAutomator/dbus.h | 49 +++++++ UIAutomator/hardware_key.cpp | 162 +++++++++++++++++++++ UIAutomator/hardware_key.h | 48 ++++++ UIAutomator/input_generator.cpp | 37 +++++ UIAutomator/input_generator.h | 50 +++++++ UIAutomator/keyboard.cpp | 228 +++++++++++++++++++++++++++++ UIAutomator/keyboard.h | 44 ++++++ UIAutomator/log.h | 52 +++++++ UIAutomator/main.cpp | 37 +++++ UIAutomator/server.cpp | 107 ++++++++++++++ UIAutomator/server.h | 59 ++++++++ UIAutomator/touch.cpp | 250 ++++++++++++++++++++++++++++++++ UIAutomator/touch.h | 54 +++++++ UIAutomator/type.h | 40 +++++ packaging/uiautomator.rule | 2 + packaging/uiautomator.spec | 50 +++++++ uiautomator.manifest | 5 + 20 files changed, 1678 insertions(+) create mode 100644 LICENSE create mode 100644 UIAutomator/CMakeLists.txt create mode 100644 UIAutomator/dbus.cpp create mode 100755 UIAutomator/dbus.h create mode 100644 UIAutomator/hardware_key.cpp create mode 100644 UIAutomator/hardware_key.h create mode 100644 UIAutomator/input_generator.cpp create mode 100644 UIAutomator/input_generator.h create mode 100644 UIAutomator/keyboard.cpp create mode 100644 UIAutomator/keyboard.h create mode 100755 UIAutomator/log.h create mode 100755 UIAutomator/main.cpp create mode 100644 UIAutomator/server.cpp create mode 100644 UIAutomator/server.h create mode 100644 UIAutomator/touch.cpp create mode 100644 UIAutomator/touch.h create mode 100644 UIAutomator/type.h create mode 100755 packaging/uiautomator.rule create mode 100755 packaging/uiautomator.spec create mode 100644 uiautomator.manifest diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/UIAutomator/CMakeLists.txt b/UIAutomator/CMakeLists.txt new file mode 100644 index 0000000..f53e110 --- /dev/null +++ b/UIAutomator/CMakeLists.txt @@ -0,0 +1,64 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(uiautomator) + +SET(PACKAGE ${PROJECT_NAME}) +SET(PKGNAME "${PROJECT_NAME}") +SET(PREFIX "/usr") +SET(BINDIR "${PREFIX}/bin") +SET(LIBDIR "${PREFIX}/lib") +SET(INCLUDEDIR "/usr/include") +SET(EXEC_PREFIX "${BINDIR}") + +FILE(GLOB_RECURSE SRCS "*.cpp") + +# ----------------------------------------------------------------------------- +# Set build type (Release by default) +# ----------------------------------------------------------------------------- + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE Release) +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") +MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +# ----------------------------------------------------------------------------- +# Required platform modules +# ----------------------------------------------------------------------------- +INCLUDE(FindPkgConfig) + +SET(PKG_MODULES + dlog + glib-2.0 + elementary + edbus + jsoncpp + dbus-glib-1 +) +PKG_CHECK_MODULES(pkgs REQUIRED ${PKG_MODULES}) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +# ----------------------------------------------------------------------------- +# CFlags +# ----------------------------------------------------------------------------- +SET(CMAKE_CXX_FLAGS_PROFILING "-O0 -std=c++0x -g -pg") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++0x -g") +SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -std=c++0x -Wall -pthread ${EXTRA_CFLAGS}") + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/src/ + ${pkgs_INCLUDE_DIRS} +) + +ADD_DEFINITIONS("-DUIAUTOMATOR_DLOG") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-lm -ldl -lrt") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) +INSTALL(FILES ${PROJECT_BINARY_DIR}/packaging/${PROJECT_NAME}.rule DESTINATION /etc/smack/accesses.d) +INSTALL(FILES ${PROJECT_BINARY_DIR}/LICENSE DESTINATION share/license RENAME ${PROJECT_NAME}) + +MESSAGE( STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR} ) +MESSAGE( STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/UIAutomator/dbus.cpp b/UIAutomator/dbus.cpp new file mode 100644 index 0000000..d5550d5 --- /dev/null +++ b/UIAutomator/dbus.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "server.h" +#include "dbus.h" + +#define DBUS_REPLY_TIMEOUT (-1) + +using namespace boost; +using namespace std; + +vector DBusSignal::SignalVector; + +DBusSignal::DBusSignal() + : EdbusConnection(NULL), + EdbusHandler(NULL) { +} + +DBusSignal::~DBusSignal() { + if (EdbusHandler != NULL) { + e_dbus_signal_handler_del(EdbusConnection, EdbusHandler); + EdbusHandler = NULL; + } + + if (EdbusConnection != NULL) { + e_dbus_connection_close(EdbusConnection); + EdbusConnection = NULL; + } +} + +DBusSignal* DBusSignal::getInstance() { + static DBusSignal instance; + return &instance; +} + +int DBusSignal::InitConnection() { + _D("InitConnection"); + if (nullptr != EdbusConnection) { + _E("Finish already to initailize connection"); + } + + e_dbus_init(); + EdbusConnection = e_dbus_bus_get(DBUS_BUS_SYSTEM); + if (EdbusConnection == NULL) { + _E("Failed to e_dbus_bus_get"); + return -1; + } + + EdbusHandler = e_dbus_signal_handler_add(EdbusConnection, NULL, "/org/tizen/appium", "org.tizen.appium", "Input", DBusSignalHandler, 0); + if (EdbusHandler == NULL) { + _E("fail to add size signal"); + return -1; + } + + EdbusHandler = e_dbus_signal_handler_add(EdbusConnection, NULL, "/aul/dbus_handler", "org.tizen.aul.signal", "app_launch", DBusAppSignalHandler, 0); + if (EdbusHandler == NULL) { + _E("Failed to e_dbus_signal_handler_add"); + return -1; + } + + return 0; +} + +void DBusSignal::DBusSignalHandler(void *data, DBusMessage *msg) { + _D("Enter"); + DBusMessageIter args; + char* type = NULL; + char* first = NULL; + char* second = NULL; + if (dbus_message_iter_init(msg, &args)) { + dbus_message_iter_get_basic(&args, &type); + dbus_message_iter_next(&args); + dbus_message_iter_get_basic(&args, &first); + dbus_message_iter_next(&args); + dbus_message_iter_get_basic(&args, &second); + dbus_message_iter_next(&args); + _D("Type=%s, 1st=%s, 2nd=%s", type, first, second); + } + + string action = type; + if (Server::getInstance().HandlerMap.find(action) != Server::getInstance().HandlerMap.end()) { + _D("[%s] Handler", action.c_str()); + //sleep(1); + Server::getInstance().HandlerMap[action](first, second); + } else { + _D("Invalid Command"); + } + return; +} + +void DBusSignal::DBusAppSignalHandler(void *data, DBusMessage *msg) { + if (NULL == msg) { + _E("DBusMessage is null"); + return; + } + + DBusMessageIter args; + unsigned int pid; + char* app_name; + if (dbus_message_iter_init(msg, &args)) { + dbus_message_iter_get_basic(&args, &pid); + dbus_message_iter_next(&args); + dbus_message_iter_get_basic(&args, &app_name); + _D("pid=%u app_name=%s", pid, app_name); + } + + if (strstr(app_name, "syspopup") != NULL) { + kill(pid, 9); + _D("PopupController kills %s during UI testing", app_name); + } + return; +} diff --git a/UIAutomator/dbus.h b/UIAutomator/dbus.h new file mode 100755 index 0000000..4cbdd19 --- /dev/null +++ b/UIAutomator/dbus.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef _DBUS_UTILS_H_ +#define _DBUS_UTILS_H_ + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +typedef std::function SignalHandler; + +class DBusSignal { + public: + DBusSignal(); + virtual ~DBusSignal(); + static DBusSignal* getInstance(); + int InitConnection(); + static void DBusAppSignalHandler(void *data, DBusMessage *msg); + static void DBusSignalHandler(void *data, DBusMessage *msg); + static void TouchHandler(void *data, DBusMessage *msg); + static void KeyboardHandler(void *data, DBusMessage *msg); + static void HardwareKeyHandler(void *data, DBusMessage *msg); + private: + E_DBus_Connection* EdbusConnection; + E_DBus_Signal_Handler* EdbusHandler; + static vector SignalVector; +}; + +#endif // _DBUS_UTILS_H_ diff --git a/UIAutomator/hardware_key.cpp b/UIAutomator/hardware_key.cpp new file mode 100644 index 0000000..0cbf577 --- /dev/null +++ b/UIAutomator/hardware_key.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016 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 "hardware_key.h" + +HardWareKey::HardWareKey() { + Initialize(); +} + +HardWareKey::~HardWareKey() { + +} + +bool HardWareKey::Initialize() { + memset(&device_information, 0, sizeof device_information); + + const char *file_name = "/dev/uinput"; + fake_device = open(file_name, O_WRONLY | O_NONBLOCK); + + if (fake_device < 0) { + _D("Fail to open fake uinput device!\n"); + return false; + } + + SetInputCodes(); + SetDeviceInformation(); + + if (write(fake_device, &device_information, sizeof(device_information)) != sizeof(device_information)) { + _D("Fail to setup uinput structure on fake device\n"); + return false; + } + + if (ioctl(fake_device, UI_DEV_CREATE) < 0) { + _D("Fail to create hardware key uinput device\n"); + return false; + } + + return true; +} + +void HardWareKey::PressKeyCode(string keyCode) { + KeyCodes key = KeyCodes::BACK; + + if (keyCode.compare("home") == 0) { + key = KeyCodes::HOME; + } else if (keyCode.compare("back") == 0) { + key = KeyCodes::BACK; + } else if (keyCode.compare("phone") == 0) { + key = KeyCodes::PHONE; + } else if (keyCode.compare("power") == 0) { + key = KeyCodes::POWER; + } else if (keyCode.compare("volumnDown") == 0) { + key = KeyCodes::VOLUME_DOWN; + } else if (keyCode.compare("volumnUp") == 0) { + key = KeyCodes::VOLUME_UP; + } + PressKeyCode(key); +} + +void HardWareKey::PressKeyCode(KeyCodes keyCode) { + int key; + switch (keyCode) { + case HOME: + key = KEY_MENU; + break; + case BACK: + key = KEY_BACK; + break; + case PHONE: + key = KEY_PHONE; + break; + case POWER: + key = KEY_POWER; + break; + case VOLUME_DOWN: + key = KEY_VOLUMEDOWN; + break; + case VOLUME_UP: + key = KEY_VOLUMEUP; + break; + default: + key = 0; + break; + } + Down(key); + Up(key); +} + +void HardWareKey::Down(int key) { + SendInputEvent(fake_device, EV_KEY, key, 1); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); +} + +void HardWareKey::Up(int key) { + SendInputEvent(fake_device, EV_KEY, key, 0); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); +} + +bool HardWareKey::SetInputCodes() { + if (ioctl(fake_device, UI_SET_EVBIT, EV_SYN) < 0) { + _D("Fail ioctl EV_SYN"); + return false; + } + + if (ioctl(fake_device, UI_SET_EVBIT, EV_KEY) < 0) { + _D("Fail ioctl EV_KEY"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_MENU) < 0) { + _D("Fail ioctl HOME KEY"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_BACK) < 0) { + _D("Fail ioctl BACK KEY"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_PHONE) < 0) { + _D("Fail ioctl PHONE KEY"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_POWER) < 0) { + _D("Fail ioctl POWER KEY"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_VOLUMEDOWN) < 0) { + _D("Fail ioctl VOLUMEDOWN KEY"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_VOLUMEUP) < 0) { + _D("Fail ioctl VOLUMEUP KEY"); + return false; + } + return true; +} + +void HardWareKey::SetDeviceInformation() { + const char *device_name = "Remote-Input(HardWareKey)"; + strncpy(device_information.name, device_name, sizeof(device_information.name) - 1); + device_information.id.bustype = BUS_USB; + device_information.id.vendor = 3; + device_information.id.product = 3; + device_information.id.version = 3; +} diff --git a/UIAutomator/hardware_key.h b/UIAutomator/hardware_key.h new file mode 100644 index 0000000..2e19124 --- /dev/null +++ b/UIAutomator/hardware_key.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016 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 "input_generator.h" + +/* + 0 : Home Button + 1 : Back Button + 2 : Phone Button + 3 : Power Button + 4 : Volume down Button + 5 : Volume up Button + */ +enum KeyCodes { + HOME = 0, + BACK, + PHONE, + POWER, + VOLUME_DOWN, + VOLUME_UP +}; + +class HardWareKey : InputGenerator { + public: + HardWareKey(); + ~HardWareKey(); + void Down(int key); + void Up(int key); + void PressKeyCode(KeyCodes keyCode); + void PressKeyCode(string keyCode); + protected: + virtual bool Initialize(); + virtual bool SetInputCodes(); + virtual void SetDeviceInformation(); +}; diff --git a/UIAutomator/input_generator.cpp b/UIAutomator/input_generator.cpp new file mode 100644 index 0000000..ab184b0 --- /dev/null +++ b/UIAutomator/input_generator.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 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 "input_generator.h" + +InputGenerator::~InputGenerator() { + if (ioctl(fake_device, UI_DEV_DESTROY) < 0) { + _D("Fail to destroy fake uinput device\n"); + } + close(fake_device); +} + +void InputGenerator::SendInputEvent(int fake_device, int type, int code, int value) { + struct input_event event; + + memset(&event, 0, sizeof(event)); + event.type = type; + event.code = code; + event.value = value; + + if (write(fake_device, &event, sizeof(event)) != sizeof(event)) { + _D("Error to send uinput event"); + } +} diff --git a/UIAutomator/input_generator.h b/UIAutomator/input_generator.h new file mode 100644 index 0000000..e2e77b0 --- /dev/null +++ b/UIAutomator/input_generator.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef __INPUT_GENERATOR_H_ +#define __INPUT_GENERATOR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" + +using namespace std; + +class InputGenerator { + public: + void SendInputEvent(int fake_device, int type, int code, int value); + protected: + ~InputGenerator(); + + int fake_device; + struct uinput_user_dev device_information; + virtual bool Initialize() = 0; + virtual bool SetInputCodes() = 0; + virtual void SetDeviceInformation() = 0; + private: + int fd_uinput_mouse; + int id; +}; + +#endif /* __INPUT_GENERATOR_H_ */ diff --git a/UIAutomator/keyboard.cpp b/UIAutomator/keyboard.cpp new file mode 100644 index 0000000..687e2d6 --- /dev/null +++ b/UIAutomator/keyboard.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2016 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 "keyboard.h" + +Keyboard::Keyboard() { + leftShiftStatus = false; + Initialize(); +} +Keyboard::~Keyboard() { + +} + +bool Keyboard::Initialize() { + memset(&device_information, 0, sizeof device_information); + + const char *file_name = "/dev/uinput"; + fake_device = open(file_name, O_WRONLY | O_NONBLOCK); + + if (fake_device < 0) { + _D("Fail to open fake uinput device!\n"); + return false; + } + + SetInputCodes(); + SetDeviceInformation(); + + if (write(fake_device, &device_information, sizeof(device_information)) != sizeof(device_information)) { + _D("Fail to setup uinput structure on fake device\n"); + return false; + } + + if (ioctl(fake_device, UI_DEV_CREATE) < 0) { + _D("Fail to create keyboard uinput device\n"); + return false; + } + + return true; +} + +void Keyboard::Down(int key) { + struct timespec sleeptime = { 0, 1000 }; + if (leftShiftStatus) { + SendInputEvent(fake_device, EV_KEY, KEY_LEFTSHIFT, 1); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + } + + SendInputEvent(fake_device, EV_KEY, key, 1); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + nanosleep(&sleeptime, NULL); + +} + +void Keyboard::Up(int key) { + struct timespec sleeptime = { 0, 1000 }; + SendInputEvent(fake_device, EV_KEY, key, 0); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + nanosleep(&sleeptime, NULL); + + if (leftShiftStatus) { + SendInputEvent(fake_device, EV_KEY, KEY_LEFTSHIFT, 0); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + leftShiftStatus = false; + } +} + +void Keyboard::PressKeyCode(char key_code) { + int key = ConvertKeyCode(key_code); + + Down(key); + Up(key); +} + +int Keyboard::ConvertKeyCode(char key_code) { + int key = 0; + map::iterator k; + map::iterator ks; + + ks = keyMapSecondary.find(key_code); + + if (ks != keyMapSecondary.end()) { + k = keyMap.find(ks->second); + if (k != keyMap.end()) { + key = k->second; + } + leftShiftStatus = true; + } else if ((int) key_code >= 65 && (int) key_code <= 90) { + int temp = (int) key_code + 32; + char tempCode = (char) temp; + k = keyMap.find(tempCode); + if (k != keyMap.end()) { + key = k->second; + } + leftShiftStatus = true; + } else { + k = keyMap.find(key_code); + if (k != keyMap.end()) { + key = k->second; + } + } + + return key; +} + +bool Keyboard::SetInputCodes() { + if (ioctl(fake_device, UI_SET_EVBIT, EV_SYN) < 0) { + _D("Fail ioctl method"); + return false; + } + + if (ioctl(fake_device, UI_SET_EVBIT, EV_KEY) < 0) { + _D("Fail ioctl method"); + return false; + } + + SetKeyCodes(); + + return true; +} + +void Keyboard::SetDeviceInformation() { + const char *device_name = "Remote-Input(Keyboard)"; + strncpy(device_information.name, device_name, sizeof(device_information.name) - 1); + device_information.id.bustype = BUS_USB; + device_information.id.vendor = 2; + device_information.id.product = 2; + device_information.id.version = 2; +} + +bool Keyboard::SetKeyCodes() { + SetKeyMaps(); + + for (pair k : keyMap) { + if (ioctl(fake_device, UI_SET_KEYBIT, k.second) < 0) { + _D("Fail ioctl method"); + return false; + } + } + + if (ioctl(fake_device, UI_SET_KEYBIT, KEY_LEFTSHIFT) < 0) { + _D("Fail ioctl method"); + return false; + } + + return true; +} + +void Keyboard::SetKeyMaps() { + keyMap['1'] = 2; + keyMap['2'] = 3; + keyMap['3'] = 4; + keyMap['4'] = 5; + keyMap['5'] = 6; + keyMap['6'] = 7; + keyMap['7'] = 8; + keyMap['8'] = 9; + keyMap['9'] = 10; + keyMap['0'] = 11; + keyMap['-'] = 12; + keyMap['='] = 13; + keyMap['q'] = 16; + keyMap['w'] = 17; + keyMap['e'] = 18; + keyMap['r'] = 19; + keyMap['t'] = 20; + keyMap['y'] = 21; + keyMap['u'] = 22; + keyMap['i'] = 23; + keyMap['o'] = 24; + keyMap['p'] = 25; + keyMap['['] = 26; + keyMap[']'] = 27; + keyMap['a'] = 30; + keyMap['s'] = 31; + keyMap['d'] = 32; + keyMap['f'] = 33; + keyMap['g'] = 34; + keyMap['h'] = 35; + keyMap['j'] = 36; + keyMap['k'] = 37; + keyMap['l'] = 38; + keyMap[';'] = 39; + keyMap['\''] = 40; + keyMap['z'] = 44; + keyMap['x'] = 45; + keyMap['c'] = 46; + keyMap['v'] = 47; + keyMap['b'] = 48; + keyMap['n'] = 49; + keyMap['m'] = 50; + keyMap[','] = 51; + keyMap['.'] = 52; + keyMap['/'] = 53; + keyMap[' '] = 57; + + keyMapSecondary['!'] = '1'; + keyMapSecondary['@'] = '2'; + keyMapSecondary['#'] = '3'; + keyMapSecondary['$'] = '4'; + keyMapSecondary['%'] = '5'; + keyMapSecondary['^'] = '6'; + keyMapSecondary['&'] = '7'; + keyMapSecondary['*'] = '8'; + keyMapSecondary['('] = '9'; + keyMapSecondary[')'] = '0'; + keyMapSecondary['_'] = '-'; + keyMapSecondary['+'] = '='; + keyMapSecondary['{'] = '['; + keyMapSecondary['}'] = ']'; + keyMapSecondary[':'] = ';'; + keyMapSecondary['"'] = '\''; + keyMapSecondary['<'] = ','; + keyMapSecondary['>'] = '.'; + keyMapSecondary['?'] = '/'; +} diff --git a/UIAutomator/keyboard.h b/UIAutomator/keyboard.h new file mode 100644 index 0000000..d610a21 --- /dev/null +++ b/UIAutomator/keyboard.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 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 "input_generator.h" + +#include + +using std::map; + +class Keyboard : InputGenerator { + public: + Keyboard(); + ~Keyboard(); + void PressKeyCode(char key_code); + void Down(int key); + void Up(int key); + protected: + virtual bool Initialize(); + virtual bool SetInputCodes(); + virtual void SetDeviceInformation(); + + private: + bool leftShiftStatus; + map keyMap; + map keyMapSecondary; + + int ConvertKeyCode(char key_code); + + bool SetKeyCodes(); + void SetKeyMaps(); +}; diff --git a/UIAutomator/log.h b/UIAutomator/log.h new file mode 100755 index 0000000..e69eae3 --- /dev/null +++ b/UIAutomator/log.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef __LOG_H_ +#define __LOG_H_ + +#ifdef UIAUTOMATOR_DLOG +#define LOG_TAG "UIAutomator" +#include + +#define _D(fmt, arg...) \ + do { LOGI(fmt, ##arg); } while(0) +#define _I(fmt, arg...) \ + do { LOGI(fmt, ##arg); } while(0) +#define _W(fmt, arg...) \ + do { LOGW(fmt, ##arg); } while(0) +#define _E(fmt, arg...) \ + do { LOGE(fmt, ##arg); } while(0) +#define _SD(fmt, arg...) \ + do { SECURE_SLOGD(fmt, ##arg); } while(0) +#define _SI(fmt, arg...) \ + do { SECURE_SLOGI(fmt, ##arg); } while(0) +#define _SW(fmt, arg...) \ + do { SECURE_SLOGW(fmt, ##arg); } while(0) +#define _SE(fmt, arg...) \ + do { SECURE_SLOGE(fmt, ##arg); } while(0) + +#else +#define _D(x, ...) do { } while (0) +#define _I(x, ...) do { } while (0) +#define _W(x, ...) do { } while (0) +#define _E(x, ...) do { } while (0) +#define _SD(fmt, args...) do { } while (0) +#define _SI(fmt, args...) do { } while (0) +#define _SW(fmt, args...) do { } while (0) +#define _SE(fmt, args...) do { } while (0) +#endif + +#endif /* __LOG_H_ */ diff --git a/UIAutomator/main.cpp b/UIAutomator/main.cpp new file mode 100755 index 0000000..a5d70bf --- /dev/null +++ b/UIAutomator/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 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 +#include + +#include "log.h" +#include "dbus.h" +#include "server.h" + +int main(int argc, char **argv) { + _D("UIAutomator Start"); + eina_init(); + ecore_init(); + + Server::getInstance().init(); + DBusSignal::getInstance()->InitConnection(); + + ecore_main_loop_begin(); + ecore_shutdown(); + return 0; +} diff --git a/UIAutomator/server.cpp b/UIAutomator/server.cpp new file mode 100644 index 0000000..e1f5cd2 --- /dev/null +++ b/UIAutomator/server.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016 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 +#include +#include +#include + +#include "type.h" +#include "server.h" + +using namespace std; + +Server::Server() { + _D("Enter"); +} + +void Server::AddHandler(string action, CommandHandler function) { + HandlerMap[action] = std::move(function); +} + +Server::~Server() { + _D("Enter"); +} + +Server& +Server::getInstance() { + static Server instance; + return instance; +} + +void Server::InputTextHandler(char* first, char* second) { + int count = strlen(first); + for (int i = 0; i < count; i++) { + keyboard.PressKeyCode(first[i]); + } +} + +void Server::ClickHandler(char* first, char* second) { + int x = atoi(first); + int y = atoi(second); + touch.Click(x, y); +} + +void Server::DownHandler(char* first, char* second) { + int x = atoi(first); + int y = atoi(second); + touch.Down(x, y); +} + +void Server::UpHandler(char* first, char* second) { + int x = atoi(first); + int y = atoi(second); + touch.Up(x, y); +} + +void Server::MoveHandler(char* first, char* second) { + int x = atoi(first); + int y = atoi(second); + touch.Move(x, y); +} + +void Server::LongPressHandler(char* first, char* second) { + int x = atoi(first); + int y = atoi(second); + int duration = 2000; + touch.Down(x, y); + usleep(duration); + touch.Up(x, y); +} + +void Server::FlickHandler(char* first, char* second) { + int xSpeed = atoi(first); + int ySpeed = atoi(second); + touch.Flick(xSpeed, ySpeed); +} + +void Server::BackHandler(char* first, char* second) { + hardwareKey.PressKeyCode("back"); +} + +void Server::init() { + _D("Init"); + AddHandler(EVENT_CLICK, std::bind(&Server::ClickHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_DOWN, std::bind(&Server::DownHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_UP, std::bind(&Server::UpHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_MOVE, std::bind(&Server::MoveHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_LONGPRESS, std::bind(&Server::LongPressHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_FLICK, std::bind(&Server::FlickHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_INPUTTEXT, std::bind(&Server::InputTextHandler, this, std::placeholders::_1, std::placeholders::_2)); + AddHandler(EVENT_BACK, std::bind(&Server::BackHandler, this, std::placeholders::_1, std::placeholders::_2)); +} diff --git a/UIAutomator/server.h b/UIAutomator/server.h new file mode 100644 index 0000000..c3758b9 --- /dev/null +++ b/UIAutomator/server.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef __SERVER_H_ +#define __SERVER_H_ + +#include +#include +#include +#include +#include + +#include "hardware_key.h" +#include "keyboard.h" +#include "touch.h" + +using namespace std; + +typedef std::function CommandHandler; + +class Server { + public: + Server(); + ~Server(); + void exit(); + void init(); + + static Server& getInstance(); + void AddHandler(string action, CommandHandler function); + + void InputTextHandler(char* first, char* second); + void ClickHandler(char* first, char* second); + void DownHandler(char* first, char* second); + void UpHandler(char* first, char* second); + void MoveHandler(char* first, char* second); + void LongPressHandler(char* first, char* second); + void FlickHandler(char* first, char* second); + void BackHandler(char* first, char* second); + std::map HandlerMap; + private: + Touch touch; + Keyboard keyboard; + HardWareKey hardwareKey; +}; + +#endif /* __SERVER_H_ */ diff --git a/UIAutomator/touch.cpp b/UIAutomator/touch.cpp new file mode 100644 index 0000000..ce45f3c --- /dev/null +++ b/UIAutomator/touch.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2016 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 "touch.h" + +Touch::Touch() { + Initialize(); +} + +Touch::~Touch() { +} + +bool Touch::Initialize() { + memset(&device_information, 0, sizeof device_information); + + const char *file_name = "/dev/uinput"; + fake_device = open(file_name, O_WRONLY | O_NONBLOCK); + + if (fake_device < 0) { + _D("Fail to open fake uinput device!\n"); + return false; + } + + SetInputCodes(); + SetDeviceInformation(); + + if (write(fake_device, &device_information, sizeof(device_information)) != sizeof(device_information)) { + _D("Fail to setup uinput structure on fake device\n"); + return false; + } + + if (ioctl(fake_device, UI_DEV_CREATE) < 0) { + _D("Fail to create touch uinput device\n"); + return false; + } + + return true; +} + +void Touch::Click(int x, int y) { + _D("X = %d, Y = %d", x, y); + Down(x, y); + Up(x, y); +} + +void Touch::Down(int x, int y) { + struct timespec sleeptime = { 0, 50 }; //speed (low value: fast, high value: slow) + _D("X = %d, Y = %d", x, y); + + int nowId = GetCurrentTrackingId(); + SendInputEvent(fake_device, EV_ABS, ABS_MT_TRACKING_ID, nowId); + SendInputEvent(fake_device, EV_KEY, BTN_TOUCH, 1); + SendInputEvent(fake_device, EV_ABS, ABS_MT_POSITION_X, x); + SendInputEvent(fake_device, EV_ABS, ABS_MT_POSITION_Y, y); + SendInputEvent(fake_device, EV_ABS, ABS_MT_TOUCH_MAJOR, 4); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + + nanosleep(&sleeptime, NULL); +} + +void Touch::Up(int x, int y) { + struct timespec sleeptime = { 0, 50 }; //speed (low value: fast, high value: slow) + _D("X = %d, Y = %d", x, y); + + SendInputEvent(fake_device, EV_ABS, ABS_MT_TRACKING_ID, -1); + SendInputEvent(fake_device, EV_KEY, BTN_TOUCH, 0); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + + nanosleep(&sleeptime, NULL); +} + +void Touch::Move(int x, int y) { + struct timespec sleeptime = { 0, 50 }; //speed (low value: fast, high value: slow) + _D("X = %d, Y = %d", x, y); + + SendInputEvent(fake_device, EV_ABS, ABS_MT_POSITION_X, x); + SendInputEvent(fake_device, EV_ABS, ABS_MT_POSITION_Y, y); + SendInputEvent(fake_device, EV_ABS, ABS_MT_TOUCH_MAJOR, 3); + SendInputEvent(fake_device, EV_SYN, SYN_REPORT, 0); + nanosleep(&sleeptime, NULL); +} + +void Touch::Flick(int xSpeed, int ySpeed) { + _D("xSpped %d, ySpeed %d", xSpeed, ySpeed); + + double speed = min(1250.0, sqrt((xSpeed * xSpeed) + (ySpeed * ySpeed))); + double steps = 1250.0 / speed; + + int xStart = ABS_X_MID; + int yStart = ABS_Y_MID; + + Point endPoint = GetEndPoint(xStart, yStart, xSpeed, ySpeed); + Swipe(xStart, yStart, endPoint.x, endPoint.y, steps); +} + +void Touch::Swipe(int xDown, int yDown, int xUp, int yUp, int steps) { + int swipeSteps = steps; + double xStep = 0; + double yStep = 0; + + if (swipeSteps == 0) { + swipeSteps = 1; + } + + xStep = ((double) (xUp - xDown)) / swipeSteps; + yStep = ((double) (yUp - yDown)) / swipeSteps; + Down(xDown, yDown); + for (int i = 0; i < swipeSteps; i++) { + Move(xDown + (int) (xStep * i), yDown + (int) (yStep * i)); + } + Up(xUp, yUp); +} + +int Touch::GetCurrentTrackingId() { + tracking_id++; + if (tracking_id >= TRACKING_ID_MAX) { + tracking_id = 1; + } + return tracking_id; +} + +Touch::Point Touch::GetEndPoint(int xStart, int yStart, int xSpeed, int ySpeed) { + double xDiff; + double yDiff; + int speedX = xSpeed; + int speedY = ySpeed; + + if (speedX == 0) { + speedX = 1; + } else if (speedX < 0) { + speedX = speedX * -1; + } + + if (speedY == 0) { + speedY = 1; + } else if (speedY < -1) { + speedY = speedY * -1; + } + double ratio = (double) speedX / speedY; + + if (ratio < 1) { + xDiff = ABS_X_MAX / 4 * ratio; + yDiff = ABS_Y_MAX / 4; + } else { + xDiff = ABS_X_MAX / 4; + yDiff = ABS_Y_MAX / 4 / ratio; + } + + xDiff = SigNumber(xSpeed) * xDiff; + yDiff = SigNumber(ySpeed) * yDiff; + + Point endPoint; + endPoint.x = (int) (xStart + xDiff); + endPoint.y = (int) (yStart + yDiff); + + return endPoint; +} + +int Touch::SigNumber(int number) { + if (number > 0) { + return 1; + } else if (number == 0) { + return 0; + } else { + return -1; + } +} + +bool Touch::SetInputCodes() { + if (ioctl(fake_device, UI_SET_EVBIT, EV_SYN) < 0) { + _D("Fail ioctl method"); + return false; + } + + if (ioctl(fake_device, UI_SET_EVBIT, EV_ABS) < 0) { + _D("Fail ioctl method"); + return false; + } + + if (ioctl(fake_device, UI_SET_EVBIT, EV_KEY) < 0) { + _D("Fail ioctl method"); + return false; + } + + if (ioctl(fake_device, UI_SET_KEYBIT, BTN_TOUCH) < 0) { + _D("Fail ioctl method"); + return false; + } + + if (ioctl(fake_device, UI_SET_ABSBIT, ABS_MT_SLOT) < 0) { // slot + _D("Fail ioctl method"); + return false; + } + if (ioctl(fake_device, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR) < 0) { // MT Touch Major + _D("Fail ioctl method"); + return false; + } + if (ioctl(fake_device, UI_SET_ABSBIT, ABS_MT_WIDTH_MAJOR) < 0) { // MT width Major + _D("Fail ioctl method"); + return false; + } + if (ioctl(fake_device, UI_SET_ABSBIT, ABS_MT_POSITION_X) < 0) { // MT Position X + _D("Fail ioctl method"); + return false; + } + if (ioctl(fake_device, UI_SET_ABSBIT, ABS_MT_POSITION_Y) < 0) { // MT Position Y + _D("Fail ioctl method"); + return false; + } + if (ioctl(fake_device, UI_SET_ABSBIT, ABS_MT_TRACKING_ID) < 0) { // MT Tacking ID + _D("Fail ioctl method"); + return false; + } + return true; +} + +void Touch::SetDeviceInformation() { + const char *device_name = "Remote-Input(Touch)"; + strncpy(device_information.name, device_name, sizeof(device_information.name) - 1); + device_information.id.bustype = BUS_USB; + device_information.id.vendor = 1; + device_information.id.product = 1; + device_information.id.version = 1; + + device_information.absmin[ABS_MT_SLOT] = 0; + device_information.absmax[ABS_MT_SLOT] = 1; + device_information.absmin[ABS_MT_TOUCH_MAJOR] = 0; + device_information.absmax[ABS_MT_TOUCH_MAJOR] = 15; + device_information.absmin[ABS_MT_WIDTH_MAJOR] = 0; + device_information.absmax[ABS_MT_WIDTH_MAJOR] = 255; + device_information.absmin[ABS_MT_POSITION_X] = 0; + device_information.absmax[ABS_MT_POSITION_X] = 719; + device_information.absmin[ABS_MT_POSITION_Y] = 0; + device_information.absmax[ABS_MT_POSITION_Y] = 1279; + device_information.absmin[ABS_MT_TRACKING_ID] = 0; + device_information.absmax[ABS_MT_TRACKING_ID] = 65535; +} diff --git a/UIAutomator/touch.h b/UIAutomator/touch.h new file mode 100644 index 0000000..297dcef --- /dev/null +++ b/UIAutomator/touch.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016 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 "input_generator.h" + +#include +#include + +#define TRACKING_ID_MAX 65535 + +class Touch : InputGenerator { + public: + Touch(); + ~Touch(); + void Click(int x, int y); + void Up(int x, int y); + void Down(int x, int y); + void Move(int x, int y); + void Flick(int xSpeed, int ySpeed); + void Swipe(int xDown, int yDown, int xUp, int yUp, int steps); + + protected: + virtual bool Initialize(); + virtual bool SetInputCodes(); + virtual void SetDeviceInformation(); + + private: + struct Point { + int x; + int y; + }; + const int ABS_X_MID = 359; + const int ABS_X_MAX = 639; + const int ABS_Y_MID = 719; + const int ABS_Y_MAX = 1279; + int tracking_id; + + int GetCurrentTrackingId(); + Point GetEndPoint(int xStart, int yStart, int xSpeed, int ySpeed); + int SigNumber(int number); +}; diff --git a/UIAutomator/type.h b/UIAutomator/type.h new file mode 100644 index 0000000..db0a4a8 --- /dev/null +++ b/UIAutomator/type.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef __TYPE_H_ +#define __TYPE_H_ + +#include +#include + +const std::string EVENT_CLICK = "click"; +const std::string EVENT_UP = "up"; +const std::string EVENT_DOWN = "down"; +const std::string EVENT_MOVE = "move"; +const std::string EVENT_LONGPRESS = "longPress"; +const std::string EVENT_FLICK = "flick"; +const std::string EVENT_SWIPE = "swipe"; + +const std::string EVENT_INPUTTEXT = "inputText"; + +const std::string EVENT_HOME = "home"; +const std::string EVENT_BACK = "back"; +const std::string EVENT_PHONE = "phone"; +const std::string EVENT_POWER = "power"; +const std::string EVENT_VOLUMEDOWN = "volumeDown"; +const std::string EVENT_VOLUMEUP = "volumeUp"; + +#endif /* __TYPE_H_ */ diff --git a/packaging/uiautomator.rule b/packaging/uiautomator.rule new file mode 100755 index 0000000..359ffe7 --- /dev/null +++ b/packaging/uiautomator.rule @@ -0,0 +1,2 @@ +uiautomator system::use_internet rw +system::use_internet uiautomator rw \ No newline at end of file diff --git a/packaging/uiautomator.spec b/packaging/uiautomator.spec new file mode 100755 index 0000000..124bd12 --- /dev/null +++ b/packaging/uiautomator.spec @@ -0,0 +1,50 @@ +Name: uiautomator +Summary: UIAutomator Service +Version: 0.1.1 +Release: 1 +Group: Framework/system +License: Apache +Source0: %{name}-%{version}.tar.gz + +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(gobject-2.0) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(gthread-2.0) +BuildRequires: pkgconfig(jsoncpp) +BuildRequires: pkgconfig(edbus) +BuildRequires: pkgconfig(systemd) +BuildRequires: cmake +BuildRequires: boost-devel +BuildRequires: pkgconfig(edbus) + +Requires(preun): /usr/bin/systemctl +Requires(post): /usr/bin/systemctl +Requires(postun): /usr/bin/systemctl + +%description +UIAutomator Service + +%prep +%setup -q + +%build +export CFLAGS+=" -fPIC" +export LDFLAGS+="-Wl,--rpath=%{PREFIX} -Wl,--as-needed" + +cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} UIAutomator + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%files -n uiautomator +%{_bindir}/uiautomator +%{_datadir}/license/uiautomator +%{_sysconfdir}/smack/accesses.d/uiautomator.rule +%manifest uiautomator.manifest \ No newline at end of file diff --git a/uiautomator.manifest b/uiautomator.manifest new file mode 100644 index 0000000..b532166 --- /dev/null +++ b/uiautomator.manifest @@ -0,0 +1,5 @@ + + + + + -- 2.34.1