diff options
author | Jose <jose@zeroc.com> | 2018-09-12 14:48:57 +0200 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2018-09-12 14:48:57 +0200 |
commit | f9801ab21989e330015ffa274493e775671fe865 (patch) | |
tree | 99f7cf77ab7863117aa8ee7f2f8047afc6351d58 /java/test | |
parent | Missing C++ header include (diff) | |
download | ice-f9801ab21989e330015ffa274493e775671fe865.tar.bz2 ice-f9801ab21989e330015ffa274493e775671fe865.tar.xz ice-f9801ab21989e330015ffa274493e775671fe865.zip |
Make test controllers layout more consistent
Close #184
Diffstat (limited to 'java/test')
16 files changed, 1217 insertions, 0 deletions
diff --git a/java/test/android/allTests.py b/java/test/android/allTests.py new file mode 100644 index 00000000000..e3a2fc3d36f --- /dev/null +++ b/java/test/android/allTests.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys +sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "scripts")) + +from Util import runTestsWithPath + +runTestsWithPath(__file__) diff --git a/java/test/android/controller/build.gradle b/java/test/android/controller/build.gradle new file mode 100644 index 00000000000..26678ed7018 --- /dev/null +++ b/java/test/android/controller/build.gradle @@ -0,0 +1,104 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +buildscript { + repositories { + jcenter() + google() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.4' + classpath "gradle.plugin.com.zeroc.gradle.ice-builder:slice:1.4.5" + } +} + +apply plugin: 'com.android.application' +apply plugin: "com.zeroc.gradle.ice-builder.slice" + +slice { + cppConfiguration = this.cppConfiguration + cppPlatform = this.cppPlatform + if(!System.env.ICE_BIN_DIST?.split(" ").find{ it == 'all' || it.contains('java')}) { + iceHome = this.hasProperty('iceHome') ? this.iceHome + : System.getenv("ICE_HOME") != null ? System.env.ICE_HOME : new File("$rootProject.projectDir/../../../..").getCanonicalPath() + } + java { + files = fileTree(dir: "$rootProject.projectDir/../../../../scripts/", includes: ['*.ice']) + } +} + +repositories { + jcenter() + google() +} + +android { + compileSdkVersion ice_compileSdkVersion.toInteger() + + defaultConfig { + applicationId "com.zeroc.testcontroller" + minSdkVersion ice_minSdkVersion.toInteger() + targetSdkVersion ice_targetSdkVersion.toInteger() + multiDexEnabled true // Necessary otherwise we'd exceed the 64K DEX limit. + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + } + + buildTypes { + debug { + // + // Set minifyEnabled to false because the test app loads classes dynamically. + // + minifyEnabled false + } + + release { + // + // Set minifyEnabled to false because the test app loads classes dynamically. + // + minifyEnabled false + } + } +} + +task copyBksTask(type: Copy) { + from "${rootProject.projectDir}/../../../../certs/client.bks" + from "${rootProject.projectDir}/../../../../certs/server.bks" + into "src/main/res/raw" +} +preBuild.dependsOn(copyBksTask) + +clean { + delete("src/main/res/raw/client.bks") + delete("src/main/res/raw/server.bks") +} + +ext.localDependency = { artifact -> + if(project.slice.srcDist || System.env.ICE_BIN_DIST == "cpp") { + return "com.zeroc:${artifact}:${iceVersion}" + } + else { + return files("${rootProject.projectDir}/../../../lib/${artifact}-${iceVersion}.jar") + } +} +dependencies { + implementation localDependency("glacier2") + implementation localDependency("ice") + implementation localDependency("icessl") + implementation localDependency("icediscovery") + implementation localDependency("icebt") + + implementation files("${rootProject.projectDir}/../../../lib/test.jar") + runtimeOnly "org.apache.commons:commons-compress:1.14" +} diff --git a/java/test/android/controller/gradle.properties b/java/test/android/controller/gradle.properties new file mode 100644 index 00000000000..6de9d9d6288 --- /dev/null +++ b/java/test/android/controller/gradle.properties @@ -0,0 +1,74 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +// +// Version used in JAR files +// +iceVersion = 3.7.1 + +// The Android versions used for the Ice build. +ice_compileSdkVersion = 25 +ice_minSdkVersion = 24 +ice_targetSdkVersion = 24 + +// +// Set iceHome to location of Ice installation if Ice was installed in a +// non-standard location. You must use forward slashes in the path, even on +// Windows. +// +// iceHome = + +// +// Set the version of the Ice Builder to use for building. It must be set to debian +// when using the gradle-ice-builder-plugin package on Debian. +// +iceBuilderVersion = 1.4.5 + +// +// Set the builder artifact class path. It must be set to com.zeroc.gradle.ice-builder +// when using the gradle-ice-builder-plugin package. +// +iceBuilderClassPath = gradle.plugin.com.zeroc.gradle.ice-builder + +// +// Set the location of a local Ice Builder for Gradle source directory +// +iceBuilderHome = + +// +// Gradle build properties +// +org.gradle.daemon = true +org.gradle.configureondemand=false + +// +// Package build properties +// +DESTDIR = +appendVersionSuffix = yes +prefix = +debug = true + +// +// Windows specific options +// + +// +// The platform used by the C++ build. Supported values are `x64` and `Win32`. +// This is required to locate the slice2java compiler in the platform-dependent +// directory. +// +cppPlatform = x64 + +// +// The configuration used by the C++ build. Supported values are `Debug` and `Release`. +// This is required to locate the slice2java compiler in the configuration-dependent +// directory. +// +cppConfiguration = Release diff --git a/java/test/android/controller/gradle/wrapper/gradle-wrapper.jar b/java/test/android/controller/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 00000000000..7a3265ee94c --- /dev/null +++ b/java/test/android/controller/gradle/wrapper/gradle-wrapper.jar diff --git a/java/test/android/controller/gradle/wrapper/gradle-wrapper.properties b/java/test/android/controller/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..08a85d50451 --- /dev/null +++ b/java/test/android/controller/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Sep 10 16:52:39 CEST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/java/test/android/controller/gradlew b/java/test/android/controller/gradlew new file mode 100644 index 00000000000..cccdd3d517f --- /dev/null +++ b/java/test/android/controller/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# 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 + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# 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 +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +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" -a "$nonstop" = "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 + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/java/test/android/controller/gradlew.bat b/java/test/android/controller/gradlew.bat new file mode 100644 index 00000000000..f9553162f12 --- /dev/null +++ b/java/test/android/controller/gradlew.bat @@ -0,0 +1,84 @@ +@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 + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@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= + +@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 Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_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=%* + +: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/java/test/android/controller/src/main/AndroidManifest.xml b/java/test/android/controller/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..20a819e4cad --- /dev/null +++ b/java/test/android/controller/src/main/AndroidManifest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.zeroc.testcontroller" + android:versionCode="1" + android:versionName="1.0.0"> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> + <uses-permission android:name="android.permission.BLUETOOTH" /> + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + + <!-- + http://developer.android.com/guide/topics/manifest/uses-sdk-element.html + --> + <application android:icon="@raw/icon" android:label="@string/app_name" android:name="ControllerApp" + android:allowBackup="false"> + <activity android:name="ControllerActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> +</application> +</manifest> diff --git a/java/test/android/controller/src/main/assets/.gitignore b/java/test/android/controller/src/main/assets/.gitignore new file mode 100644 index 00000000000..2cbf86bc394 --- /dev/null +++ b/java/test/android/controller/src/main/assets/.gitignore @@ -0,0 +1 @@ +*.dex diff --git a/java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java b/java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java new file mode 100644 index 00000000000..87919488eaf --- /dev/null +++ b/java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java @@ -0,0 +1,143 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package com.zeroc.testcontroller; + +import java.util.LinkedList; +import android.app.*; +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.content.Intent; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import android.widget.*; +import android.view.View; + +public class ControllerActivity extends ListActivity +{ + private WifiManager _wifiManager; + private WifiManager.MulticastLock _lock; + private LinkedList<String> _output = new LinkedList<String>(); + private ArrayAdapter<String> _outputAdapter; + private ArrayAdapter<String> _ipv4Adapter; + private ArrayAdapter<String> _ipv6Adapter; + + private static final int REQUEST_ENABLE_BT = 1; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + _wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE); + _lock = _wifiManager.createMulticastLock("com.zeroc.testcontroller"); + _lock.acquire(); + } + + @Override + public void onStart() + { + super.onStart(); + + // + // Enable Bluetooth if necessary. + // + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + if(adapter == null) + { + Toast.makeText(this, R.string.no_bluetooth, Toast.LENGTH_SHORT).show(); + setup(false); + } + else if(!adapter.isEnabled()) + { + Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + startActivityForResult(enableIntent, REQUEST_ENABLE_BT); + } + else + { + setup(true); + } + } + + @Override + protected void onActivityResult(int req, int res, Intent data) + { + switch(req) + { + case REQUEST_ENABLE_BT: + { + if(_outputAdapter == null) + { + if(res == Activity.RESULT_OK) + { + setup(true); + } + else + { + Toast.makeText(this, R.string.no_bluetooth, Toast.LENGTH_SHORT).show(); + setup(false); + } + } + break; + } + } + } + + private synchronized void setup(boolean bluetooth) + { + _outputAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, _output); + setListAdapter(_outputAdapter); + final ControllerApp app = (ControllerApp)getApplication(); + final java.util.List<String> ipv4Addresses = app.getAddresses(false); + _ipv4Adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, ipv4Addresses); + Spinner s = (Spinner)findViewById(R.id.ipv4); + s.setAdapter(_ipv4Adapter); + s.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() + { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) + { + app.setIpv4Address(ipv4Addresses.get((int)id)); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) + { + } + }); + s.setSelection(0); + + final java.util.List<String> ipv6Addresses = app.getAddresses(true); + _ipv6Adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, ipv6Addresses); + s = (Spinner)findViewById(R.id.ipv6); + s.setAdapter(_ipv6Adapter); + s.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() + { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) + { + app.setIpv6Address(ipv6Addresses.get((int)id)); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) + { + } + }); + s.setSelection(0); + app.startController(this, bluetooth); + } + + public synchronized void println(String data) + { + _output.add(data); + _outputAdapter.notifyDataSetChanged(); + } +} diff --git a/java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java b/java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java new file mode 100644 index 00000000000..d3582c03d7b --- /dev/null +++ b/java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java @@ -0,0 +1,532 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2018 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package com.zeroc.testcontroller; + +import java.io.*; +import java.util.*; + +import com.zeroc.Ice.Logger; +import com.zeroc.Ice.Communicator; +import com.zeroc.IceInternal.Time; + +import android.os.Build; +import android.util.Log; +import android.app.Application; + +import Test.Common.ProcessControllerRegistryPrx; +import Test.Common.ProcessControllerPrx; + +public class ControllerApp extends Application +{ + private final String TAG = "ControllerApp"; + private ControllerI _controllerI; + private ControllerActivity _activity; + private String _ipv4Address; + private String _ipv6Address; + + static private class TestSuiteBundle + { + @SuppressWarnings("unchecked") + TestSuiteBundle(String name, ClassLoader loader) throws ClassNotFoundException + { + _loader = loader; + _class = (Class<? extends test.TestHelper>)_loader.loadClass(name); + } + + test.TestHelper newInstance() + throws IllegalAccessException, InstantiationException + { + if(_class == null) + { + return null; + } + return _class.newInstance(); + } + + ClassLoader getClassLoader() + { + return _loader; + } + + private String _name; + private ClassLoader _loader; + private Class<? extends test.TestHelper> _class; + } + + class AndroidLogger implements Logger + { + private final String _prefix; + + AndroidLogger(String prefix) + { + _prefix = prefix; + } + + @Override + public void print(String message) + { + Log.d(TAG, message); + } + + @Override + public void trace(String category, String message) + { + Log.v(category, message); + } + + @Override + public void warning(String message) + { + Log.w(TAG, message); + } + + @Override + public void error(String message) + { + Log.e(TAG, message); + } + + @Override + public String getPrefix() + { + return _prefix; + } + + @Override + public Logger cloneWithPrefix(String s) + { + return new AndroidLogger(s); + } + } + + @Override + public void onCreate() + { + super.onCreate(); + com.zeroc.Ice.Util.setProcessLogger(new AndroidLogger("")); + } + + synchronized public void setIpv4Address(String address) + { + _ipv4Address = address; + } + + synchronized public void setIpv6Address(String address) + { + int i = address.indexOf("%"); + _ipv6Address = i == -1 ? address : address.substring(i); + } + + public List<String> getAddresses(boolean ipv6) + { + List<String> addresses = new java.util.ArrayList<String>(); + try + { + java.util.Enumeration<java.net.NetworkInterface> ifaces = java.net.NetworkInterface.getNetworkInterfaces(); + while(ifaces.hasMoreElements()) + { + java.net.NetworkInterface iface = ifaces.nextElement(); + java.util.Enumeration<java.net.InetAddress> addrs = iface.getInetAddresses(); + while(addrs.hasMoreElements()) + { + java.net.InetAddress addr = addrs.nextElement(); + if((ipv6 && addr instanceof java.net.Inet6Address) || + (!ipv6 && !(addr instanceof java.net.Inet6Address))) + { + addresses.add(addr.getHostAddress()); + } + } + } + } + catch(java.net.SocketException ex) + { + } + return addresses; + } + + public synchronized void startController(ControllerActivity activity, boolean bluetooth) + { + _activity = activity; + if(_controllerI == null) + { + _controllerI = new ControllerI(bluetooth); + } + } + + public synchronized void println(final String data) + { + _activity.runOnUiThread(new Runnable() + { + @Override + public void run() + { + synchronized(ControllerApp.this) + { + _activity.println(data); + } + } + }); + } + + public static boolean isEmulator() + { + return Build.FINGERPRINT.startsWith("generic") || + Build.FINGERPRINT.startsWith("unknown") || + Build.MODEL.contains("google_sdk") || + Build.MODEL.contains("Emulator") || + Build.MODEL.contains("Android SDK built for x86") || + Build.MANUFACTURER.contains("Genymotion") || + (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || + Build.PRODUCT.equals("google_sdk"); + } + + class ControllerI + { + public ControllerI(boolean bluetooth) + { + com.zeroc.Ice.InitializationData initData = new com.zeroc.Ice.InitializationData(); + initData.properties = com.zeroc.Ice.Util.createProperties(); + initData.properties.setProperty("Ice.ThreadPool.Server.SizeMax", "10"); + initData.properties.setProperty("ControllerAdapter.Endpoints", "tcp"); + //initData.properties.setProperty("Ice.Trace.Network", "3"); + //initData.properties.setProperty("Ice.Trace.Protocol", "1"); + initData.properties.setProperty("ControllerAdapter.AdapterId", java.util.UUID.randomUUID().toString()); + initData.properties.setProperty("Ice.Override.ConnectTimeout", "1000"); + if(!isEmulator()) + { + if(bluetooth) + { + initData.properties.setProperty("Ice.Plugin.IceBT", "com.zeroc.IceBT.PluginFactory"); + } + initData.properties.setProperty("Ice.Plugin.IceDiscovery", "com.zeroc.IceDiscovery.PluginFactory"); + initData.properties.setProperty("IceDiscovery.DomainId", "TestController"); + } + _communicator = com.zeroc.Ice.Util.initialize(initData); + com.zeroc.Ice.ObjectAdapter adapter = _communicator.createObjectAdapter("ControllerAdapter"); + ProcessControllerPrx processController = ProcessControllerPrx.uncheckedCast( + adapter.add(new ProcessControllerI(), + com.zeroc.Ice.Util.stringToIdentity("Android/ProcessController"))); + adapter.activate(); + if(isEmulator()) + { + ProcessControllerRegistryPrx registry = ProcessControllerRegistryPrx.uncheckedCast( + _communicator.stringToProxy("Util/ProcessControllerRegistry:tcp -h 10.0.2.2 -p 15001")); + registerProcessController(adapter, registry, processController); + } + println("Android/ProcessController"); + } + + public void + registerProcessController(final com.zeroc.Ice.ObjectAdapter adapter, + final ProcessControllerRegistryPrx registry, + final ProcessControllerPrx processController) + { + registry.ice_pingAsync().whenCompleteAsync( + (r1, e1) -> + { + if(e1 != null) + { + handleException(e1, adapter, registry, processController); + } + else + { + com.zeroc.Ice.Connection connection = registry.ice_getConnection(); + connection.setAdapter(adapter); + connection.setACM(OptionalInt.of(5), + Optional.of(com.zeroc.Ice.ACMClose.CloseOff), + Optional.of(com.zeroc.Ice.ACMHeartbeat.HeartbeatAlways)); + connection.setCloseCallback( + con -> + { + println("connection with process controller registry closed"); + while (true) { + try + { + Thread.sleep(500); + break; + } + catch(InterruptedException e) + { + } + } + registerProcessController(adapter, registry, processController); + }); + + registry.setProcessControllerAsync(processController).whenCompleteAsync( + (r2, e2) -> + { + if(e2 != null) + { + handleException(e2, adapter, registry, processController); + } + }); + } + }); + } + + public void handleException(Throwable ex, + final com.zeroc.Ice.ObjectAdapter adapter, + final ProcessControllerRegistryPrx registry, + final ProcessControllerPrx processController) + { + if(ex instanceof com.zeroc.Ice.ConnectFailedException || ex instanceof com.zeroc.Ice.TimeoutException) + { + while(true) + { + try + { + Thread.sleep(500); + break; + } + catch(InterruptedException e) + { + } + } + registerProcessController(adapter, registry, processController); + } + else + { + println(ex.toString()); + } + } + + public void destroy() + { + _communicator.destroy(); + } + + private ProcessControllerRegistryPrx _registry; + private com.zeroc.Ice.Communicator _communicator; + } + + class ControllerHelperI extends Thread implements test.TestHelper.ControllerHelper + { + public ControllerHelperI(TestSuiteBundle bundle, String[] args, String exe) + { + _bundle = bundle; + _args = args; + _exe = exe; + } + + public void communicatorInitialized(Communicator communicator) + { + com.zeroc.Ice.Properties properties = communicator.getProperties(); + if(properties.getProperty("Ice.Plugin.IceSSL").equals("com.zeroc.IceSSL.PluginFactory")) + { + com.zeroc.IceSSL.Plugin plugin = + (com.zeroc.IceSSL.Plugin)communicator.getPluginManager().getPlugin("IceSSL"); + String keystore = communicator.getProperties().getProperty("IceSSL.Keystore"); + properties.setProperty("IceSSL.Keystore", ""); + int resource = keystore.equals("client.bks") ? R.raw.client : R.raw.server; + java.io.InputStream certs = getResources().openRawResource(resource); + plugin.setKeystoreStream(certs); + plugin.setTruststoreStream(certs); + communicator.getPluginManager().initializePlugins(); + } + } + + public void run() + { + try + { + _helper = _bundle.newInstance(); + _helper.setClassLoader(_bundle.getClassLoader()); + _helper.setControllerHelper(this); + + _helper.setWriter(new Writer() + { + @Override + public void close() throws IOException + { + } + + @Override + public void flush() throws IOException + { + } + + @Override + public void write(char[] buf, int offset, int count) + throws IOException + { + _out.append(buf, offset, count); + } + }); + + _helper.run(_args); + completed(0); + } + catch(Exception ex) + { + ex.printStackTrace(_helper.getWriter()); + completed(-1); + } + } + + public void shutdown() + { + if(_helper != null) + { + _helper.shutdown(); + } + } + + public String getOutput() + { + return _out.toString(); + } + + synchronized public void serverReady() + { + _ready = true; + notifyAll(); + } + + synchronized private void completed(int status) + { + _completed = true; + _status = status; + notifyAll(); + } + + synchronized private void waitReady(int timeout) + throws Test.Common.ProcessFailedException + { + long now = Time.currentMonotonicTimeMillis(); + while(!_ready && !_completed) + { + try + { + wait(timeout * 1000); + if(Time.currentMonotonicTimeMillis() - now > timeout * 1000) + { + throw new Test.Common.ProcessFailedException("timed out waiting for the process to be ready"); + } + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(_completed && _status != 0) + { + throw new Test.Common.ProcessFailedException(_out.toString()); + } + } + + synchronized private int waitSuccess(int timeout) + throws Test.Common.ProcessFailedException + { + long now = Time.currentMonotonicTimeMillis(); + while(!_completed) + { + try + { + wait(timeout * 1000); + if(Time.currentMonotonicTimeMillis() - now > timeout * 1000) + { + throw new Test.Common.ProcessFailedException("timed out waiting for the process to be ready"); + } + } + catch(java.lang.InterruptedException ex) + { + } + } + return _status; + } + + private TestSuiteBundle _bundle; + private String[] _args; + private String _exe; + private test.TestHelper _helper; + private boolean _ready = false; + private boolean _completed = false; + private int _status = 0; + private final StringBuffer _out = new StringBuffer(); + } + + class ProcessControllerI implements Test.Common.ProcessController + { + public Test.Common.ProcessPrx start(final String testsuite, final String exe, String[] args, + com.zeroc.Ice.Current current) + throws Test.Common.ProcessFailedException + { + println("starting " + testsuite + " " + exe + "... "); + String className = "test." + testsuite.replace("/", ".") + "." + exe.substring(0, 1).toUpperCase() + exe.substring(1); + try + { + TestSuiteBundle bundle = new TestSuiteBundle(className, getClassLoader()); + ControllerHelperI mainHelper = new ControllerHelperI(bundle, args, exe); + mainHelper.start(); + return Test.Common.ProcessPrx.uncheckedCast(current.adapter.addWithUUID(new ProcessI(mainHelper))); + } + catch(ClassNotFoundException ex) + { + throw new Test.Common.ProcessFailedException( + "testsuite `" + testsuite + "' exe ` " + exe + "' start failed:\n" + ex.toString()); + } + } + + public String getHost(String protocol, boolean ipv6, com.zeroc.Ice.Current current) + { + if(isEmulator()) + { + return "127.0.0.1"; + } + else + { + synchronized(ControllerApp.this) + { + return ipv6 ? _ipv6Address : _ipv4Address; + } + } + } + } + + class ProcessI implements Test.Common.Process + { + public ProcessI(ControllerHelperI controllerHelper) + { + _controllerHelper = controllerHelper; + } + + public void waitReady(int timeout, com.zeroc.Ice.Current current) + throws Test.Common.ProcessFailedException + { + _controllerHelper.waitReady(timeout); + } + + public int waitSuccess(int timeout, com.zeroc.Ice.Current current) + throws Test.Common.ProcessFailedException + { + return _controllerHelper.waitSuccess(timeout); + } + + public String terminate(com.zeroc.Ice.Current current) + { + _controllerHelper.shutdown(); + current.adapter.remove(current.id); + while(true) + { + try + { + _controllerHelper.join(); + break; + } + catch(InterruptedException ex) + { + } + } + return _controllerHelper.getOutput(); + } + + private ControllerHelperI _controllerHelper; + } +} diff --git a/java/test/android/controller/src/main/res/layout/main.xml b/java/test/android/controller/src/main/res/layout/main.xml new file mode 100644 index 00000000000..df4c8db98c7 --- /dev/null +++ b/java/test/android/controller/src/main/res/layout/main.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingBottom="5dip"> + <TextView + android:layout_width="5dip" + android:layout_weight="25" + android:layout_height="wrap_content" + android:text="IPv4" + android:layout_gravity="center_vertical"/> + + <Spinner + android:id="@+id/ipv4" + android:layout_width="5dip" + android:layout_weight="75" + android:layout_height="wrap_content" + android:drawSelectorOnTop="false"/> + </LinearLayout> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:paddingBottom="5dip"> + <TextView + android:layout_width="0dip" + android:layout_weight="25" + android:layout_height="wrap_content" + android:text="IPv6" + android:layout_gravity="center_vertical"/> + + <Spinner + android:id="@+id/ipv6" + android:layout_width="0dip" + android:layout_weight="75" + android:layout_height="wrap_content" + android:drawSelectorOnTop="false"/> + </LinearLayout> + + <ListView + android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:stackFromBottom="true" + android:transcriptMode="alwaysScroll"/> +</LinearLayout> diff --git a/java/test/android/controller/src/main/res/raw/client.bks b/java/test/android/controller/src/main/res/raw/client.bks Binary files differnew file mode 100644 index 00000000000..7a5b88d45c1 --- /dev/null +++ b/java/test/android/controller/src/main/res/raw/client.bks diff --git a/java/test/android/controller/src/main/res/raw/icon.png b/java/test/android/controller/src/main/res/raw/icon.png Binary files differnew file mode 100644 index 00000000000..75024841d32 --- /dev/null +++ b/java/test/android/controller/src/main/res/raw/icon.png diff --git a/java/test/android/controller/src/main/res/raw/server.bks b/java/test/android/controller/src/main/res/raw/server.bks Binary files differnew file mode 100644 index 00000000000..2da60311b53 --- /dev/null +++ b/java/test/android/controller/src/main/res/raw/server.bks diff --git a/java/test/android/controller/src/main/res/values/strings.xml b/java/test/android/controller/src/main/res/values/strings.xml new file mode 100644 index 00000000000..f96e345d87f --- /dev/null +++ b/java/test/android/controller/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Test Controller</string> + <string name="no_bluetooth">Bluetooth disabled</string> +</resources> |