summaryrefslogtreecommitdiff
path: root/java/test
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2018-09-12 14:48:57 +0200
committerJose <jose@zeroc.com>2018-09-12 14:48:57 +0200
commitf9801ab21989e330015ffa274493e775671fe865 (patch)
tree99f7cf77ab7863117aa8ee7f2f8047afc6351d58 /java/test
parentMissing C++ header include (diff)
downloadice-f9801ab21989e330015ffa274493e775671fe865.tar.bz2
ice-f9801ab21989e330015ffa274493e775671fe865.tar.xz
ice-f9801ab21989e330015ffa274493e775671fe865.zip
Make test controllers layout more consistent
Close #184
Diffstat (limited to 'java/test')
-rw-r--r--java/test/android/allTests.py16
-rw-r--r--java/test/android/controller/build.gradle104
-rw-r--r--java/test/android/controller/gradle.properties74
-rw-r--r--java/test/android/controller/gradle/wrapper/gradle-wrapper.jarbin0 -> 54708 bytes
-rw-r--r--java/test/android/controller/gradle/wrapper/gradle-wrapper.properties6
-rw-r--r--java/test/android/controller/gradlew172
-rw-r--r--java/test/android/controller/gradlew.bat84
-rw-r--r--java/test/android/controller/src/main/AndroidManifest.xml25
-rw-r--r--java/test/android/controller/src/main/assets/.gitignore1
-rw-r--r--java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerActivity.java143
-rw-r--r--java/test/android/controller/src/main/java/com/zeroc/testcontroller/ControllerApp.java532
-rw-r--r--java/test/android/controller/src/main/res/layout/main.xml55
-rw-r--r--java/test/android/controller/src/main/res/raw/client.bksbin0 -> 3524 bytes
-rw-r--r--java/test/android/controller/src/main/res/raw/icon.pngbin0 -> 3180 bytes
-rw-r--r--java/test/android/controller/src/main/res/raw/server.bksbin0 -> 3558 bytes
-rw-r--r--java/test/android/controller/src/main/res/values/strings.xml5
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
new file mode 100644
index 00000000000..7a3265ee94c
--- /dev/null
+++ b/java/test/android/controller/gradle/wrapper/gradle-wrapper.jar
Binary files differ
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
new file mode 100644
index 00000000000..7a5b88d45c1
--- /dev/null
+++ b/java/test/android/controller/src/main/res/raw/client.bks
Binary files differ
diff --git a/java/test/android/controller/src/main/res/raw/icon.png b/java/test/android/controller/src/main/res/raw/icon.png
new file mode 100644
index 00000000000..75024841d32
--- /dev/null
+++ b/java/test/android/controller/src/main/res/raw/icon.png
Binary files differ
diff --git a/java/test/android/controller/src/main/res/raw/server.bks b/java/test/android/controller/src/main/res/raw/server.bks
new file mode 100644
index 00000000000..2da60311b53
--- /dev/null
+++ b/java/test/android/controller/src/main/res/raw/server.bks
Binary files differ
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>