--- /dev/null
+
+ 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
--- /dev/null
+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} )
--- /dev/null
+/*
+ * 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 <iostream>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <set>
+#include <list>
+#include <algorithm>
+#include <functional>
+#include <boost/tokenizer.hpp>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <E_DBus.h>
+
+#include "log.h"
+#include "server.h"
+#include "dbus.h"
+
+#define DBUS_REPLY_TIMEOUT (-1)
+
+using namespace boost;
+using namespace std;
+
+vector<SignalHandler> 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;
+}
--- /dev/null
+/*
+ * 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 <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <functional>
+#include <dbus/dbus.h>
+#include <E_DBus.h>
+
+using namespace std;
+
+typedef std::function<void(void *data, DBusMessage *msg)> 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<SignalHandler> SignalVector;
+};
+
+#endif // _DBUS_UTILS_H_
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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();
+};
--- /dev/null
+/*
+ * 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");
+ }
+}
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+#include <string>
+#include <string.h>
+
+#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_ */
--- /dev/null
+/*
+ * 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<char, int>::iterator k;
+ map<char, char>::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<char, int> 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['?'] = '/';
+}
--- /dev/null
+/*
+ * 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 <map>
+
+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<char, int> keyMap;
+ map<char, char> keyMapSecondary;
+
+ int ConvertKeyCode(char key_code);
+
+ bool SetKeyCodes();
+ void SetKeyMaps();
+};
--- /dev/null
+/*
+ * 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 <dlog.h>
+
+#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_ */
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Ecore.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <Ecore.h>
+
+#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));
+}
--- /dev/null
+/*
+ * 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 <map>
+#include <string>
+#include <Ecore.h>
+#include <functional>
+#include <condition_variable>
+
+#include "hardware_key.h"
+#include "keyboard.h"
+#include "touch.h"
+
+using namespace std;
+
+typedef std::function<void(char* first, char* second)> 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<string, CommandHandler> HandlerMap;
+ private:
+ Touch touch;
+ Keyboard keyboard;
+ HardWareKey hardwareKey;
+};
+
+#endif /* __SERVER_H_ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 <tgmath.h>
+#include <algorithm>
+
+#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);
+};
--- /dev/null
+/*
+ * 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 <iostream>
+#include <string>
+
+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_ */
--- /dev/null
+uiautomator system::use_internet rw
+system::use_internet uiautomator rw
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+<manifest>
+ <define>
+ <domain name="uiautomator"/>
+ </define>
+</manifest>