diff options
author | Jingjing Liu <jingjingliu@google.com> | 2016-11-08 10:55:03 -0800 |
---|---|---|
committer | Jingjing Liu <jingjingliu@google.com> | 2016-11-08 11:25:08 -0800 |
commit | 0dd4be439821d5925358fbf3e4d456a318eb3df4 (patch) | |
tree | 8a3f277299cf372a0ea88091b2c7aa4c88c2132a /console_test_server | |
parent | 1d13eb735d77b17c84f69d86d637a8ec635310c4 (diff) | |
download | adt-infra-0dd4be439821d5925358fbf3e4d456a318eb3df4.tar.gz |
Refactor console test code
1) move the event testing data to utils/constants directory
2) move REST service for console tests out
3) update related python files duo to the above changes
test tracker doc: go/adt-consoletest-tracker
Test: run all console test cases by command "python emu_test/dotest.py -l DEBUG -n "Ubuntu 12.04 HD Graphics 4000" -c emu_test/config/console_cfg.csv -p "test_console.*" --skip-adb-perf -f '{"gpu":"yes"}'", passed
Change-Id: I8a419a89ab46bc9456fedb981217ced5200dda02
Diffstat (limited to 'console_test_server')
41 files changed, 1704 insertions, 0 deletions
diff --git a/console_test_server/Server.iml b/console_test_server/Server.iml new file mode 100644 index 00000000..54de7e02 --- /dev/null +++ b/console_test_server/Server.iml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module external.linked.project.id="Server" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4"> + <component name="FacetManager"> + <facet type="java-gradle" name="Java-Gradle"> + <configuration> + <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" /> + <option name="BUILDABLE" value="false" /> + </configuration> + </facet> + </component> + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <excludeFolder url="file://$MODULE_DIR$/.gradle" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module>
\ No newline at end of file diff --git a/console_test_server/app/build.gradle b/console_test_server/app/build.gradle new file mode 100644 index 00000000..da72cacc --- /dev/null +++ b/console_test_server/app/build.gradle @@ -0,0 +1,35 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.3" + + defaultConfig { + applicationId "com.android.devtools.server" + minSdkVersion 18 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile 'com.android.support:appcompat-v7:23.+' + compile 'com.android.support:support-annotations:+' + compile 'com.android.support.test.uiautomator:uiautomator-v18:+' + compile 'com.android.support.test:runner:+' + compile 'com.android.support.test:rules:+' + compile 'com.google.guava:guava:+' + compile 'org.hamcrest:hamcrest-library:1.3' + compile group: 'org.mortbay.jetty', name: 'jetty', version: '6.1.22' + compile group: 'com.google.code.gson', name: 'gson', version: '2.3.1' + +} diff --git a/console_test_server/app/proguard-rules.pro b/console_test_server/app/proguard-rules.pro new file mode 100644 index 00000000..fdadc4b2 --- /dev/null +++ b/console_test_server/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /usr/local/google/home/jesikmin/Android/Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/console_test_server/app/src/androidTest/java/com/android/devtools/server/Server.java b/console_test_server/app/src/androidTest/java/com/android/devtools/server/Server.java new file mode 100644 index 00000000..5dbe217c --- /dev/null +++ b/console_test_server/app/src/androidTest/java/com/android/devtools/server/Server.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ + +package com.android.devtools.server; + +import com.android.devtools.server.http.HttpServer; +import com.android.devtools.server.http.UiAutomatorServlet; +import com.android.devtools.server.services.ServiceLocator; +import com.android.devtools.server.services.SmsManagerService; +import com.android.devtools.server.services.TelephonyManagerService; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import android.app.Instrumentation; +import android.content.Context; +import android.os.RemoteException; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.Until; +import android.util.Log; +import java.util.HashMap; +import java.util.Map; + +/** + * InstrumentationTestCase for launching servlet on emulator and use Android SDK. + */ +@RunWith(AndroidJUnit4.class) +public class Server { + private final Instrumentation mInstrumentation = + InstrumentationRegistry.getInstrumentation(); + private final UiDevice mDevice = UiDevice.getInstance(mInstrumentation); + private final Context mContext = mInstrumentation.getTargetContext(); + + @Before + public void setUp() throws RemoteException { + if (!mDevice.isScreenOn()) { + mDevice.wakeUp(); + mDevice.wait(Until.hasObject(By.res("android", "glow_pad_view")), 10000); + mDevice.swipe(560, 1500, 560, 1000, 40); + } + mDevice.pressHome(); + } + + @Test + public void testLaunchTestServer() { + Map<Class<?>, String> servletUrlMapping = new HashMap<>(1); + servletUrlMapping.put(UiAutomatorServlet.class, "/"); + HttpServer server = + new HttpServer.HttpServerBuilder() + .withServer(new org.mortbay.jetty.Server()) + .withAcceptors(10) + .withMaxIdleTime(1000) + .withPort(8081) + .withSoLingerTime(-1) + .withServletUrlPathMapping(servletUrlMapping) + .build(); + registerService(); + try { + server.start(); + } catch (Exception e) { + Log.e(this.getClass().getName(), e.getMessage()); + } + } + + private void registerService() { + ServiceLocator.register(new TelephonyManagerService(mContext)); + ServiceLocator.register(new SmsManagerService(mContext)); + } +} diff --git a/console_test_server/app/src/main/AndroidManifest.xml b/console_test_server/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..2c61bd9d --- /dev/null +++ b/console_test_server/app/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.devtools.server"> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> + <uses-permission android:name="android.permission.BLUETOOTH"/> + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> + <uses-permission android:name="android.permission.READ_SMS"/> + +</manifest> diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/Readme.md b/console_test_server/app/src/main/java/com/android/devtools/server/Readme.md new file mode 100644 index 00000000..0599fc2e --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/Readme.md @@ -0,0 +1,10 @@ +# Description: + Android instrumentation test application that launches servlet on Android emulator. + Set up console tests (e.g. GSM call test) via REST service. +## HOWTO: + ./gradlew assemble ("gradle.bat assemble" for windows) + adb install -r app/build/outputs/apk/app-debug.apk + ./gradlew assembleAndroidTest ("gradle.bat" assembleAndroidTest for windows) + adb install -r app/build/outputs/apk/app-debug-androidTest-unaligned.apk + adb shell am instrument -w -e class com.android.devtools.server.Server com.android.devtools.server.test/android.support.test.runner.AndroidJUnitRunner + adb -s emulator-5554 -e forward tcp:8080 tcp:8081 diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/http/GetProcessor.java b/console_test_server/app/src/main/java/com/android/devtools/server/http/GetProcessor.java new file mode 100644 index 00000000..bbe8e6b0 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/http/GetProcessor.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.http; + +import com.android.devtools.server.services.ServiceLocator; +import com.android.devtools.server.utils.ErrorHandleUtils; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Handle all HTTP GET request and response. + */ +public class GetProcessor implements HttpMethodsProcessor { + + private final HttpServletRequest req; + private final HttpServletResponse resp; + + public GetProcessor(HttpServletRequest req, HttpServletResponse resp) { + this.req = req; + this.resp = resp; + } + + @Override + public void processRequest() { + assert req.getMethod().equals("GET"); + String path = req.getRequestURI(); + resp.setStatus(HttpServletResponse.SC_OK); + if (path.equals("/help") || path.equals("/")) { + resp.setContentType("text/html"); + writeHelpInfoToResponse(); + } else { + resp.setContentType("application/json"); + renderServicesResponse(path); + } + } + + private void renderServicesResponse(String path) { + if (null == path) { + return; + } + try { + resp.getWriter().print(ServiceLocator.getService(path.substring(1)).execute("")); + } catch (IOException e) { + ErrorHandleUtils.logStacktrace(ErrorHandleUtils.getStacktrace(e), "GET"); + } + } + + private void writeHelpInfoToResponse() { + try { + resp.getWriter().println(ServiceLocator.getServices()); + } catch (IOException e) { + ErrorHandleUtils.logStacktrace(ErrorHandleUtils.getStacktrace(e), "GET"); + } + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/http/HttpMethodsProcessor.java b/console_test_server/app/src/main/java/com/android/devtools/server/http/HttpMethodsProcessor.java new file mode 100644 index 00000000..176f869f --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/http/HttpMethodsProcessor.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.http; + +/** + * Interface for handling Http Request and Http Response. + */ +public interface HttpMethodsProcessor { + void processRequest(); +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/http/HttpServer.java b/console_test_server/app/src/main/java/com/android/devtools/server/http/HttpServer.java new file mode 100644 index 00000000..fb4b9adf --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/http/HttpServer.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.http; + +import org.mortbay.jetty.Server; +import org.mortbay.jetty.handler.ContextHandler; +import org.mortbay.jetty.nio.SelectChannelConnector; +import org.mortbay.jetty.servlet.HashSessionManager; +import org.mortbay.jetty.servlet.ServletHandler; +import org.mortbay.jetty.servlet.SessionHandler; + +import java.util.Map; + +/** + * <p>Http Server Implementation.</p> <p> It is the place to register servlet.</p> + */ +public class HttpServer { + + private static final String SERVER_CONTEXT_PATH = "/"; + private final int port; + private final int acceptors; + private final int maxIdleTime; + private final int soLingerTime; + private final Map<Class<?>, String> servletUrlPathMapping; + private Server server; + + private HttpServer(final Server server, final int port, final int acceptors, + final int maxIdleTime, + final int soLingerTime, final Map<Class<?>, String> servletUrlPathMapping) { + this.server = server; + this.port = port; + this.acceptors = acceptors; + this.maxIdleTime = maxIdleTime; + this.soLingerTime = soLingerTime; + this.servletUrlPathMapping = servletUrlPathMapping; + } + + public void start() throws Exception { + configureServer(); + server.start(); + server.join(); + } + + private void configureServer() { + ServletHandler servletHandler = setServletHandler(); + setSelectChannelConnector(); + SessionHandler sessionsHandler = setSessionHandler(servletHandler); + setSessionHandler(sessionsHandler); + } + + private void setSessionHandler(SessionHandler sessionsHandler) { + ContextHandler contextHandler = new ContextHandler(SERVER_CONTEXT_PATH); + contextHandler.setHandler(sessionsHandler); + server.setHandler(contextHandler); + } + + private SessionHandler setSessionHandler(ServletHandler servletHandler) { + HashSessionManager manager = new HashSessionManager(); + SessionHandler sessionsHandler = new SessionHandler(manager); + sessionsHandler.setHandler(servletHandler); + return sessionsHandler; + } + + private void setSelectChannelConnector() { + SelectChannelConnector connector = new SelectChannelConnector(); + connector.setPort(port); + connector.setAcceptors(acceptors); + connector.setMaxIdleTime(maxIdleTime); + connector.setSoLingerTime(soLingerTime); + server.addConnector(connector); + } + + private ServletHandler setServletHandler() { + ServletHandler servletHandler = new ServletHandler(); + for (Class<?> servlet : servletUrlPathMapping.keySet()) { + servletHandler.addServletWithMapping(servlet, servletUrlPathMapping.get(servlet)); + } + return servletHandler; + } + + public void stop() throws Exception { + if (server != null) { + server.stop(); + server = null; + } + } + + /** + * A builder for creating HttpServer. + */ + public static class HttpServerBuilder { + + private int port; + private int acceptors; + private int maxIdleTime; + private int soLingerTime; + private Map<Class<?>, String> servletUrlPathMapping; + private Server server; + + public HttpServer build() { + checkServletMappingNullOrEmpty(servletUrlPathMapping); + return new HttpServer(server, port, acceptors, maxIdleTime, soLingerTime, + servletUrlPathMapping); + } + + public HttpServerBuilder withServer(final Server server) { + this.server = server; + return this; + } + + public HttpServerBuilder withPort(final int port) { + this.port = port; + return this; + } + + public HttpServerBuilder withAcceptors(final int acceptors) { + this.acceptors = acceptors; + return this; + } + + public HttpServerBuilder withMaxIdleTime(final int maxIdleTime) { + this.maxIdleTime = maxIdleTime; + return this; + } + + public HttpServerBuilder withSoLingerTime(final int soLingerTime) { + this.soLingerTime = soLingerTime; + return this; + } + + public HttpServerBuilder withServletUrlPathMapping( + final Map<Class<?>, String> servletUrlPathMapping) { + checkServletMappingNullOrEmpty(servletUrlPathMapping); + this.servletUrlPathMapping = servletUrlPathMapping; + return this; + } + + private void checkServletMappingNullOrEmpty(Map<Class<?>, String> servletUrlPathMapping) { + if (null == servletUrlPathMapping) { + throw new RuntimeException("servletUrlPathMapping should not be null"); + } + } + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/http/PostProcessor.java b/console_test_server/app/src/main/java/com/android/devtools/server/http/PostProcessor.java new file mode 100644 index 00000000..cc8d6c25 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/http/PostProcessor.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.http; + +import com.android.devtools.server.model.Result; +import com.android.devtools.server.services.ServiceLocator; +import com.android.devtools.server.utils.ErrorHandleUtils; +import com.google.gson.Gson; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Handle all HTTP POST request and response. + */ +public class PostProcessor implements HttpMethodsProcessor { + + private final HttpServletRequest req; + private final HttpServletResponse resp; + + public PostProcessor(HttpServletRequest req, HttpServletResponse resp) { + this.req = req; + this.resp = resp; + } + + @Override + public void processRequest() { + assert req.getMethod().equals("POST"); + resp.setContentType("application/json"); + StringBuilder reqBody = new StringBuilder(); + try { + consumeRequestBody(reqBody); + } catch (IOException e) { + ErrorHandleUtils.logStacktrace(ErrorHandleUtils.getStacktrace(e), "POST"); + } + String stacktrace = null; + try { + resp.getWriter().print( + ServiceLocator.getService(req.getRequestURI().substring(1)).execute(reqBody.toString())); + } catch (Exception e) { + stacktrace = ErrorHandleUtils.getStacktrace(e); + ErrorHandleUtils.logStacktrace(stacktrace, "POST"); + } finally { + try { + if (null != stacktrace) { + resp.getWriter().print(new Gson() + .toJson(new Result().setIsFail(true).setDescription(stacktrace))); + } + resp.getWriter().flush(); + resp.getWriter().close(); + } catch (IOException e) { + ErrorHandleUtils.logStacktrace(ErrorHandleUtils.getStacktrace(e), "POST"); + } + } + } + + private void consumeRequestBody(StringBuilder reqBody) throws IOException { + String line; + while (null != (line = req.getReader().readLine())) { + reqBody.append(line); + } + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/http/UiAutomatorServlet.java b/console_test_server/app/src/main/java/com/android/devtools/server/http/UiAutomatorServlet.java new file mode 100644 index 00000000..ffe970ff --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/http/UiAutomatorServlet.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.http; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Servlet for dispacthing HTTP Request by different HTTP method. + */ +public class UiAutomatorServlet extends HttpServlet { + public UiAutomatorServlet() {} + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + processRequest(new GetProcessor(req, resp)); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + processRequest(new PostProcessor(req, resp)); + } + + public void processRequest(final HttpMethodsProcessor processor) { + processor.processRequest(); + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/Action.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/Action.java new file mode 100644 index 00000000..f22ba6f3 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/Action.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; + +/** + * Json model for POST + */ +public abstract class Action { + private UiModel ui; + + public UiModel getUi() { + return ui; + } + + public void setUi(UiModel ui) { + this.ui = ui; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/Clazz.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/Clazz.java new file mode 100644 index 00000000..01088cd0 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/Clazz.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; + +/** + * Model for class selector. + */ +public class Clazz { + + private String classNameWithoutPackage; + private String packageName; + + public String getClassNameWithoutPackage() { + return classNameWithoutPackage; + } + + public void setClassNameWithoutPackage(String classNameWithoutPackage) { + this.classNameWithoutPackage = classNameWithoutPackage; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + @Override + public String toString() { + StringBuilder stringBuilder = + new StringBuilder(packageName).append(".").append(classNameWithoutPackage); + return stringBuilder.toString(); + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/PackageModel.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/PackageModel.java new file mode 100644 index 00000000..3f1c6d32 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/PackageModel.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; + +/** + * Json model for By.pkg. + */ +public class PackageModel { + private final String packageName; + + public PackageModel(String packageName) { + this.packageName = packageName; + } + + public String getPackageName() { + return packageName; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/Point.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/Point.java new file mode 100644 index 00000000..8000c507 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/Point.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; + +/** + * Json model for a location at android ui. + */ +public class Point { + private int x; + private int y; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/RestServiceModel.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/RestServiceModel.java new file mode 100644 index 00000000..5468e0c2 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/RestServiceModel.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; + +/** + * Model for describe a rest service endpoint. + */ +public class RestServiceModel { + + private final String method; + private final String path; + private final String body; + + public RestServiceModel(String method, String path, String body) { + this.method = method; + this.path = path; + this.body = body; + } + + public String getMethod() { + return method; + } + + public String getPath() { + return path; + } + + public String getBody() { + return body; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/Result.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/Result.java new file mode 100644 index 00000000..96476ca4 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/Result.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ + +package com.android.devtools.server.model; + +/** + * Json model for HTTP response. + */ +public class Result { + private boolean isFail; + private String description; + private String requestBody; + private String windowHierarchy; + private String smsAddress; + private String smsTextMessage; + + public boolean isFail() { + return isFail; + } + + public Result setIsFail(boolean isFail) { + this.isFail = isFail; + return this; + } + + public String getDescription() { + return description; + } + + public Result setDescription(String description) { + this.description = description; + return this; + } + + public String getRequestBody() { + return requestBody; + } + + public Result setRequestBody(String requestBody) { + this.requestBody = requestBody; + return this; + } + + public String getWindowHierarchy() { + return windowHierarchy; + } + + public Result setWindowHierarchy(String windowHierarchy) { + this.windowHierarchy = windowHierarchy; + return this; + } + + public String getSmsAddress() { + return smsAddress; + } + + public Result setSmsAddress(String smsAddress) { + this.smsAddress = smsAddress; + return this; + } + + public String getSmsTextMessage() { + return smsTextMessage; + } + + public Result setSmsTextMessage(String smsTextMessage) { + this.smsTextMessage = smsTextMessage; + return this; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/SmsManagerModel.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/SmsManagerModel.java new file mode 100644 index 00000000..4b99a585 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/SmsManagerModel.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ + +package com.android.devtools.server.model; + +import com.google.gson.Gson; + +/** + * Representation model for SMS manager services. + */ +public class SmsManagerModel { + private final String action; + + public SmsManagerModel(String action) { + this.action = action; + } + + @Override + public String toString() { + return new Gson().toJson(this); + } + + public String getAction() { + return action; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/TelephonyManagerModel.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/TelephonyManagerModel.java new file mode 100644 index 00000000..2eb6e4e1 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/TelephonyManagerModel.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; + +import com.google.gson.Gson; + +/** + * Representation model for Wifi manager services. + */ +public class TelephonyManagerModel { + + private final String action; + + public TelephonyManagerModel(String action) { + this.action = action; + } + + @Override + public String toString() { + return new Gson().toJson(this); + } + + public String getAction() { + return action; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/model/UiModel.java b/console_test_server/app/src/main/java/com/android/devtools/server/model/UiModel.java new file mode 100644 index 00000000..288322af --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/model/UiModel.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.model; +/** + * Json model for ui selector. + */ +public class UiModel { + + private String res; + private Clazz uiElementClass; + private String description; + private String text; + private int index; + private int depth; + + public int getDepth() { + return depth; + } + + public void setDepth(int depth) { + this.depth = depth; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRes() { + return res; + } + + public void setRes(String res) { + this.res = res; + } + + public Clazz getUiElementClass() { + return uiElementClass; + } + + public void setUiElementClass(Clazz uiElementClass) { + this.uiElementClass = uiElementClass; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/services/Service.java b/console_test_server/app/src/main/java/com/android/devtools/server/services/Service.java new file mode 100644 index 00000000..3ce72af5 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/services/Service.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.services; + +import java.io.IOException; + +/** + * Part of Service Locator design pattern, a interface for all services. + */ +public interface Service { + + static final String GET = "GET"; + static final String POST = "POST"; + static final String EMPTY_BODY = "{}"; + + long MAX_WAIT_TIME = 8000; + + String execute(String json) throws IOException; +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/services/ServiceBase.java b/console_test_server/app/src/main/java/com/android/devtools/server/services/ServiceBase.java new file mode 100644 index 00000000..b1ab421e --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/services/ServiceBase.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.services; + +import com.android.devtools.server.model.Result; +import com.android.devtools.server.model.UiModel; +import com.google.gson.Gson; + +import android.support.test.uiautomator.UiDevice; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +/** + * A parent class for all services. The idea is to provide share function for all services. + */ +public abstract class ServiceBase implements Service { + + protected final UiDevice mDevice; + protected final ByteArrayOutputStream outStream; + + protected ServiceBase(UiDevice mDevice) { + assert null != mDevice; + this.mDevice = mDevice; + this.outStream = new ByteArrayOutputStream(); + } + + protected boolean isUseText(UiModel ui) { + return null != ui.getText() && !ui.getText().isEmpty(); + } + + protected boolean isUseClass(UiModel ui) { + return null != ui.getUiElementClass(); + } + + protected boolean isUseResourceId(UiModel ui) { + return null != ui.getRes() && !ui.getRes().isEmpty(); + } + + protected boolean isUsingDescription(UiModel ui) { + return null != ui.getDescription() + && !ui.getDescription().isEmpty(); + } + + protected String getWidnowsHierachy() { + try { + mDevice.dumpWindowHierarchy(outStream); + } catch (IOException e) { + writeErrorToOutStream(e); + } + try { + return outStream.toString(Charset.forName("UTF-8").displayName()); + } catch (UnsupportedEncodingException e) { + logException(e); + } + return outStream.toString(); + } + + protected String foundInvalidRequestBody(Result result) { + result.setIsFail(true).setDescription("Unable deserialize request body"); + return new Gson().toJson(result); + } + + private void logException(Exception e) { + Log.e("Service Error", e.getCause().toString()); + } + + private void writeErrorToOutStream(IOException e) { + try { + outStream.write(e.getCause().toString().getBytes(Charset.defaultCharset())); + } catch (IOException e1) { + logException(e); + } + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/services/ServiceLocator.java b/console_test_server/app/src/main/java/com/android/devtools/server/services/ServiceLocator.java new file mode 100644 index 00000000..a25e020c --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/services/ServiceLocator.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.services; + +import android.util.Log; + +import java.util.HashMap; +import java.util.Map; + +/** + * Service Locator design pattern. + */ +public final class ServiceLocator { + + private static final Map<String, Service> serviceProvider = new HashMap<>(); + + public static void register(Service service) { + serviceProvider.put(service.getClass().getSimpleName(), service); + } + + public static Service getService(String name) { + return serviceProvider.get(name); + } + + public static String getServices() { + StringBuilder sb = new StringBuilder(); + for (Service service : serviceProvider.values()){ + Log.d("hihi", service.toString()); + sb.append("<p>").append(service.toString()).append("</p>"); + } + return sb.toString(); + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/services/SmsManagerService.java b/console_test_server/app/src/main/java/com/android/devtools/server/services/SmsManagerService.java new file mode 100644 index 00000000..2f56c519 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/services/SmsManagerService.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ + +package com.android.devtools.server.services; + +import com.android.devtools.server.model.Result; +import com.android.devtools.server.model.RestServiceModel; +import com.android.devtools.server.model.SmsManagerModel; +import com.google.gson.Gson; + +import java.io.IOException; + +import android.content.Context; +import android.content.ContentResolver; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +/** + * Service for reading sms. + */ +public class SmsManagerService implements Service { + + private static final String TAG = SmsManagerService.class.getSimpleName(); + private static final String SMS_INBOX_URI = "content://sms/inbox"; + private static final String SMS_ADDRESS_COLUMN = "address"; + private static final String SMS_BODY_COLUMN = "body"; + private static final String SMS_SERVICE_PATH = "/SmsManagerService"; + private static final String ACTION = "String"; + private final Context mContext; + + public SmsManagerService(Context context) { + mContext = context; + } + + @Override + public String execute(String json) throws IOException { + boolean isSuccess = false; + Result result = new Result(); + + SmsManagerModel smsModel = new Gson().fromJson(json, SmsManagerModel.class); + if (smsModel == null) { + Log.e(TAG, "SmsManagerModel is null. Invalid POST Request body: " + json); + result.setIsFail(true); + result.setDescription("Invalid POST Request Body"); + return new Gson().toJson(result); + } + + Uri smsQueryUri = Uri.parse(SMS_INBOX_URI); + ContentResolver contentResolver = mContext.getContentResolver(); + Cursor cursor = null; + + try { + cursor = contentResolver.query(smsQueryUri, null, null, null, null); + + if (cursor == null) { + final String CURSOR_IS_NULL = "cursor is null."; + Log.i(TAG, CURSOR_IS_NULL + " uri: " + smsQueryUri); + result.setIsFail(!isSuccess); + return new Gson().toJson(CURSOR_IS_NULL + " uri: " + smsQueryUri); + } + + if(cursor.moveToFirst()) { + for(String s : cursor.getColumnNames()){ + Log.d(TAG + "smsColumns", "Column: " + s); + } + + final String address = cursor.getString( + cursor.getColumnIndexOrThrow(SMS_ADDRESS_COLUMN)); + result.setSmsAddress(address); + final String body = cursor.getString( + cursor.getColumnIndexOrThrow(SMS_BODY_COLUMN)); + result.setSmsTextMessage(body); + + isSuccess = true; + } + } catch (NullPointerException npe) { + Log.e(TAG, npe.getMessage()); + isSuccess = false; + result.setDescription(Log.getStackTraceString(npe)); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + isSuccess = false; + result.setDescription(Log.getStackTraceString(e)); + } finally { + cursor.close(); + } + + result.setIsFail(!isSuccess); + return new Gson().toJson(result); + } + + @Override + public String toString() { + return new Gson() + .toJson( + new RestServiceModel( + POST, + SMS_SERVICE_PATH, + new SmsManagerModel(ACTION).toString())); + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/services/TelephonyManagerService.java b/console_test_server/app/src/main/java/com/android/devtools/server/services/TelephonyManagerService.java new file mode 100644 index 00000000..c38ec790 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/services/TelephonyManagerService.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.services; + +import android.content.Context; +import android.telephony.TelephonyManager; +import android.util.Log; +import com.android.devtools.server.model.RestServiceModel; +import com.android.devtools.server.model.Result; +import com.android.devtools.server.model.TelephonyManagerModel; +import com.google.gson.Gson; +import java.io.IOException; + +/** + * Service for phone(calling status) of phone. + */ +public class TelephonyManagerService implements Service { + + private static final String TAG = TelephonyManagerService.class.getSimpleName(); + private TelephonyManager telephonyManager = null; + private Result result = new Result(); + + public TelephonyManagerService(Context c) { + telephonyManager = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE); + } + + @Override + public String execute(String json) throws IOException { + boolean isSuccess = false; + + TelephonyManagerModel telephonyModel = new Gson().fromJson(json, TelephonyManagerModel.class); + if (telephonyModel == null) { + Log.e(TAG, "TelephonyManagerModel null. Invalid POST Request body: " + json); + result.setIsFail(true); + result.setDescription("Invalid POST Request Body"); + return new Gson().toJson(result); + } + int callState = telephonyManager.getCallState(); + switch (callState) { + case TelephonyManager.CALL_STATE_IDLE: + case TelephonyManager.CALL_STATE_OFFHOOK: + case TelephonyManager.CALL_STATE_RINGING: + isSuccess = true; + result.setDescription(Integer.toString(callState)); + break; + default: + Log.e(TAG, "Invalid Action specified in POST Request"); + isSuccess = false; + result.setDescription("Unknown Action specified in request."); + } + result.setIsFail(!isSuccess); + return new Gson().toJson(result); + } + + @Override + public String toString() { + return new Gson() + .toJson( + new RestServiceModel( + POST, "/TelephonyManagerService", new TelephonyManagerModel("String").toString())); + } +} diff --git a/console_test_server/app/src/main/java/com/android/devtools/server/utils/ErrorHandleUtils.java b/console_test_server/app/src/main/java/com/android/devtools/server/utils/ErrorHandleUtils.java new file mode 100644 index 00000000..7d120953 --- /dev/null +++ b/console_test_server/app/src/main/java/com/android/devtools/server/utils/ErrorHandleUtils.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * 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. + */ +package com.android.devtools.server.utils; + +import android.util.Log; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * Utils for error handling + */ +public class ErrorHandleUtils { + + public static void logStacktrace(String stacktrace, String httpMethod){ + Log.e(httpMethod, stacktrace); + } + + public static String getStacktrace(Throwable t){ + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter(sWriter); + t.printStackTrace(pWriter); + return sWriter.toString(); + } + +} diff --git a/console_test_server/app/src/main/res/mipmap-hdpi/ic_launcher.png b/console_test_server/app/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..cde69bcc --- /dev/null +++ b/console_test_server/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/console_test_server/app/src/main/res/mipmap-mdpi/ic_launcher.png b/console_test_server/app/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..c133a0cb --- /dev/null +++ b/console_test_server/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/console_test_server/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/console_test_server/app/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..bfa42f0e --- /dev/null +++ b/console_test_server/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/console_test_server/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/console_test_server/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..324e72cd --- /dev/null +++ b/console_test_server/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/console_test_server/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/console_test_server/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 00000000..aee44e13 --- /dev/null +++ b/console_test_server/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/console_test_server/app/src/main/res/values/colors.xml b/console_test_server/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..3ab3e9cb --- /dev/null +++ b/console_test_server/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#3F51B5</color> + <color name="colorPrimaryDark">#303F9F</color> + <color name="colorAccent">#FF4081</color> +</resources> diff --git a/console_test_server/app/src/main/res/values/strings.xml b/console_test_server/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..a381ffb7 --- /dev/null +++ b/console_test_server/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="app_name">Server</string> +</resources> diff --git a/console_test_server/app/src/main/res/values/styles.xml b/console_test_server/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..5885930d --- /dev/null +++ b/console_test_server/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ +<resources> + + <!-- Base application theme. --> + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <!-- Customize your theme here. --> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> + <item name="colorAccent">@color/colorAccent</item> + </style> + +</resources> diff --git a/console_test_server/build.gradle b/console_test_server/build.gradle new file mode 100644 index 00000000..aff4f415 --- /dev/null +++ b/console_test_server/build.gradle @@ -0,0 +1,23 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.1.2' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/console_test_server/gradle.properties b/console_test_server/gradle.properties new file mode 100644 index 00000000..1d3591c8 --- /dev/null +++ b/console_test_server/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true
\ No newline at end of file diff --git a/console_test_server/gradle/wrapper/gradle-wrapper.jar b/console_test_server/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 00000000..13372aef --- /dev/null +++ b/console_test_server/gradle/wrapper/gradle-wrapper.jar diff --git a/console_test_server/gradle/wrapper/gradle-wrapper.properties b/console_test_server/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..122a0dca --- /dev/null +++ b/console_test_server/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Dec 28 10:00:20 PST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip diff --git a/console_test_server/gradlew b/console_test_server/gradlew new file mode 100755 index 00000000..9d82f789 --- /dev/null +++ b/console_test_server/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/console_test_server/gradlew.bat b/console_test_server/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/console_test_server/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/console_test_server/settings.gradle b/console_test_server/settings.gradle new file mode 100644 index 00000000..e7b4def4 --- /dev/null +++ b/console_test_server/settings.gradle @@ -0,0 +1 @@ +include ':app' |