Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Byko-Ianko <v.bykoianko@corp.mail.ru>2015-02-27 20:31:21 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:46:03 +0300
commitc5a45d38c2060c1b8722a387031bef03cabdc9e6 (patch)
treecfbcac93439a272583e96657c5d17caaae8c97b5 /android/UnitTests
parentb6db1697139223354c36524605eb13cbdc2f9f15 (diff)
Developing infrastucture for launching integration tests and unit tests for Android. Porting integration tests and indexer tests on Android platform.
Diffstat (limited to 'android/UnitTests')
-rw-r--r--android/UnitTests/.gitignore9
-rw-r--r--android/UnitTests/AndroidManifest.xml67
l---------android/UnitTests/assets1
-rw-r--r--android/UnitTests/build.gradle110
l---------android/UnitTests/gradle.properties1
-rw-r--r--android/UnitTests/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--android/UnitTests/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xandroid/UnitTests/gradlew164
-rw-r--r--android/UnitTests/gradlew.bat90
-rw-r--r--android/UnitTests/jni/Android.mk32
-rw-r--r--android/UnitTests/jni/AndroidBeginning.mk63
-rw-r--r--android/UnitTests/jni/AndroidEnding.mk2
-rw-r--r--android/UnitTests/jni/Application.mk36
-rw-r--r--android/UnitTests/jni/main.cpp20
-rw-r--r--android/UnitTests/jni/mock.cpp256
-rw-r--r--android/UnitTests/jni/mock.hpp11
-rwxr-xr-xandroid/UnitTests/native_build.sh58
-rwxr-xr-xandroid/UnitTests/native_clean.sh24
l---------android/UnitTests/proguard-mwm.txt1
-rw-r--r--android/UnitTests/res/mipmap-hdpi/ic_launcher.pngbin0 -> 3418 bytes
-rw-r--r--android/UnitTests/res/mipmap-mdpi/ic_launcher.pngbin0 -> 2206 bytes
-rw-r--r--android/UnitTests/res/mipmap-xhdpi/ic_launcher.pngbin0 -> 4842 bytes
-rw-r--r--android/UnitTests/res/mipmap-xxhdpi/ic_launcher.pngbin0 -> 7718 bytes
-rw-r--r--android/UnitTests/res/values/strings.xml3
-rw-r--r--android/UnitTests/settings.gradle1
-rw-r--r--android/UnitTests/src/com/mapswithme/maps/unittests/AllTestsActivity.java12
-rw-r--r--android/UnitTests/tests_list.sh12
27 files changed, 979 insertions, 0 deletions
diff --git a/android/UnitTests/.gitignore b/android/UnitTests/.gitignore
new file mode 100644
index 0000000000..fccffe73ec
--- /dev/null
+++ b/android/UnitTests/.gitignore
@@ -0,0 +1,9 @@
+.gradle
+.idea
+.DS_Store
+bin
+build
+gen
+libs
+obj
+local.properties
diff --git a/android/UnitTests/AndroidManifest.xml b/android/UnitTests/AndroidManifest.xml
new file mode 100644
index 0000000000..42e844142f
--- /dev/null
+++ b/android/UnitTests/AndroidManifest.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- BEGIN_INCLUDE(manifest) -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.mapswithme.maps.unittests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- This is the platform API where NativeActivity was introduced. -->
+ <uses-sdk android:minSdkVersion="9" />
+
+ <uses-feature
+ android:glEsVersion="0x00020000"
+ android:required="true"/>
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="true"/>
+ <uses-feature
+ android:name="android.hardware.wifi"
+ android:required="false"/>
+ <uses-feature
+ android:name="android.hardware.location"
+ android:required="false"/>
+ <uses-feature
+ android:name="android.hardware.location.network"
+ android:required="false"/>
+ <uses-feature
+ android:name="android.hardware.location.gps"
+ android:required="false"/>
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
+
+ <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+ <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
+
+
+ <supports-screens
+ android:largeScreens="true"
+ android:xlargeScreens="true"/>
+
+ <!-- This .apk has no Java code itself, so set hasCode to false. android:hasCode="false" -->
+ <application android:label="@string/app_name">
+
+ <!-- Our activity is the built-in NativeActivity framework class.
+ This will take care of integrating with our NDK code. -->
+ <activity android:name="com.mapswithme.maps.unittests.AllTestsActivity"
+ android:label="@string/app_name"
+ android:configChanges="orientation|keyboardHidden">
+ <!-- Tell NativeActivity the name of or .so -->
+ <meta-data android:name="android.app.lib_name"
+ android:value="all_tests" />
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+<!-- END_INCLUDE(manifest) -->
diff --git a/android/UnitTests/assets b/android/UnitTests/assets
new file mode 120000
index 0000000000..ec2e4be2f8
--- /dev/null
+++ b/android/UnitTests/assets
@@ -0,0 +1 @@
+../assets \ No newline at end of file
diff --git a/android/UnitTests/build.gradle b/android/UnitTests/build.gradle
new file mode 100644
index 0000000000..c7d09e5619
--- /dev/null
+++ b/android/UnitTests/build.gradle
@@ -0,0 +1,110 @@
+// 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:1.1.+'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion propTargetSdkVersion.toInteger()
+ buildToolsVersion propBuildToolsVersion
+
+ defaultConfig {
+ // Default package name is taken from the manifest and should be com.mapswithme.maps.unittests
+ versionCode propVersionCode.toInteger()
+ versionName propVersionName
+ minSdkVersion propMinSdkVersion.toInteger()
+ targetSdkVersion propTargetSdkVersion.toInteger()
+ }
+
+ sourceSets.main {
+ manifest.srcFile 'AndroidManifest.xml'
+ res.srcDirs = ['res']
+ java.srcDirs = ['src']
+ assets.srcDirs = ['assets']
+ jniLibs.srcDirs = ['libs']
+ }
+
+ signingConfigs {
+ mapswithme {
+ storeFile file('../../tools/android/mapswithmetests.keystore')
+ storePassword 'ITHOrMARopHE'
+ keyAlias 'mapswithmetests'
+ keyPassword 'ITHOrMARopHE'
+ }
+ }
+
+ buildTypes {
+ debug {
+ applicationIdSuffix '.debug' // Allows to install debug and release builds together
+ versionNameSuffix '-debug'
+ jniDebuggable true // Enable jni debug build
+ zipAlignEnabled true
+ }
+
+ release {
+ signingConfig signingConfigs.mapswithme
+ minifyEnabled true
+ shrinkResources true
+ proguardFile('proguard-mwm.txt')
+ }
+ }
+
+ // We don't compress these extensions in assets/ because our random FileReader can't read zip-compressed files from apk
+ aaptOptions {
+ noCompress 'txt', 'bin', 'skn', 'html', 'png', 'json', 'mwm', 'ttf'
+ ignoreAssetsPattern "!.svn:!.git:!.DS_Store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"
+ }
+
+ // Enables new Java features in KitKat+ but needs Java 1.7 installed
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+}
+
+def NUM_OF_PARALLEL_MAKE_TASKS = Runtime.runtime.availableProcessors() + 1
+def INTEGRATION_TESTS_BUILD = '../../integration_tests/'
+Properties properties = new Properties()
+properties.load(project.rootProject.file('local.properties').newDataInputStream())
+def NDK_BUILD = properties.getProperty('ndk.dir') + '/ndk-build'
+
+// Building all static libraries
+task cppLibsBuildDebug(type: Exec, description: 'Building DEBUG version of static C++ libraries') {
+ commandLine 'bash', './native_build.sh', 'debug'
+}
+
+task cppLibsBuildRelease(type: Exec, description: 'Building RELEASE/PRODUCTION version of static C++ libraries') {
+ commandLine 'bash', './native_build.sh', 'production'
+}
+
+tasks.withType(JavaCompile) { compileTask ->
+ if (compileTask.name.contains('Release')) {
+ compileTask.dependsOn cppLibsBuildRelease
+ } else {
+ compileTask.dependsOn cppLibsBuildDebug
+ }
+}
+
+// Cleaning ndk
+task cppLibsClean(type: Exec, description: 'Clean native libraries') {
+ commandLine 'bash', './native_clean.sh'
+}
+
+clean.dependsOn 'cppLibsClean'
+
diff --git a/android/UnitTests/gradle.properties b/android/UnitTests/gradle.properties
new file mode 120000
index 0000000000..7677fb73be
--- /dev/null
+++ b/android/UnitTests/gradle.properties
@@ -0,0 +1 @@
+../gradle.properties \ No newline at end of file
diff --git a/android/UnitTests/gradle/wrapper/gradle-wrapper.jar b/android/UnitTests/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..8c0fb64a86
--- /dev/null
+++ b/android/UnitTests/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/android/UnitTests/gradle/wrapper/gradle-wrapper.properties b/android/UnitTests/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..0c71e760dc
--- /dev/null
+++ b/android/UnitTests/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/android/UnitTests/gradlew b/android/UnitTests/gradlew
new file mode 100755
index 0000000000..91a7e269e1
--- /dev/null
+++ b/android/UnitTests/gradlew
@@ -0,0 +1,164 @@
+#!/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
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# 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\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+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"`
+
+ # 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/android/UnitTests/gradlew.bat b/android/UnitTests/gradlew.bat
new file mode 100644
index 0000000000..8a0b282aa6
--- /dev/null
+++ b/android/UnitTests/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/android/UnitTests/jni/Android.mk b/android/UnitTests/jni/Android.mk
new file mode 100644
index 0000000000..839ba603c8
--- /dev/null
+++ b/android/UnitTests/jni/Android.mk
@@ -0,0 +1,32 @@
+
+LOCAL_PATH := $(call my-dir)
+
+# Add prebuilt shared lib
+# todo(VB) extract the names of the libs from tests_list.sh
+MY_PREBUILT_LIBS_PATH := ../libs/tmp/$(TARGET_ARCH_ABI)
+$(info $(MY_PREBUILT_LIBS_PATH))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := integration_tests
+LOCAL_SRC_FILES := $(MY_PREBUILT_LIBS_PATH)/libintegration_tests.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := indexer_tests
+LOCAL_SRC_FILES := $(MY_PREBUILT_LIBS_PATH)/libindexer_tests.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+ROOT_PATH := ../..
+include ./jni/AndroidBeginning.mk
+
+LOCAL_MODULE := all_tests
+
+LOCAL_SRC_FILES := ./main.cpp
+LOCAL_STATIC_LIBRARIES := android_native_app_glue
+
+# todo(VB) extract the names of the libs from tests_list.sh
+LOCAL_SHARED_LIBRARIES := integration_tests indexer_tests
+
+include ./jni/AndroidEnding.mk
diff --git a/android/UnitTests/jni/AndroidBeginning.mk b/android/UnitTests/jni/AndroidBeginning.mk
new file mode 100644
index 0000000000..3cad168ef1
--- /dev/null
+++ b/android/UnitTests/jni/AndroidBeginning.mk
@@ -0,0 +1,63 @@
+
+OMIM_CONFIG := debug
+ifeq ($(NDK_DEBUG),1)
+ OMIM_CONFIG := debug
+else
+ ifeq ($(PRODUCTION),1)
+ OMIM_CONFIG := production
+ endif
+endif
+
+# Avoid clean errors due to missing external static libs
+ifneq ($(MAKECMDGOALS),clean)
+
+ROOT_PATH_FROM_JNI = $(ROOT_PATH)/..
+
+MY_PREBUILT_LIBS_PATH := $(ROOT_PATH_FROM_JNI)/../omim-android-$(OMIM_CONFIG)-$(TARGET_ARCH_ABI)/out/$(OMIM_CONFIG)
+$(info $(MY_PREBUILT_LIBS_PATH))
+
+define add_prebuild_static_lib
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := $1
+ LOCAL_SRC_FILES := $(MY_PREBUILT_LIBS_PATH)/lib$1.a
+ include $(PREBUILT_STATIC_LIBRARY)
+endef
+
+prebuild_static_libs := osrm protobuf tomcrypt jansson bzip2 zlib fribidi freetype expat base coding geometry anim platform graphics indexer storage search routing gui map stats_client succinct
+
+$(foreach item,$(prebuild_static_libs),$(eval $(call add_prebuild_static_lib,$(item))))
+
+endif
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_FEATURES += exceptions rtti
+
+LOCAL_C_INCLUDES := $(ROOT_PATH_FROM_JNI)/
+LOCAL_C_INCLUDES += $(ROOT_PATH)/
+
+ifneq ($(NDK_DEBUG),1)
+ ifeq ($(PRODUCTION),1)
+ OMIM_CONFIG := production
+ LOCAL_CPPFLAGS += -fvisibility-inlines-hidden
+ endif
+ LOCAL_CFLAGS += -O3
+ LOCAL_LFLAGS += -O3
+endif
+LOCAL_CFLAGS += -ffunction-sections -fdata-sections -Wno-extern-c-compat
+
+TARGET_PLATFORM := android-9
+
+$(info $(LOCAL_PATH))
+
+MY_CPP_PATH = $(LOCAL_PATH)/..
+MY_LOCAL_SRC_FILES := $(wildcard $(MY_CPP_PATH)/*.cpp)
+LOCAL_SRC_FILES += $(subst jni/, , $(MY_LOCAL_SRC_FILES))
+
+LOCAL_SRC_FILES += $(ROOT_PATH_FROM_JNI)/testing/testingmain.cpp
+LOCAL_SRC_FILES += $(ROOT_PATH_FROM_JNI)/android/UnitTests/jni/mock.cpp
+LOCAL_SRC_FILES += ./test.cpp
+
+LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
+LOCAL_LDLIBS += -lGLESv2 -latomic
+LOCAL_LDLIBS += -Wl,--gc-sections
diff --git a/android/UnitTests/jni/AndroidEnding.mk b/android/UnitTests/jni/AndroidEnding.mk
new file mode 100644
index 0000000000..917c9accff
--- /dev/null
+++ b/android/UnitTests/jni/AndroidEnding.mk
@@ -0,0 +1,2 @@
+include $(BUILD_SHARED_LIBRARY)
+$(call import-module,android/native_app_glue)
diff --git a/android/UnitTests/jni/Application.mk b/android/UnitTests/jni/Application.mk
new file mode 100644
index 0000000000..d2d2ced6bc
--- /dev/null
+++ b/android/UnitTests/jni/Application.mk
@@ -0,0 +1,36 @@
+NDK_TOOLCHAIN_VERSION := clang3.5
+APP_ABI := armeabi-v7a-hard
+# APP_ABI := armeabi-v7a
+
+APP_PLATFORM := android-9
+APP_STL := c++_static
+
+# libc++-specific issues: -std=c++11" is turned on by default.
+
+APP_CPPFLAGS += -Wno-deprecated-register
+
+#@todo(VB) Build tests for android x86 platform
+#ifeq (x$(NDK_ABI_TO_BUILD), x)
+# APP_ABI := armeabi-v7a-hard x86
+#else
+# APP_ABI := $(NDK_ABI_TO_BUILD)
+#endif
+
+APP_CPPFLAGS += -fexceptions
+LOCAL_CPPFLAGS += -fexceptions
+
+APP_CPPFLAGS += -frtti
+LOCAL_CPPFLAGS += -frtti
+
+APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti
+
+ifeq ($(NDK_DEBUG),1)
+ APP_OPTIM := debug
+ APP_CFLAGS += -DDEBUG -D_DEBUG
+else
+ APP_OPTIM := release
+ APP_CFLAGS += -DRELEASE -D_RELEASE
+ifeq ($(PRODUCTION),1)
+ APP_CFLAGS += -DOMIM_PRODUCTION
+endif
+endif
diff --git a/android/UnitTests/jni/main.cpp b/android/UnitTests/jni/main.cpp
new file mode 100644
index 0000000000..53c752ee8c
--- /dev/null
+++ b/android/UnitTests/jni/main.cpp
@@ -0,0 +1,20 @@
+// @todo(VB) this file should be generated with a script based on tests_list.sh
+#include "mock.hpp"
+
+#include "integration_tests/jni/test.hpp"
+#include "indexer/indexer_tests/jni/test.hpp"
+
+#include <android_native_app_glue.h>
+
+
+void android_main(struct android_app * state)
+{
+ // Make sure glue isn't stripped.
+ app_dummy();
+
+ integration_tests::test(state);
+ indexer_tests::test(state);
+
+ // @todo(VB) you need to write code to leave the activity correctly after all tests are finished. And show a dialog with the results.
+ // @todo(VB) It's nice to show the result of the test on Android screen. Message box or something like that.
+}
diff --git a/android/UnitTests/jni/mock.cpp b/android/UnitTests/jni/mock.cpp
new file mode 100644
index 0000000000..d06c074309
--- /dev/null
+++ b/android/UnitTests/jni/mock.cpp
@@ -0,0 +1,256 @@
+#include "mock.hpp"
+
+#include "android/jni/com/mapswithme/core/logging.hpp"
+
+#include "coding/file_writer.hpp"
+
+#include "platform/file_logging.hpp"
+#include "platform/platform.hpp"
+
+#include "base/assert.hpp"
+#include "base/logging.hpp"
+
+#include "std/string.hpp"
+
+using namespace my;
+
+// @todo(VB) probably it's worth thinking about output of the function to make the result of the tests more readable
+// @todo(VB) it's necessary display test name android log
+static void AndroidLogMessage(LogLevel l, SrcPoint const & src, string const & s)
+{
+ android_LogPriority pr = ANDROID_LOG_SILENT;
+
+ switch (l)
+ {
+ case LINFO: pr = ANDROID_LOG_INFO; break;
+ case LDEBUG: pr = ANDROID_LOG_DEBUG; break;
+ case LWARNING: pr = ANDROID_LOG_WARN; break;
+ case LERROR: pr = ANDROID_LOG_ERROR; break;
+ case LCRITICAL: pr = ANDROID_LOG_FATAL; break;
+ }
+
+ string const out = DebugPrint(src) + " " + s;
+ __android_log_write(pr, " MapsMeTests ", out.c_str());
+}
+
+static void AndroidAssertMessage(SrcPoint const & src, string const & s)
+{
+#if defined(MWM_LOG_TO_FILE)
+ AndroidLogToFile(LERROR, src, s);
+#else
+ AndroidLogMessage(LERROR, src, s);
+#endif
+
+#ifdef DEBUG
+ assert(false);
+#else
+ MYTHROW(RootException, (s));
+#endif
+}
+
+static void InitSystemLog()
+{
+#if defined(MWM_LOG_TO_FILE)
+ SetLogMessageFn(&AndroidLogToFile);
+#else
+ SetLogMessageFn(&AndroidLogMessage);
+#endif
+}
+
+static void InitAssertLog()
+{
+ SetAssertFunction(&AndroidAssertMessage);
+}
+
+namespace
+{
+ JavaVM * javaVM = nullptr;
+}
+
+namespace android_tests
+{
+ class MainThreadScopeGuard
+ {
+ JavaVM * m_Vm;
+ JNIEnv * m_Env;
+ public:
+ MainThreadScopeGuard(JavaVM * vm) : m_Vm(vm), m_Env(nullptr)
+ {
+ assert(vm);
+ m_Vm->AttachCurrentThread(&m_Env, NULL);
+ }
+ ~MainThreadScopeGuard() { m_Vm->DetachCurrentThread(); }
+ JNIEnv * GetEnv() const { return m_Env; }
+ };
+
+ static bool CheckExceptions(JNIEnv * env)
+ {
+ jthrowable exception = env->ExceptionOccurred();
+ if (exception)
+ {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ return true;
+ }
+ return false;
+ }
+
+ static string GetApkPath(ANativeActivity * activity, JNIEnv * env)
+ {
+ ASSERT(activity, ());
+ ASSERT(env, ());
+
+ jclass const clazz = env->GetObjectClass(activity->clazz);
+ ASSERT(clazz, ());
+ jmethodID const methodID = env->GetMethodID(clazz, "getPackageCodePath", "()Ljava/lang/String;");
+ ASSERT(methodID, ());
+ jobject const result = env->CallObjectMethod(activity->clazz, methodID);
+ ASSERT(result, ());
+ ASSERT(!CheckExceptions(env), ());
+ jboolean isCopy;
+ std::string const res = env->GetStringUTFChars((jstring)result, &isCopy);
+ return res;
+ }
+
+ static string GetSdcardPath(ANativeActivity * activity, JNIEnv * env)
+ {
+ ASSERT(activity, ());
+ ASSERT(env, ());
+
+ jclass const classEnvironment = env->FindClass("android/os/Environment");
+ ASSERT(classEnvironment, ());
+ jmethodID const methodIDgetExternalStorageDirectory = env->GetStaticMethodID(classEnvironment, "getExternalStorageDirectory", "()Ljava/io/File;");
+ ASSERT(methodIDgetExternalStorageDirectory, ());
+ jobject const objectFile = env->CallStaticObjectMethod(classEnvironment, methodIDgetExternalStorageDirectory);
+ ASSERT(objectFile, ());
+ ASSERT(!CheckExceptions(env), ());
+
+ jclass const classFile = env->GetObjectClass(objectFile);
+ ASSERT(classFile, ());
+ jmethodID const methodIDgetAbsolutePath = env->GetMethodID(classFile, "getAbsolutePath", "()Ljava/lang/String;");
+ ASSERT(methodIDgetAbsolutePath, ());
+ jstring const stringPath = (jstring) env->CallObjectMethod(objectFile, methodIDgetAbsolutePath);
+ ASSERT(stringPath, ());
+ ASSERT(!CheckExceptions(env), ());
+
+ jboolean isCopy;
+ std::string const res = env->GetStringUTFChars((jstring)stringPath, &isCopy);
+ return res;
+ }
+
+ static string GetPackageName(ANativeActivity * activity, JNIEnv * env)
+ {
+ ASSERT(activity, ());
+ ASSERT(env, ());
+
+ jclass const clazz = env->GetObjectClass(activity->clazz);
+ ASSERT(clazz, ());
+ jmethodID const methodID = env->GetMethodID(clazz, "getPackageName", "()Ljava/lang/String;");
+ ASSERT(methodID, ());
+ jobject const result = env->CallObjectMethod(activity->clazz, methodID);
+ ASSERT(result, ());
+ ASSERT(!CheckExceptions(env), ());
+ jboolean isCopy;
+ std::string const res = env->GetStringUTFChars((jstring)result, &isCopy);
+ return res;
+ }
+
+ class Platform : public ::Platform
+ {
+ public:
+ void Initialize(ANativeActivity * activity, JNIEnv * env)
+ {
+ LOG(LINFO, ("Platform::Initialize()"));
+ string apkPath = android_tests::GetApkPath(activity, env);
+ LOG(LINFO, ("Apk path FromJNI: ", apkPath.c_str()));
+
+ string sdcardPath = android_tests::GetSdcardPath(activity, env);
+ LOG(LINFO, ("Sdcard path FromJNI: ", sdcardPath.c_str()));
+
+ string packageName = android_tests::GetPackageName(activity, env);
+ LOG(LINFO, ("Package name FromJNI: ", packageName.c_str()));
+
+ m_writableDir = sdcardPath + "/MapsWithMe/";
+ m_resourcesDir = apkPath;
+
+ m_tmpDir = sdcardPath + "/Android/data/" + packageName + "/cache/";
+ m_settingsDir = m_writableDir;
+ m_androidDefResScope = "rfw";
+ }
+
+ void OnExternalStorageStatusChanged(bool isAvailable)
+ {
+ LOG(LWARNING, ("OnExternalStorageStatusChanged() is not implemented."));
+ }
+
+ /// get storage path without ending "/MapsWithMe/"
+ string GetStoragePathPrefix() const
+ {
+ return string("/sdcard");
+ }
+ /// assign storage path (should contain ending "/MapsWithMe/")
+ void SetStoragePath(string const & path) {}
+
+ bool HasAvailableSpaceForWriting(uint64_t size) const{ return true; }
+
+ static void RunOnGuiThreadImpl(TFunctor const & fn, bool blocking = false)
+ {
+ ASSERT(false, ());
+ }
+
+ static Platform & Instance()
+ {
+ static Platform platform;
+ return platform;
+ }
+ };
+}
+
+Platform & GetPlatform()
+{
+ return android_tests::Platform::Instance();
+}
+
+string GetAndroidSystemLanguage()
+{
+ return "en_US";
+}
+
+void AndroidThreadAttachToJVM()
+{
+ LOG(LWARNING, ("AndroidThreadAttachToJVM() is not implemented."));
+}
+void AndroidThreadDetachFromJVM()
+{
+ LOG(LWARNING, ("AndroidThreadDetachFromJVM() is not implemented."));
+}
+
+void Platform::RunOnGuiThread(TFunctor const & fn)
+{
+ LOG(LWARNING, ("Platform::RunOnGuiThread() is not implemented."));
+}
+
+JavaVM * GetJVM()
+{
+ LOG(LWARNING, ("GetJVM() returns nullptr."));
+ return nullptr;
+}
+
+void Initialize(android_app * state)
+{
+ LOGI("Indexperf. Initialize()");
+ assert(state);
+ ANativeActivity * activity = state->activity;
+ assert(activity);
+ android_tests::MainThreadScopeGuard mainThreadScopeGuard(activity->vm);
+ JNIEnv * env = mainThreadScopeGuard.GetEnv();
+ assert(env);
+
+ javaVM = activity->vm;
+
+ InitSystemLog();
+ InitAssertLog();
+ android_tests::Platform::Instance().Initialize(activity, env);
+ LOG(LINFO, ("Indexperf. Initialization finished...."));
+}
+
diff --git a/android/UnitTests/jni/mock.hpp b/android/UnitTests/jni/mock.hpp
new file mode 100644
index 0000000000..eaf4bebc51
--- /dev/null
+++ b/android/UnitTests/jni/mock.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <android/log.h>
+#include <android_native_app_glue.h>
+#include <cassert>
+
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
+#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
+
+void Initialize(android_app * state);
+JavaVM * GetJVM();
diff --git a/android/UnitTests/native_build.sh b/android/UnitTests/native_build.sh
new file mode 100755
index 0000000000..5bfcf130d0
--- /dev/null
+++ b/android/UnitTests/native_build.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+MY_PATH=$(dirname "$0") # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+
+source "$MY_PATH/tests_list.sh"
+
+declare -r NDK_ABI=armeabi-v7a-hard
+
+declare -r PROP_DEBUG_NDK_FLAGS="-j8 V=1 NDK_DEBUG=1 DEBUG=1 APP_ABI=$NDK_ABI"
+declare -r PROP_RELEASE_NDK_FLAGS="-j8 V=1 NDK_DEBUG=0 PRODUCTION=1 APP_ABI=$NDK_ABI"
+
+Usage() {
+ echo "Usage: $0 <debug|release|production>" 1>&2
+ exit 1
+}
+
+NdkBuild() {
+ if [ "$1" = "debug" ]; then
+ NDK_PARAMS="--directory=$2 ${PROP_DEBUG_NDK_FLAGS}"
+ else
+ NDK_PARAMS="--directory=$2 ${PROP_RELEASE_NDK_FLAGS}"
+ fi
+ echo "ndk-build $NDK_PARAMS"
+ ndk-build $NDK_PARAMS
+}
+
+if [ $# != 1 ]; then
+ Usage
+fi
+
+if [ "$1" != "debug" && "$1" != "release" && "$1" != "production" ]; then
+ Usage
+fi
+
+echo "Building omim/andoid..."
+if [ "$1" = "debug" ]; then
+ bash $MY_PATH/../../tools/autobuild/android.sh debug $NDK_ABI
+else
+ bash $MY_PATH/../../tools/autobuild/android.sh production $NDK_ABI
+fi
+
+for test in "${TESTS_LIST[@]}"; do
+ echo "Building test $test"
+ NdkBuild $1 ${test}
+done
+
+echo "Copying so-files with tests to the libs directory: "
+TMP_LIB_DIR=$MY_PATH/libs/tmp/$NDK_ABI/
+echo $TMP_LIB_DIR
+mkdir -p $TMP_LIB_DIR
+for test in "${TESTS_LIST[@]}"; do
+ echo "Copying so-file for test: $test"
+ cp -r $test/libs/*/*.so $TMP_LIB_DIR
+done
+
+echo "Building main so file for the native activity... "
+NdkBuild $1 .
diff --git a/android/UnitTests/native_clean.sh b/android/UnitTests/native_clean.sh
new file mode 100755
index 0000000000..efd4bea30b
--- /dev/null
+++ b/android/UnitTests/native_clean.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+MY_PATH=$(dirname "$0") # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+
+source "$MY_PATH/tests_list.sh"
+
+echo "Cleaning omim/andoid..."
+#ndk-build --directory=$MY_PATH/.. clean
+
+RemoveObjLibs() {
+ rm -r $1/obj
+ rm -r $1/libs
+}
+
+for test in "${TESTS_LIST[@]}"; do
+ echo "Cleaning test $test"
+ ndk-build --directory=$test clean
+ RemoveObjLibs $test
+done
+
+ndk-build --directory=$MY_PATH clean
+RemoveObjLibs $MY_PATH
+rm -r $MY_PATH/build
diff --git a/android/UnitTests/proguard-mwm.txt b/android/UnitTests/proguard-mwm.txt
new file mode 120000
index 0000000000..a3abbc779a
--- /dev/null
+++ b/android/UnitTests/proguard-mwm.txt
@@ -0,0 +1 @@
+./../proguard-mwm.txt \ No newline at end of file
diff --git a/android/UnitTests/res/mipmap-hdpi/ic_launcher.png b/android/UnitTests/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..cde69bccce
--- /dev/null
+++ b/android/UnitTests/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/android/UnitTests/res/mipmap-mdpi/ic_launcher.png b/android/UnitTests/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..c133a0cbd3
--- /dev/null
+++ b/android/UnitTests/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/android/UnitTests/res/mipmap-xhdpi/ic_launcher.png b/android/UnitTests/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..bfa42f0e7b
--- /dev/null
+++ b/android/UnitTests/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/android/UnitTests/res/mipmap-xxhdpi/ic_launcher.png b/android/UnitTests/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..324e72cdd7
--- /dev/null
+++ b/android/UnitTests/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/UnitTests/res/values/strings.xml b/android/UnitTests/res/values/strings.xml
new file mode 100644
index 0000000000..a36dbd5633
--- /dev/null
+++ b/android/UnitTests/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">MAPS.ME Unit Tests</string>
+</resources>
diff --git a/android/UnitTests/settings.gradle b/android/UnitTests/settings.gradle
new file mode 100644
index 0000000000..e7b4def49c
--- /dev/null
+++ b/android/UnitTests/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/android/UnitTests/src/com/mapswithme/maps/unittests/AllTestsActivity.java b/android/UnitTests/src/com/mapswithme/maps/unittests/AllTestsActivity.java
new file mode 100644
index 0000000000..5dcfb6355f
--- /dev/null
+++ b/android/UnitTests/src/com/mapswithme/maps/unittests/AllTestsActivity.java
@@ -0,0 +1,12 @@
+package com.mapswithme.maps.unittests;
+// @todo(VB) This file should be generaged based on tests_list.h
+
+public class AllTestsActivity extends android.app.NativeActivity {
+
+ static {
+ System.loadLibrary("integration_tests");
+ System.loadLibrary("indexer_tests");
+ System.loadLibrary("all_tests");
+ }
+ }
+ \ No newline at end of file
diff --git a/android/UnitTests/tests_list.sh b/android/UnitTests/tests_list.sh
new file mode 100644
index 0000000000..d5b625e4b2
--- /dev/null
+++ b/android/UnitTests/tests_list.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# This file contains a list of test which will be built for android.
+# If you want you can leave a subset of tests here for developent purpose
+
+# @todo this list of test paths should be used in sh scripts and in C++ as well.
+# The main point is you need to add a test to UnitTests project only once and here.
+
+MY_PATH=$(dirname "$0") # relative
+MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
+
+declare -r TESTS_LIST=($MY_PATH/../../integration_tests/ $MY_PATH/../../indexer/indexer_tests/)