Init UIAutomator 81/178481/4 accepted/tizen/unified/20180511.172249 submit/tizen/20180511.002243
authorRinaYou <rina6350.you@samsung.com>
Thu, 10 May 2018 06:52:53 +0000 (15:52 +0900)
committershyun.min <shyun.min@samsung.com>
Thu, 10 May 2018 09:48:43 +0000 (18:48 +0900)
Change-Id: I1c00b55cd7091adb71c800015e9065727c8c5bb0

20 files changed:
LICENSE [new file with mode: 0644]
UIAutomator/CMakeLists.txt [new file with mode: 0644]
UIAutomator/dbus.cpp [new file with mode: 0644]
UIAutomator/dbus.h [new file with mode: 0755]
UIAutomator/hardware_key.cpp [new file with mode: 0644]
UIAutomator/hardware_key.h [new file with mode: 0644]
UIAutomator/input_generator.cpp [new file with mode: 0644]
UIAutomator/input_generator.h [new file with mode: 0644]
UIAutomator/keyboard.cpp [new file with mode: 0644]
UIAutomator/keyboard.h [new file with mode: 0644]
UIAutomator/log.h [new file with mode: 0755]
UIAutomator/main.cpp [new file with mode: 0755]
UIAutomator/server.cpp [new file with mode: 0644]
UIAutomator/server.h [new file with mode: 0644]
UIAutomator/touch.cpp [new file with mode: 0644]
UIAutomator/touch.h [new file with mode: 0644]
UIAutomator/type.h [new file with mode: 0644]
packaging/uiautomator.rule [new file with mode: 0755]
packaging/uiautomator.spec [new file with mode: 0755]
uiautomator.manifest [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
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 (file)
index 0000000..f53e110
--- /dev/null
@@ -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 (file)
index 0000000..d5550d5
--- /dev/null
@@ -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 <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;
+}
diff --git a/UIAutomator/dbus.h b/UIAutomator/dbus.h
new file mode 100755 (executable)
index 0000000..4cbdd19
--- /dev/null
@@ -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 <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_
diff --git a/UIAutomator/hardware_key.cpp b/UIAutomator/hardware_key.cpp
new file mode 100644 (file)
index 0000000..0cbf577
--- /dev/null
@@ -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 (file)
index 0000000..2e19124
--- /dev/null
@@ -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 (file)
index 0000000..ab184b0
--- /dev/null
@@ -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 (file)
index 0000000..e2e77b0
--- /dev/null
@@ -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 <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_ */
diff --git a/UIAutomator/keyboard.cpp b/UIAutomator/keyboard.cpp
new file mode 100644 (file)
index 0000000..687e2d6
--- /dev/null
@@ -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<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['?'] = '/';
+}
diff --git a/UIAutomator/keyboard.h b/UIAutomator/keyboard.h
new file mode 100644 (file)
index 0000000..d610a21
--- /dev/null
@@ -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 <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();
+};
diff --git a/UIAutomator/log.h b/UIAutomator/log.h
new file mode 100755 (executable)
index 0000000..e69eae3
--- /dev/null
@@ -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 <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_ */
diff --git a/UIAutomator/main.cpp b/UIAutomator/main.cpp
new file mode 100755 (executable)
index 0000000..a5d70bf
--- /dev/null
@@ -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 <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;
+}
diff --git a/UIAutomator/server.cpp b/UIAutomator/server.cpp
new file mode 100644 (file)
index 0000000..e1f5cd2
--- /dev/null
@@ -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 <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));
+}
diff --git a/UIAutomator/server.h b/UIAutomator/server.h
new file mode 100644 (file)
index 0000000..c3758b9
--- /dev/null
@@ -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 <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_ */
diff --git a/UIAutomator/touch.cpp b/UIAutomator/touch.cpp
new file mode 100644 (file)
index 0000000..ce45f3c
--- /dev/null
@@ -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 (file)
index 0000000..297dcef
--- /dev/null
@@ -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 <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);
+};
diff --git a/UIAutomator/type.h b/UIAutomator/type.h
new file mode 100644 (file)
index 0000000..db0a4a8
--- /dev/null
@@ -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 <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_ */
diff --git a/packaging/uiautomator.rule b/packaging/uiautomator.rule
new file mode 100755 (executable)
index 0000000..359ffe7
--- /dev/null
@@ -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 (executable)
index 0000000..124bd12
--- /dev/null
@@ -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 (file)
index 0000000..b532166
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <define>
+        <domain name="uiautomator"/>
+    </define>
+</manifest>