From: Jay Sharma Date: Wed, 7 Oct 2015 13:04:54 +0000 (+0530) Subject: [Resource-Container] Java SDK and Sample applications X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7f042c3b4985a254764b4d8f81b9ffe2dff6abcd;p=contrib%2Fiotivity.git [Resource-Container] Java SDK and Sample applications - Java SDK for Resource Container. - Android Sample Applications for Resource Container. Change-Id: I1138ea7c82a155b18b8951d2bcdd94b24f1bd579 Signed-off-by: Jay Sharma Reviewed-on: https://gerrit.iotivity.org/gerrit/3641 Tested-by: jenkins-iotivity Reviewed-by: Madan Lanka --- diff --git a/service/resource-container/SConscript b/service/resource-container/SConscript index aaded92..45382d4 100644 --- a/service/resource-container/SConscript +++ b/service/resource-container/SConscript @@ -238,4 +238,10 @@ containersample_env.AppendUnique(LIBS = ['rcs_container']) containersampleclient_src = ['examples/ContainerSampleClient.cpp'] containersampleclientapp = containersample_env.Program('ContainerSampleClient',containersampleclient_src) Alias("containersampleclient", containersampleclientapp) -env.AppendTarget('containersampleclient') \ No newline at end of file +env.AppendTarget('containersampleclient') + +###################################################################### +# Build Container Java SDK +###################################################################### +if target_os == 'android': + SConscript('android/SConscript') \ No newline at end of file diff --git a/service/resource-container/android/.gitignore b/service/resource-container/android/.gitignore new file mode 100644 index 0000000..49ffed7 --- /dev/null +++ b/service/resource-container/android/.gitignore @@ -0,0 +1,9 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build/* +/service/build/* +/service/src/main/obj/* +/service/src/main/libs/* diff --git a/service/resource-container/android/SConscript b/service/resource-container/android/SConscript new file mode 100644 index 0000000..ce0d922 --- /dev/null +++ b/service/resource-container/android/SConscript @@ -0,0 +1,58 @@ +import os +import platform +Import('env') + +android_home = env.get('ANDROID_HOME') + +ANDROID_TARGET_ARCH = env.get('TARGET_ARCH') +if env.get('RELEASE'): + ANDROID_RELEASE="release" +else: + ANDROID_RELEASE="debug" + +os.environ['ANDROID_HOME'] = env.get('ANDROID_HOME') +os.environ['ANDROID_NDK_HOME'] = env.get('ANDROID_NDK') + +if not os.path.exists(android_home + '/platforms/android-21') or not os.path.exists(android_home + '/build-tools/20.0.0'): + print ''' +***************************************** Info ******************************** +* Either 'Android API 21' is not installed or 'Android SDK Build Tools * +* 20.0.0' is not installed. The Android SDK Manager will now open. Please * +* be sure to deselect all options, then select the following 2 packages: * +* 1. Under "Tools" select "Android SDK Build-tools" Revision 20. * +* 2. Under "Android 5.0.1 (API 21)" select "SDK Platform" * +* 3. Continue by selecting "Install 2 Packages" * +* * +* NOTE: If you have an http proxy, please press ctrl+c now and edit/create * +* the following file in your $HOME directory as follows: * +* * +* Edit/Create file: "$HOME/.android/androidtool.cfg" * +* * +* http.proxyPort= * +* sdkman.monitor.density=108 * +* http.proxyHost= * +* sdkman.show.update.only=true * +* sdkman.ask.adb.restart=false * +* sdkman.force.http=true * +* sdkman.show.updateonly=true * +* * +******************************************************************************* + +...Opening Android SDK Manager now. Once you are finished, the build will continue. +''' + os.system(android_home + '/tools/android') + + +def ensure_libs(target, source, env): + return target, [source, env.get('BUILD_DIR') + 'librcs_server.so', + env.get('BUILD_DIR') + 'librcs_client.so', + env.get('BUILD_DIR') + 'librcs_container.so'] + +jdk_env = Environment(ENV=os.environ) +jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + + ' build -bservice/resource-container/android/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE), + emitter = ensure_libs) +jdk_env['BUILD_DIR'] = env.get('BUILD_DIR') + +jdk_env.Gradle(target="service/objs", + source="resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java") diff --git a/service/resource-container/android/android.iml b/service/resource-container/android/android.iml new file mode 100644 index 0000000..2a02201 --- /dev/null +++ b/service/resource-container/android/android.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/service/resource-container/android/build.gradle b/service/resource-container/android/build.gradle new file mode 100644 index 0000000..cbfddfd --- /dev/null +++ b/service/resource-container/android/build.gradle @@ -0,0 +1,40 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ +// 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.3.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter { + url "http://jcenter.bintray.com/" + } + } +} diff --git a/service/resource-container/android/gradle.properties b/service/resource-container/android/gradle.properties new file mode 100644 index 0000000..dff37f4 --- /dev/null +++ b/service/resource-container/android/gradle.properties @@ -0,0 +1,40 @@ +# +# //****************************************************************** +# // +# // Copyright 2015 Intel Corporation. +# // +# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# // +# // Licensed under the Apache License, Version 2.0 (the "License"); +# // you may not use this file except in compliance with the License. +# // You may obtain a copy of the License at +# // +# // http://www.apache.org/licenses/LICENSE-2.0 +# // +# // Unless required by applicable law or agreed to in writing, software +# // distributed under the License is distributed on an "AS IS" BASIS, +# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# // See the License for the specific language governing permissions and +# // limitations under the License. +# // +# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# + +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/service/resource-container/android/gradlew b/service/resource-container/android/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/service/resource-container/android/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/service/resource-container/android/gradlew.bat b/service/resource-container/android/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/service/resource-container/android/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/service/resource-container/android/resource-container/base.iml b/service/resource-container/android/resource-container/base.iml new file mode 100644 index 0000000..3bf0877 --- /dev/null +++ b/service/resource-container/android/resource-container/base.iml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/service/resource-container/android/resource-container/build.gradle b/service/resource-container/android/resource-container/build.gradle new file mode 100644 index 0000000..50c7205 --- /dev/null +++ b/service/resource-container/android/resource-container/build.gradle @@ -0,0 +1,107 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 21 + buildToolsVersion "20.0.0" + archivesBaseName = "iotivity" + + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${archivesBaseName}-${TARGET_ARCH}-${outputFile.name}" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + lintOptions { + abortOnError false + } + + sourceSets { + main { + manifest.srcFile 'src/main/AndroidManifest.xml' + jni.srcDirs = [] //disable automatic ndk-build call + jniLibs.srcDir new File(buildDir, 'native-libs') + } + androidTest.setRoot('src/androidTest') + } +} + + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + + androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0' + androidTestCompile 'com.google.dexmaker:dexmaker:1.0' + androidTestCompile 'org.mockito:mockito-core:1.10.19' +} + +//////////////// +////NDK Support +//////////////// +//If using this, Android studio will fail run the following to set the environment variable for android studio: +//launchctl setenv ANDROID_NDK_HOME +//otherwise remove the dependsOn part and run ./gradlew buildNative from the command line +task copyNativeLibs(type: Copy, dependsOn: 'buildNative') { + dependsOn 'buildNative' + from(new File('src/main/libs')) { include '**/*.so' exclude '**/libgnustl_shared.so' } + into new File(buildDir, 'native-libs') +} + +tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn copyNativeLibs } + +clean.dependsOn 'cleanCopyNativeLibs' + +tasks.withType(com.android.build.gradle.tasks.PackageApplication) { + pkgTask -> + pkgTask.jniFolders = new HashSet() + pkgTask.jniFolders.add(new File(buildDir, 'native-libs')) +} + +task buildNative(type: Exec) { + if (System.env.ANDROID_NDK_HOME != null) { + //for windows use 'ndk-build.cmd' + //def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd') + def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build') + commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", '-C', file('src/main').absolutePath + } else { + println '##################' + println 'Skipping NDK build' + println 'Reason: ANDROID_NDK_HOME not set.' + println '##################' + } +} diff --git a/service/resource-container/android/resource-container/proguard-rules.pro b/service/resource-container/android/resource-container/proguard-rules.pro new file mode 100644 index 0000000..c5f9a5b --- /dev/null +++ b/service/resource-container/android/resource-container/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:/android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/service/resource-container/android/resource-container/src/main/AndroidManifest.xml b/service/resource-container/android/resource-container/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d641087 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java new file mode 100644 index 0000000..670ceca --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java @@ -0,0 +1,96 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +/** + * @file + * This file contains RCSBundleInfo class, which provides APIs related to Bundle information. + */ +package org.iotivity.service.resourcecontainer; + +import org.iotivity.service.utils.RcsObject; + +/** + * This class provides APIs for getting and setting the Bundle Information + */ +public class RcsBundleInfo extends RcsObject { + private native String nativeGetID(); + + private native String nativeGetPath(); + + private native String nativeGetActivatorName(); + + private native String nativeGetLibraryPath(); + + private native String nativeGetVersion(); + + private RcsBundleInfo() { + } + + /** + * API for getting the Id of the bundle + * + * @return string - Id of the bundle + * + */ + public String getID() { + return nativeGetID(); + } + + /** + * API for getting the path of the bundle + * + * @return path - path of the bundle + * + */ + public String getPath() { + return nativeGetPath(); + } + + /** + * API for setting the Activator name for the bundle + * + * @return string - Name of the activator + * + */ + public String getActivatorName() { + return nativeGetActivatorName(); + } + + /** + * API for getting the library path for the bundle + * + * @return string - Library path in string form + * + */ + public String getLibraryPath() { + return nativeGetLibraryPath(); + } + + /** + * API for getting the version of the bundle + * + * @return string - version of the bundle + * + */ + public String getVersion() { + return nativeGetVersion(); + } + +} diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java new file mode 100644 index 0000000..bb19810 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java @@ -0,0 +1,214 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +/** + * @file + * This file contains the Resource Container APIs + */ +package org.iotivity.service.resourcecontainer; + +import java.util.List; +import java.util.Map; + +// TODO null check for parameters +/** + * This class provides APIs for managing the container and bundles in the + * container. + */ +public class RcsResourceContainer { + + static { + System.loadLibrary("gnustl_shared"); + System.loadLibrary("oc_logger"); + System.loadLibrary("connectivity_abstraction"); + System.loadLibrary("ca-interface"); + System.loadLibrary("octbstack"); + System.loadLibrary("oc"); + System.loadLibrary("rcs_client"); + System.loadLibrary("rcs_server"); + System.loadLibrary("rcs_common"); + System.loadLibrary("rcs_container"); + System.loadLibrary("resource_container_jni"); + } + + private static RcsResourceContainer sInstance = new RcsResourceContainer(); + + private native void nativeStartContainer(String configFile); + + private native void nativeStopContainer(); + + private native void nativeAddBundle(String bundleId, String bundleUri, + String bundlePath, String activator, Map params); + + private native void nativeRemoveBundle(String bundleId); + + private native List nativeListBundles(); + + private native void nativeStartBundle(String bundleId); + + private native void nativeStopBundle(String bundleId); + + private native void nativeAddResourceConfig(String bundleId, + String resourceUri, Map params); + + private native void nativeRemoveResourceConfig(String bundleId, + String resourceUri); + + private native List nativeListBundleResources(String bundleId); + + /** + * API for getting the Instance of ResourceContainer class + * + */ + public static RcsResourceContainer getInstance() { + return sInstance; + } + + /** + * API for starting the Container + * + *

+ * This API start the container with the provided Configuration file. + * + * @param configFile + * configuration File that contains the Bundle/Bundles + * information. + * + */ + public void startContainer(String configFile) { + nativeStartContainer(configFile); + } + + /** + * API for stopping the Container + */ + public void stopContainer() { + nativeStopContainer(); + } + + /** + * API for getting the list of all bundles in the container + * + * @return list -List of BundleInfo objects each associated + * with a bundle + * + * {@link RcsBundleInfo} + */ + public List listBundles() { + return nativeListBundles(); + } + + /** + * API for adding the bundle to the Container + * + * @param bundleId + * Id of the Bundle + * @param bundleUri + * Uri of the bundle + * @param bundlePath + * Path of the bundle + * @param activator + * Activation prefix for .so bundles, or activator class name for + * .jar bundles + * @param params + * key-value pairs in string form for other Bundle parameters + * + *

+ * It is dynamic configuration + */ + public void addBundle(String bundleId, String bundleUri, String bundlePath, + String activator, Map params) { + nativeAddBundle(bundleId, bundleUri, bundlePath, activator, params); + } + + /** + * API for removing the bundle from the container + * + * @param bundleId + * Id of the Bundle + * + */ + public void removeBundle(String bundleId) { + nativeRemoveBundle(bundleId); + } + + /** + * API for starting the bundle. + * + * @param bundleId + * Id of the Bundle + * + */ + public void startBundle(String bundleId) { + nativeStartBundle(bundleId); + } + + /** + * API for Stopping the bundle + * + * @param bundleId + * Id of the Bundle + * + */ + public void stopBundle(String bundleId) { + nativeStopBundle(bundleId); + } + + /** + * API for adding the Resource configuration information to the bundle + * + * @param bundleId + * Id of the Bundle + * @param resourceUri + * URI of the resource + * @param params + * key-value pairs in string form for other Bundle parameters + * + */ + public void addResourceConfig(String bundleId, String resourceUri, + Map params) { + nativeAddResourceConfig(bundleId, resourceUri, params); + } + + /** + * API for removing the Resource configuration information from the bundle + * + * @param bundleId + * Id of the Bundle + * @param resourceUri + * URI of the resource + * + */ + public void removeResourceConfig(String bundleId, String resourceUri) { + nativeRemoveResourceConfig(bundleId, resourceUri); + } + + /** + * API for getting the list of Bundle Resources + * + * @param bundleId + * Id of the Bundle + * + * @return List All the bundle resources + */ + public List listBundleResources(String bundleId) { + return nativeListBundleResources(bundleId); + } +} diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsException.java new file mode 100644 index 0000000..70b46c7 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsException.java @@ -0,0 +1,33 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +package org.iotivity.service.utils; + +/** + * An exception that indicates there was an error with execution of Rcs APIs. + */ +public class RcsException extends Exception { + + private static final long serialVersionUID = 7044421943523001940L; + + public RcsException(String message) { + super(message); + } +} diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsIllegalStateException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsIllegalStateException.java new file mode 100644 index 0000000..c6150f5 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsIllegalStateException.java @@ -0,0 +1,35 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +package org.iotivity.service.utils; + +/** + * Thrown when an action is attempted at a time when not in the correct state. + * + */ +public class RcsIllegalStateException extends RcsException { + + private static final long serialVersionUID = 6142669404885957616L; + + public RcsIllegalStateException(String message) { + super(message); + } + +} diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsObject.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsObject.java new file mode 100644 index 0000000..203651c --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsObject.java @@ -0,0 +1,58 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ +package org.iotivity.service.utils; + +public class RcsObject { + static { + System.loadLibrary("gnustl_shared"); + System.loadLibrary("oc_logger"); + System.loadLibrary("connectivity_abstraction"); + System.loadLibrary("ca-interface"); + System.loadLibrary("octbstack"); + System.loadLibrary("oc"); + System.loadLibrary("rcs_client"); + System.loadLibrary("rcs_server"); + System.loadLibrary("rcs_common"); + System.loadLibrary("rcs_container"); + System.loadLibrary("resource_container_jni"); + } + + private long mNativeHandle; + + private native void nativeDispose(); + + protected RcsObject() { + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + protected void dispose() { + if (mNativeHandle != 0L) nativeDispose(); + } + + protected boolean hasHandle() { + return mNativeHandle != 0L; + } +} diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsPlatformException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsPlatformException.java new file mode 100644 index 0000000..52297be --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/utils/RcsPlatformException.java @@ -0,0 +1,22 @@ +package org.iotivity.service.utils; + +/** + * Thrown when an operation that has base-layer dependency is failed. + * + */ +public class RcsPlatformException extends RcsException { + + private static final long serialVersionUID = -6093438347973754721L; + + private final int mReasonCode; + + public RcsPlatformException(String message, int reasonCode) { + super(message); + + mReasonCode = reasonCode; + } + + public int getReasonCode() { + return mReasonCode; + } +} diff --git a/service/resource-container/android/resource-container/src/main/jni/Android.mk b/service/resource-container/android/resource-container/src/main/jni/Android.mk new file mode 100644 index 0000000..7a01fc1 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/Android.mk @@ -0,0 +1,35 @@ +LOCAL_PATH := $(call my-dir) + +ROOT_PATH := ../../../../../../.. +IOTIVITY_LIB_PATH := $(ROOT_PATH)/out/android/$(TARGET_ARCH_ABI)/$(APP_OPTIM) + +include $(CLEAR_VARS) +LOCAL_MODULE := rcs_container +LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_container.so +include $(PREBUILT_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_LDLIBS := -L$(LOCAL_PATH)/$(IOTIVITY_LIB_PATH)/ +LOCAL_LDLIBS += -lrcs_common + +OIC_SRC_DIR := ../../../../../.. +LOCAL_MODULE := resource_container_jni + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/util +LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/c_common +LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/csdk/stack/include +LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/extlibs/boost/boost_1_58_0 +LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-encapsulation/include +LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-container/include +LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-encapsulation/src/serverBuilder/include + +LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/util/*.cpp)) +LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/*.cpp)) + +LOCAL_CPPFLAGS := -std=c++0x -frtti -fexceptions + +LOCAL_LDLIBS += -llog + +LOCAL_SHARED_LIBRARIES += rcs_container + +include $(BUILD_SHARED_LIBRARY) diff --git a/service/resource-container/android/resource-container/src/main/jni/Application.mk b/service/resource-container/android/resource-container/src/main/jni/Application.mk new file mode 100644 index 0000000..c177a13 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/Application.mk @@ -0,0 +1,2 @@ +NDK_TOOLCHAIN_VERSION := 4.9 +APP_STL := gnustl_shared diff --git a/service/resource-container/android/resource-container/src/main/jni/JniMain.cpp b/service/resource-container/android/resource-container/src/main/jni/JniMain.cpp new file mode 100644 index 0000000..16b6894 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniMain.cpp @@ -0,0 +1,88 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "JniRcsObject.h" + +#include "JniRcsResourceContainer.h" +#include "JavaClasses.h" +#include "JavaExceptions.h" +#include "JNIEnvWrapper.h" +#include "Log.h" + +#define LOG_TAG "JNI-Main" + +#define JNI_CURRENT_VERSION JNI_VERSION_1_6 + +JavaVM *g_jvm; + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) +{ + LOGI("JNI_OnLoad"); + JNIEnv *env; + g_jvm = vm; + + if (g_jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK) + { + LOGE("Failed to get the environment using GetEnv()"); + return JNI_ERR; + } + + JNIEnvWrapper envWrapper { env }; + + try + { + initJavaClasses(&envWrapper); + initJavaExceptions(&envWrapper); + initRCSObject(&envWrapper); + initRCSResourceContainer(&envWrapper); + } + catch (const JavaException &) + { + if (env->ExceptionCheck()) env->ExceptionDescribe(); + return JNI_ERR; + } + + return JNI_CURRENT_VERSION; +} + +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) +{ + LOGI("JNI_OnUnload"); + JNIEnv *env; + + if (g_jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK) + { + LOGE("Failed to get the environment using GetEnv()"); + return; + } + + JNIEnvWrapper envWrapper { env }; + + try + { + clearRCSResourceContainer(&envWrapper); + clearRCSObject(&envWrapper); + clearJavaExceptions(&envWrapper); + clearJavaClasses(&envWrapper); + } + catch (const JavaException &) + { + } +} diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsBundleInfo.cpp b/service/resource-container/android/resource-container/src/main/jni/JniRcsBundleInfo.cpp new file mode 100644 index 0000000..7bbac93 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniRcsBundleInfo.cpp @@ -0,0 +1,100 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "JniRcsBundleInfo.h" + +#include "Log.h" +#include "Verify.h" +#include "JniRcsObject.h" + +#include "RCSBundleInfo.h" + +#define LOG_TAG "JNI-RCSBundleInfo" + +using namespace OIC::Service; + +namespace +{ + RCSBundleInfo *getNativeBundleInfo(JNIEnv *env, jobject obj) + { + return getNativeHandleAs< RCSBundleInfo * >(env, obj); + } +} + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetID +(JNIEnv *env, jobject obj) +{ + LOGI("nativeGetID"); + + auto bundleInfo = getNativeBundleInfo(env, obj); + VERIFY_NO_EXC_RET_DEF(env); + + return newStringObject(env, bundleInfo->getID()); +} + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetPath +(JNIEnv *env, jobject obj) +{ + LOGI("nativeGetPath"); + + auto bundleInfo = getNativeBundleInfo(env, obj); + VERIFY_NO_EXC_RET_DEF(env); + + return newStringObject(env, bundleInfo->getPath()); +} + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetActivatorName +(JNIEnv *env, jobject obj) +{ + LOGI("nativeGetActivatorName"); + + auto bundleInfo = getNativeBundleInfo(env, obj); + VERIFY_NO_EXC_RET_DEF(env); + + return newStringObject(env, bundleInfo->getActivatorName()); +} + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetLibraryPath +(JNIEnv *env, jobject obj) +{ + LOGI("nativeGetLibraryPath"); + + auto bundleInfo = getNativeBundleInfo(env, obj); + VERIFY_NO_EXC_RET_DEF(env); + + return newStringObject(env, bundleInfo->getLibraryPath()); +} + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetVersion +(JNIEnv *env, jobject obj) +{ + LOGI("nativeGetVersion"); + + auto bundleInfo = getNativeBundleInfo(env, obj); + VERIFY_NO_EXC_RET_DEF(env); + + return newStringObject(env, bundleInfo->getVersion()); +} + diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsBundleInfo.h b/service/resource-container/android/resource-container/src/main/jni/JniRcsBundleInfo.h new file mode 100644 index 0000000..83b5dcd --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniRcsBundleInfo.h @@ -0,0 +1,60 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +/** @file jni_re_rcs_bundle_info.h + * + * @brief This file contains the JniBundleInfo class + * & declaration of RCSBundleInfo APIs for JNI implementation + */ + +#ifndef JNI_RCS_BUNDLE_INFO_H_ +#define JNI_RCS_BUNDLE_INFO_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetID +(JNIEnv *, jobject); + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetPath +(JNIEnv *, jobject); + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetActivatorName +(JNIEnv *, jobject); + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetLibraryPath +(JNIEnv *, jobject); + +JNIEXPORT jstring JNICALL +Java_org_iotivity_service_resourcecontainer_RcsBundleInfo_nativeGetVersion +(JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif // JNI_RCS_BUNDLE_INFO_H_ + diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.cpp b/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.cpp new file mode 100644 index 0000000..7a3c014 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.cpp @@ -0,0 +1,48 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "JniRcsObject.h" + +#include "JavaClasses.h" +#include "JNIEnvWrapper.h" +#include "Log.h" +#include "Verify.h" + +#define LOG_TAG "JNI-RCSObject" + +jfieldID g_field_mNativeHandle; + +void initRCSObject(JNIEnvWrapper *env) +{ + auto clsRCSObject = env->FindClass(PACKAGE_NAME "/utils/RcsObject"); + + g_field_mNativeHandle = env->GetFieldID(clsRCSObject, "mNativeHandle", "J"); +} + +void clearRCSObject(JNIEnvWrapper *env) +{ +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_utils_RcsObject_nativeDispose(JNIEnv *env, jobject obj) +{ + LOGD("release nativeHandle!"); + releaseNativeHandle(env, obj); +} diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.h b/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.h new file mode 100644 index 0000000..cfa7a71 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.h @@ -0,0 +1,125 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef JNI_RCS_OBJECT_H_ +#define JNI_RCS_OBJECT_H_ + +#include + +#include + +#include "JavaClasses.h" +#include "JNIEnvWrapper.h" + +extern jfieldID g_field_mNativeHandle; + +void initRCSObject(JNIEnvWrapper *); +void clearRCSObject(JNIEnvWrapper *); + +namespace Detail +{ + struct BaseHandleHolder + { + virtual ~BaseHandleHolder() {} + }; + + template< typename T > + struct HandleHolder: public BaseHandleHolder + { + HandleHolder(T *ptr) : m_ptr { ptr } {} + + virtual ~HandleHolder() { delete m_ptr; } + + T *m_ptr; + }; + + template< typename ENV > + void *getNativeHandle(ENV *env, jobject obj) + { + return reinterpret_cast< void * >(env->GetLongField(obj, g_field_mNativeHandle)); + } +} + +template< typename ENV > +bool hasNativeHandle(ENV *env, jobject obj) +{ + return Detail::getNativeHandle(env, obj) != nullptr; +} + +template< typename T, typename ENV, typename ...PARAMS > +inline void setSafeNativeHandle(ENV *env, jobject obj, PARAMS &&... params) +{ + static_assert(!std::is_array< T >::value, "Array is not supported!"); + + std::unique_ptr< Detail::HandleHolder< T > > p( + new Detail::HandleHolder< T > { new T{ std::forward< PARAMS >(params)... } }); + + env->SetLongField(obj, g_field_mNativeHandle, reinterpret_cast< jlong >(p.get())); + + if (env->ExceptionCheck()) return; + + p.release(); +} + +template< typename ENV > +void releaseNativeHandle(ENV *env, jobject obj) +{ + auto handleHolder = reinterpret_cast< Detail::BaseHandleHolder * >( + env->GetLongField(obj, g_field_mNativeHandle)); + + delete handleHolder; + + env->SetLongField(obj, g_field_mNativeHandle, 0); +} + + +template< typename T > +inline T &getNativeHandleAs(JNIEnv *env, jobject obj) +{ + auto handleHolder = static_cast< Detail::HandleHolder< T >* >(Detail::getNativeHandle(env, obj)); + + if (!handleHolder) + { + env->ThrowNew(env->FindClass(EXC_NAME_ILLEGAL_STATE), "Internal handle is null!"); + } + + return *handleHolder->m_ptr; +} + +template< typename T > +inline T &getNativeHandleAs(JNIEnvWrapper *env, jobject obj) +{ + getNativeHandleAs< T >(env->get(), obj); + if (env->ExceptionCheck()) throw JavaException(); +} + + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void JNICALL +Java_org_iotivity_service_utils_RcsObject_nativeDispose(JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif + +#endif // JNI_RCS_OBJECT_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.cpp b/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.cpp new file mode 100644 index 0000000..5b829d7 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.cpp @@ -0,0 +1,287 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "JniRcsResourceContainer.h" + +#include "JavaLocalRef.h" +#include "JNIEnvWrapper.h" +#include "Log.h" +#include "Verify.h" +#include "JniRcsObject.h" + +#include "RCSResourceContainer.h" +#include "RCSBundleInfo.h" + +#define LOG_TAG "JNI-RCSResourceContainer" + +using namespace OIC::Service; + +#define CLS_NAME_BUNDLE_INFO PACKAGE_NAME "/resourcecontainer/RcsBundleInfo" + +#include + + + +namespace +{ + jclass g_cls_RCSBundleInfo; + + jmethodID g_ctor_RCSBundleInfo; + + std::map< std::string, std::string > convertJavaMapToParamsMap(JNIEnvWrapper *env, + jobject mapObj) + { + EXPECT_RET_DEF(mapObj, "map is null"); + + auto setObj = invoke_Map_entrySet(env, mapObj); + auto iterObj = invoke_Set_iterator(env, setObj); + + std::map< std::string, std::string > ret; + + while (invoke_Iterator_hasNext(env, iterObj)) + { + JavaLocalObject entryObj { env, invoke_Iterator_next(env, iterObj) }; + + JavaLocalString keyObj { env, + static_cast< jstring >(invoke_MapEntry_getKey(env, entryObj)) + }; + JavaLocalString valueObj { env, + static_cast< jstring >(invoke_MapEntry_getValue(env, entryObj)) + }; + + ret.emplace(toStdString(env, keyObj), toStdString(env, valueObj)); + } + + return ret; + } +} + +void initRCSResourceContainer(JNIEnvWrapper *env) +{ + g_cls_RCSBundleInfo = env->FindClassAsGlobalRef(CLS_NAME_BUNDLE_INFO); + + g_ctor_RCSBundleInfo = env->GetConstructorID(g_cls_RCSBundleInfo, "()V"); +} + +void clearRCSResourceContainer(JNIEnvWrapper *env) +{ + env->DeleteGlobalRef(g_cls_RCSBundleInfo); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartContainer +(JNIEnv *env, jobject, jstring configFileObj) +{ + LOGD("nativeStartContainer"); + + EXPECT(configFileObj, "ConfigFile is null."); + + auto configFile = toStdString(env, configFileObj); + // std::string nativeFilePath = env->GetStringUTFChars(configFile, NULL); + VERIFY_NO_EXC(env); + + RCSResourceContainer::getInstance()->startContainer(configFile); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopContainer +(JNIEnv *env, jobject) +{ + LOGD("nativeStopContainers"); + + RCSResourceContainer::getInstance()->stopContainer(); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddBundle +(JNIEnv *env, jobject, jstring idObj, jstring uriObj, jstring pathObj, jstring activatorObj, + jobject paramsObj) +{ + LOGD("nativeAddBundle"); + + EXPECT(idObj, "BundleId is null."); + EXPECT(pathObj, "BundlePath is null."); + EXPECT(activatorObj, "Activator is null."); + + JNIEnvWrapper envWrapper(env); + + try + { + LOGD("nativeAddBundle before calling native"); + RCSResourceContainer::getInstance()->addBundle(toStdString(&envWrapper, idObj), + toStdString(&envWrapper, uriObj), toStdString(&envWrapper, pathObj), + toStdString(&envWrapper, activatorObj), + convertJavaMapToParamsMap(&envWrapper, paramsObj)); + + LOGD("nativeAddBundle after calling native"); + } + catch (const JavaException &) + { + LOGE("Failed to add bundle."); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveBundle +(JNIEnv *env, jobject, jstring idObj) +{ + LOGD("nativeRemoveBundle"); + + EXPECT(idObj, "BundleId is null."); + + auto id = toStdString(env, idObj); + VERIFY_NO_EXC(env); + + RCSResourceContainer::getInstance()->removeBundle(id); +} + + +JNIEXPORT jobject JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundles +(JNIEnv *env, jobject) +{ + LOGD("nativeListBundles"); + + JNIEnvWrapper envWrapper(env); + + try + { + auto listObj = newArrayList(&envWrapper); + + for (auto& uniqeBundleInfo : RCSResourceContainer::getInstance()->listBundles()) + { + RCSBundleInfo* bundleInfo = uniqeBundleInfo.release(); + JavaLocalObject bundleInfoObj { &envWrapper, + envWrapper.NewObject(g_cls_RCSBundleInfo, g_ctor_RCSBundleInfo) }; + + setSafeNativeHandle< RCSBundleInfo* >(&envWrapper, bundleInfoObj, bundleInfo); + + invoke_Collection_add(&envWrapper, listObj, bundleInfoObj); + } + return listObj; + } + catch (const JavaException &) + { + LOGE("Failed to convert bundle info list."); + } + return nullptr; +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartBundle +(JNIEnv *env, jobject, jstring idObj) +{ + LOGD("nativeStartBundle"); + + EXPECT(idObj, "BundleId is null."); + + auto id = env->GetStringUTFChars(idObj, NULL); + VERIFY_NO_EXC(env); + + RCSResourceContainer::getInstance()->startBundle(id); +} +JNICALL +JNIEXPORT void +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopBundle +(JNIEnv *env, jobject, jstring idObj) +{ + LOGD("nativeStopBundle"); + + EXPECT(idObj, "BundleId is null."); + + auto id = env->GetStringUTFChars(idObj, NULL); + VERIFY_NO_EXC(env); + + RCSResourceContainer::getInstance()->stopBundle(id); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddResourceConfig +(JNIEnv *env, jobject, jstring idObj, jstring uriObj, jobject paramsObj) +{ + LOGD("nativeAddResourceConfig"); + + EXPECT(idObj, "BundleId is null."); + EXPECT(uriObj, "BundleUri is null."); + EXPECT(paramsObj, "Params is null."); + + JNIEnvWrapper envWrapper(env); + + try + { + RCSResourceContainer::getInstance()->addResourceConfig(toStdString(&envWrapper, idObj), + toStdString(&envWrapper, uriObj), convertJavaMapToParamsMap(&envWrapper, paramsObj)); + } + catch (const JavaException &) + { + LOGE("Failed to add bundle."); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveResourceConfig +(JNIEnv *env, jobject, jstring idObj, jstring uriObj) +{ + LOGD("nativeRemoveResourceConfig"); + + EXPECT(idObj, "BundleId is null."); + EXPECT(uriObj, "BundleUri is null."); + + auto id = toStdString(env, idObj); + VERIFY_NO_EXC(env); + auto uri = toStdString(env, uriObj); + VERIFY_NO_EXC(env); + + RCSResourceContainer::getInstance()->removeResourceConfig(id, uri); +} + +JNIEXPORT jobject JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundleResources +(JNIEnv *env, jobject, jstring idObj) +{ + LOGD("nativeListBundleResources"); + + EXPECT_RET_DEF(idObj, "BundleId is null."); + + JNIEnvWrapper envWrapper(env); + + try + { + auto id = toStdString(&envWrapper, idObj); + + auto listObj = newArrayList(&envWrapper); + + for (const auto & s : RCSResourceContainer::getInstance()->listBundleResources(id)) + { + JavaLocalString strObj { &envWrapper, newStringObject(&envWrapper, s) }; + + invoke_Collection_add(&envWrapper, listObj, strObj); + } + + return listObj; + } + catch (const JavaException &) + { + LOGE("Failed to convert bundle info list."); + } + + return nullptr; +} + diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.h b/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.h new file mode 100644 index 0000000..2474b7e --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.h @@ -0,0 +1,85 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +/** @file jni_re_rcs_resource_container.h + * + * @brief This file contains the declaration of RCSResourceContainer + * APIs for JNI implementation + */ + +#ifndef JNI_RCS_RESOURCE_CONTAINER_H_ +#define JNI_RCS_RESOURCE_CONTAINER_H_ + +#include + +class JNIEnvWrapper; + +void initRCSResourceContainer(JNIEnvWrapper *); +void clearRCSResourceContainer(JNIEnvWrapper *); + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartContainer +(JNIEnv *, jobject, jstring configFile); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopContainer +(JNIEnv *, jobject); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddBundle +(JNIEnv *, jobject, jstring bundleId, jstring bundleUri, jstring bundlePath, jstring activator, + jobject params); + +JNIEXPORT jobject JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundles +(JNIEnv *, jobject); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveBundle +(JNIEnv *, jobject, jstring bundleId); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartBundle +(JNIEnv *, jobject, jstring bundleId); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopBundle +(JNIEnv *, jobject, jstring bundleId); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddResourceConfig +(JNIEnv *, jobject, jstring bundleId, jstring resourceUri, jobject params); + +JNIEXPORT void JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveResourceConfig +(JNIEnv *, jobject, jstring bundleId, jstring resourceUri); + +JNIEXPORT jobject JNICALL +Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundleResources +(JNIEnv *, jobject, jstring bundleId); + +#ifdef __cplusplus +} +#endif +#endif //JNI_RCS_RESOURCE_CONTAINER_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JNIEnvWrapper.h b/service/resource-container/android/resource-container/src/main/jni/util/JNIEnvWrapper.h new file mode 100644 index 0000000..9a4d413 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JNIEnvWrapper.h @@ -0,0 +1,392 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef RCS_JNI_ENV_WRAPPER_H_ +#define RCS_JNI_ENV_WRAPPER_H_ + +#include + +#include + +#include "JavaLocalRef.h" + +class JavaException: public std::exception +{ +}; + +class JNIEnvWrapper +{ + public: + JNIEnvWrapper() noexcept : m_env { } {} + JNIEnvWrapper(JNIEnv *env) noexcept : m_env { env } {} + + JNIEnvWrapper &operator=(JNIEnv *env) noexcept + { + m_env = env; + return *this; + } + + jboolean IsSameObject(jobject lhs, jobject rhs) + { + return m_env->IsSameObject(lhs, rhs); + } + + jclass GetObjectClass(jobject obj) + { + auto ret = m_env->GetObjectClass(obj); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jclass FindClass(const char *name) + { + auto ret = m_env->FindClass(name); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jclass FindClassAsGlobalRef(const char *name) + { + JavaLocalClass cls { m_env, FindClass(name) }; + + return NewGlobalRef(cls); + } + + jobject NewGlobalRef(jobject obj) + { + auto ret = m_env->NewGlobalRef(obj); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + template + T NewGlobalRef(T obj) + { + auto ret = static_cast< T >(m_env->NewGlobalRef(obj)); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + template + T NewGlobalRef(const JavaLocalRef< T > &obj) + { + auto ret = static_cast< T >(m_env->NewGlobalRef(obj)); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + void DeleteGlobalRef(jobject obj) + { + m_env->DeleteGlobalRef(obj); + } + + jobject NewObject(jclass cls, jmethodID ctor, ...) + { + va_list args; + va_start(args, ctor); + auto ret = m_env->NewObjectV(cls, ctor, args); + va_end(args); + + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jstring NewStringUTF(const char *str) + { + auto ret = m_env->NewStringUTF(str); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + const char *GetStringUTFChars(jstring str, jboolean *isCopy) + { + auto ret = m_env->GetStringUTFChars(str, isCopy); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + void ReleaseStringUTFChars(jstring str, const char *chars) + { + m_env->ReleaseStringUTFChars(str, chars); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + jmethodID GetConstructorID(jclass cls, const char *sig) + { + auto ret = m_env->GetMethodID(cls, "", sig); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jmethodID GetMethodID(jclass cls, const char *name, const char *sig) + { + auto ret = m_env->GetMethodID(cls, name, sig); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jmethodID GetStaticMethodID(jclass cls, const char *name, const char *sig) + { + auto ret = m_env->GetStaticMethodID(cls, name, sig); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + + jfieldID GetFieldID(jclass cls, const char *name, const char *sig) + { + auto ret = m_env->GetFieldID(cls, name, sig); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jfieldID GetStaticFieldID(jclass cls, const char *name, const char *sig) + { + auto ret = m_env->GetStaticFieldID(cls, name, sig); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jobject GetStaticObjectField(jclass cls, jfieldID fieldId) + { + auto ret = m_env->GetStaticObjectField(cls, fieldId); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jobject GetStaticObjectField(jclass cls, const char *name, const char *sig) + { + return GetStaticObjectField(cls, GetStaticFieldID(cls, name, sig)); + } + + jint GetIntField(jobject obj, jfieldID fieldId) + { + auto ret = m_env->GetIntField(obj, fieldId); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jlong GetLongField(jobject obj, jfieldID fieldId) + { + auto ret = m_env->GetLongField(obj, fieldId); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + void SetLongField(jobject obj, jfieldID fieldId, jlong val) + { + m_env->SetLongField(obj, fieldId, val); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + jobject GetObjectField(jobject obj, jfieldID fieldId) + { + auto ret = m_env->GetObjectField(obj, fieldId); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jint CallStaticIntMethod(jclass cls, jmethodID methodId, ...) + { + va_list args; + va_start(args, methodId); + auto ret = m_env->CallStaticIntMethodV(cls, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jobject CallStaticObjectMethod(jclass cls, jmethodID methodId, ...) + { + va_list args; + va_start(args, methodId); + auto ret = m_env->CallStaticObjectMethodV(cls, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + void CallVoidMethod(jobject obj, jmethodID methodId, ...) + { + va_list args; + va_start(args, methodId); + m_env->CallVoidMethodV(obj, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + jboolean CallBooleanMethod(jobject obj, jmethodID methodId, ...) + { + va_list args; + va_start(args, methodId); + auto ret = m_env->CallBooleanMethodV(obj, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jint CallIntMethod(jobject obj, jmethodID methodId, ...) + { + va_list args; + va_start(args, methodId); + auto ret = m_env->CallIntMethod(obj, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodId, ...) + { + va_list args; + va_start(args , methodId); + auto ret = m_env->CallDoubleMethod(obj, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + + jobject CallObjectMethod(jobject obj, jmethodID methodId, ...) + { + va_list args; + va_start(args, methodId); + auto ret = m_env->CallObjectMethodV(obj, methodId, args); + va_end(args); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jbooleanArray NewBooleanArray(jsize len) + { + auto ret = m_env->NewBooleanArray(len); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jintArray NewIntArray(jsize len) + { + auto ret = m_env->NewIntArray(len); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jdoubleArray NewDoubleArray(jsize len) + { + auto ret = m_env->NewDoubleArray(len); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jobjectArray NewObjectArray(jsize len, jclass cls, jobject init) + { + auto ret = m_env->NewObjectArray(len, cls, init); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jsize GetArrayLength(jarray array) + { + auto ret = m_env->GetArrayLength(array); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + jobject GetObjectArrayElement(jobjectArray array, jsize index) + { + auto ret = m_env->GetObjectArrayElement(array, index); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + void SetObjectArrayElement(jobjectArray array, jsize index, jobject val) + { + m_env->SetObjectArrayElement(array, index, val); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, const jboolean *buf) + { + m_env->SetBooleanArrayRegion(array, start, len, buf); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + void SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint *buf) + { + m_env->SetIntArrayRegion(array, start, len, buf); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, const jdouble *buf) + { + m_env->SetDoubleArrayRegion(array, start, len, buf); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + void *GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) + { + auto ret = m_env->GetPrimitiveArrayCritical(array, isCopy); + if (m_env->ExceptionCheck()) throw JavaException(); + return ret; + } + + void ReleasePrimitiveArrayCritical(jarray array, void *carray, int mode) + { + m_env->ReleasePrimitiveArrayCritical(array, carray, mode); + if (m_env->ExceptionCheck()) throw JavaException(); + } + + void ThrowNew(jclass cls, const char *msg) + { + m_env->ThrowNew(cls, msg); + throw JavaException(); + } + + void ExceptionDescribe() const noexcept + { + m_env->ExceptionDescribe(); + } + + void ExceptionClear() noexcept + { + m_env->ExceptionClear(); + } + + jboolean ExceptionCheck() const noexcept + { + return m_env->ExceptionCheck(); + } + + operator bool() const noexcept + { + return m_env != nullptr; + } + + JNIEnv *get() const + { + return m_env; + } + + private: + JNIEnv *m_env; +}; + + + +#endif // RCS_JNI_ENV_WRAPPER_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.cpp b/service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.cpp new file mode 100644 index 0000000..f84f4d9 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.cpp @@ -0,0 +1,119 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "JavaClasses.h" + +#include "JNIEnvWrapper.h" + +jclass g_cls_String; +jclass g_cls_Integer; +jclass g_cls_Double; +jclass g_cls_Boolean; + +jclass g_cls_ArrayList; +jclass g_cls_Set; +jclass g_cls_Map; +jclass g_cls_MapEntry; +jclass g_cls_Iterator; + +jmethodID g_method_Boolean_booleanValue; +jmethodID g_method_Integer_intValue; +jmethodID g_method_Double_doubleValue; + +jmethodID g_method_Collection_add; + +jmethodID g_method_Set_iterator; + +jmethodID g_method_Map_entrySet; +jmethodID g_method_Map_put; + +jmethodID g_method_MapEntry_getKey; +jmethodID g_method_MapEntry_getValue; + +jmethodID g_method_Iterator_hasNext; +jmethodID g_method_Iterator_next; + +jmethodID g_ctor_Boolean; +jmethodID g_ctor_Integer; +jmethodID g_ctor_Double; + +jmethodID g_ctor_ArrayList; + +namespace +{ + inline void initPrimitiveTypes(JNIEnvWrapper *env) + { + g_cls_Boolean = env->FindClassAsGlobalRef(CLS_NAME_BOOLEAN); + g_ctor_Boolean = env->GetConstructorID(g_cls_Boolean, "(Z)V"); + g_method_Boolean_booleanValue = env->GetMethodID(g_cls_Boolean, "booleanValue", "()Z"); + + g_cls_Integer = env->FindClassAsGlobalRef(CLS_NAME_INTEGER); + g_ctor_Integer = env->GetConstructorID(g_cls_Integer, "(I)V"); + g_method_Integer_intValue = env->GetMethodID(g_cls_Integer, "intValue", "()I"); + + g_cls_Double = env->FindClassAsGlobalRef(CLS_NAME_DOUBLE); + g_ctor_Double = env->GetConstructorID(g_cls_Double, "(D)V"); + g_method_Double_doubleValue = env->GetMethodID(g_cls_Double, "doubleValue", "()D"); + + g_cls_String = env->FindClassAsGlobalRef(CLS_NAME_STRING); + } +} + +void initJavaClasses(JNIEnvWrapper *env) +{ + initPrimitiveTypes(env); + + auto clsCollection = env->FindClass(CLS_NAME_COLLECTION); + g_method_Collection_add = env->GetMethodID(clsCollection, "add", + "(" AS_SIG(CLS_NAME_OBJECT) ")Z"); + + g_cls_ArrayList = env->FindClassAsGlobalRef(CLS_NAME_ARRAY_LIST); + g_ctor_ArrayList = env->GetConstructorID(g_cls_ArrayList, "()V"); + + g_cls_Set = env->FindClassAsGlobalRef(CLS_NAME_SET); + g_method_Set_iterator = env->GetMethodID(g_cls_Set, "iterator", "()" AS_SIG(CLS_NAME_ITERATOR)); + + g_cls_Map = env->FindClassAsGlobalRef(CLS_NAME_MAP); + g_method_Map_entrySet = env->GetMethodID(g_cls_Map, "entrySet", "()" AS_SIG(CLS_NAME_SET)); + g_method_Map_put = env->GetMethodID(g_cls_Map, "put", + "(" AS_SIG(CLS_NAME_OBJECT) AS_SIG(CLS_NAME_OBJECT) ")" AS_SIG(CLS_NAME_OBJECT)); + + g_cls_MapEntry = env->FindClassAsGlobalRef(CLS_NAME_MAP_ENTRY); + g_method_MapEntry_getKey = env->GetMethodID(g_cls_MapEntry, "getKey", + "()" AS_SIG(CLS_NAME_OBJECT)); + g_method_MapEntry_getValue = env->GetMethodID(g_cls_MapEntry, "getValue", + "()" AS_SIG(CLS_NAME_OBJECT)); + + g_cls_Iterator = env->FindClassAsGlobalRef(CLS_NAME_ITERATOR); + g_method_Iterator_hasNext = env->GetMethodID(g_cls_Iterator, "hasNext", "()Z"); + g_method_Iterator_next = env->GetMethodID(g_cls_Iterator, "next", "()" AS_SIG(CLS_NAME_OBJECT)); +} + +void clearJavaClasses(JNIEnvWrapper *env) +{ + env->DeleteGlobalRef(g_cls_Boolean); + env->DeleteGlobalRef(g_cls_Integer); + env->DeleteGlobalRef(g_cls_Double); + env->DeleteGlobalRef(g_cls_String); + env->DeleteGlobalRef(g_cls_Set); + env->DeleteGlobalRef(g_cls_Map); + env->DeleteGlobalRef(g_cls_MapEntry); + env->DeleteGlobalRef(g_cls_Iterator); +} diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.h b/service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.h new file mode 100644 index 0000000..b91ffea --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.h @@ -0,0 +1,206 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef JAVA_CLASSES_H_ +#define JAVA_CLASSES_H_ + +#include + +#include + +#define PACKAGE_NAME "org/iotivity/service" + +#define CLS_NAME_OBJECT "java/lang/Object" +#define CLS_NAME_STRING "java/lang/String" +#define CLS_NAME_INTEGER "java/lang/Integer" +#define CLS_NAME_DOUBLE "java/lang/Double" +#define CLS_NAME_BOOLEAN "java/lang/Boolean" + +#define CLS_NAME_COLLECTION "java/util/Collection" +#define CLS_NAME_ARRAY_LIST "java/util/ArrayList" +#define CLS_NAME_SET "java/util/Set" +#define CLS_NAME_MAP "java/util/Map" +#define CLS_NAME_MAP_ENTRY "java/util/Map$Entry" +#define CLS_NAME_ITERATOR "java/util/Iterator" + +#define EXC_NAME_RCS PACKAGE_NAME "/utils/RcsException" +#define EXC_NAME_PLATFORM PACKAGE_NAME "/utils/RcsPlatformException" +#define EXC_NAME_ILLEGAL_STATE PACKAGE_NAME "/utils/RcsIllegalStateException" + +#define AS_SIG(CLS_NAME) "L" CLS_NAME ";" + +class JNIEnvWrapper; + +extern jclass g_cls_Integer; +extern jclass g_cls_Double; +extern jclass g_cls_Boolean; +extern jclass g_cls_String; + +extern jclass g_cls_ArrayList; +extern jclass g_cls_Set; +extern jclass g_cls_Map; +extern jclass g_cls_MapEntry; +extern jclass g_cls_Iterator; + +extern jmethodID g_method_Boolean_booleanValue; +extern jmethodID g_method_Integer_intValue; +extern jmethodID g_method_Double_doubleValue; + +extern jmethodID g_method_Collection_add; + +extern jmethodID g_method_Set_iterator; + +extern jmethodID g_method_Map_entrySet; +extern jmethodID g_method_Map_put; + +extern jmethodID g_method_MapEntry_getKey; +extern jmethodID g_method_MapEntry_getValue; + +extern jmethodID g_method_Iterator_hasNext; +extern jmethodID g_method_Iterator_next; + +extern jmethodID g_ctor_Boolean; +extern jmethodID g_ctor_Integer; +extern jmethodID g_ctor_Double; + +extern jmethodID g_ctor_ArrayList; + +void initJavaClasses(JNIEnvWrapper *); +void clearJavaClasses(JNIEnvWrapper *); + +template< typename ENV > +inline jobject newBooleanObject(ENV *env, bool value) +{ + return env->NewObject(g_cls_Boolean, g_ctor_Boolean, value); +} + +template< typename ENV > +inline jobject newIntegerObject(ENV *env, int value) +{ + return env->NewObject(g_cls_Integer, g_ctor_Integer, value); +} + +template< typename ENV > +inline jobject newDoubleObject(ENV *env, double value) +{ + return env->NewObject(g_cls_Double, g_ctor_Double, value); +} + +template< typename ENV > +inline jstring newStringObject(ENV *env, const std::string &value) +{ + return env->NewStringUTF(value.c_str()); +} + +template< typename ENV > +inline jstring newStringObjectCstr(ENV *env, const char *value) +{ + return env->NewStringUTF(value); +} + +template< typename ENV > +inline std::string toStdString(ENV *env, jstring obj) +{ + if (!obj) return ""; + + auto cstr = env->GetStringUTFChars(obj, nullptr); + + if (!cstr) return ""; + + std::string result { cstr }; + + env->ReleaseStringUTFChars(obj, cstr); + + return result; +} + +template< typename ENV > +inline jobject newArrayList(ENV *env) +{ + return env->NewObject(g_cls_ArrayList, g_ctor_ArrayList); +} + +template< typename ENV > +inline bool invoke_Boolean_booleanValue(ENV *env, jobject obj) +{ + return env->CallBooleanMethod(obj, g_method_Boolean_booleanValue); +} + +template< typename ENV > +inline int invoke_Integer_intValue(ENV *env, jobject obj) +{ + return env->CallIntMethod(obj, g_method_Integer_intValue); +} + +template< typename ENV > +inline double invoke_Double_doubleValue(ENV *env, jobject obj) +{ + return env->CallDoubleMethod(obj, g_method_Double_doubleValue); +} + +template< typename ENV > +inline jboolean invoke_Collection_add(ENV *env, jobject collectionObj, jobject valueObj) +{ + return env->CallBooleanMethod(collectionObj, g_method_Collection_add, valueObj); +} + +template< typename ENV > +inline jobject invoke_Map_entrySet(ENV *env, jobject mapObj) +{ + return env->CallObjectMethod(mapObj, g_method_Map_entrySet); +} + +template< typename ENV > +inline jobject invoke_Map_put(ENV *env, jobject mapObj, jobject keyObj, jobject valueObj) +{ + return env->CallObjectMethod(mapObj, g_method_Map_put, keyObj, valueObj); +} + +template< typename ENV > +inline jobject invoke_MapEntry_getKey(ENV *env, jobject entryObj) +{ + return env->CallObjectMethod(entryObj, g_method_MapEntry_getKey); +} + +template< typename ENV > +inline jobject invoke_MapEntry_getValue(ENV *env, jobject entryObj) +{ + return env->CallObjectMethod(entryObj, g_method_MapEntry_getValue); +} + +template< typename ENV > +inline jobject invoke_Set_iterator(ENV *env, jobject setObj) +{ + return env->CallObjectMethod(setObj, g_method_Set_iterator); +} + +template< typename ENV > +inline bool invoke_Iterator_hasNext(ENV *env, jobject iterObj) +{ + return env->CallBooleanMethod(iterObj, g_method_Iterator_hasNext); +} + +template< typename ENV > +inline jobject invoke_Iterator_next(ENV *env, jobject iterObj) +{ + return env->CallObjectMethod(iterObj, g_method_Iterator_next); +} + +#endif // JAVA_CLASSES_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.cpp b/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.cpp new file mode 100644 index 0000000..4774a72 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.cpp @@ -0,0 +1,57 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#include "JavaExceptions.h" + +#include "JNIEnvWrapper.h" +#include "Verify.h" + +#include "RCSException.h" + +namespace +{ + jclass g_cls_PlatformException; + + jmethodID g_ctor_PlatformException; +} + +void initJavaExceptions(JNIEnvWrapper *env) +{ + g_cls_PlatformException = env->FindClassAsGlobalRef(EXC_NAME_PLATFORM); + g_ctor_PlatformException = env->GetConstructorID(g_cls_PlatformException, + "(" AS_SIG(CLS_NAME_STRING) "I)V"); +} + +void clearJavaExceptions(JNIEnvWrapper *env) +{ + env->DeleteGlobalRef(g_cls_PlatformException); +} + +void throwPlatformException(JNIEnv *env, const OIC::Service::RCSPlatformException &e) +{ + auto msg = newStringObject(env, e.getReason()); + VERIFY_NO_EXC(env); + + auto exObj = env->NewObject(g_cls_PlatformException, g_ctor_PlatformException, + msg, e.getReasonCode()); + VERIFY_NO_EXC(env); + + env->Throw(static_cast< jthrowable >(exObj)); +} diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.h b/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.h new file mode 100644 index 0000000..40b8999 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.h @@ -0,0 +1,50 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef JAVA_EXCEPTIONS_H_ +#define JAVA_EXCEPTIONS_H_ + +#include + +#include "JavaClasses.h" + +namespace OIC +{ + namespace Service + { + class RCSPlatformException; + } +} + +class JNIEnvWrapper; + +void initJavaExceptions(JNIEnvWrapper *); +void clearJavaExceptions(JNIEnvWrapper *); + +void throwPlatformException(JNIEnv *, const OIC::Service::RCSPlatformException &); + +template < typename ENV > +void throwRCSException(ENV *env, const char *msg) +{ + env->ThrowNew(env->FindClass(EXC_NAME_RCS), msg); +} + + +#endif // JAVA_EXCEPTIONS_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaGlobalRef.h b/service/resource-container/android/resource-container/src/main/jni/util/JavaGlobalRef.h new file mode 100644 index 0000000..812fb41 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JavaGlobalRef.h @@ -0,0 +1,61 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef JAVA_GLOBAL_REF_H_ +#define JAVA_GLOBAL_REF_H_ + +#include +#include + +#include "ScopedEnv.h" + +class JavaGlobalRef +{ + public: + JavaGlobalRef(JNIEnv *env, jobject obj) noexcept : + m_obj { } + { + assert(env &&"JNIEnv is nullptr"); + + static auto deleter = [](jobject * obj) + { + if (obj && *obj) + { + ScopedEnv env; + env->DeleteGlobalRef(*obj); + } + delete obj; + }; + + m_obj.reset(new jobject{ env->NewGlobalRef(obj) }, deleter); + } + + operator jobject() const noexcept + { + return *m_obj; + } + + private: + std::shared_ptr< jobject > m_obj; +}; + + + +#endif // JAVA_GLOBAL_REF_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaLocalRef.h b/service/resource-container/android/resource-container/src/main/jni/util/JavaLocalRef.h new file mode 100644 index 0000000..34e7d1e --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/JavaLocalRef.h @@ -0,0 +1,70 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef JAVA_LOCAL_REF_H_ +#define JAVA_LOCAL_REF_H_ + +#include +#include + +template < typename T > +class JavaLocalRef +{ + public: + JavaLocalRef(JNIEnv *env, T obj) noexcept : + m_env { env }, + m_obj { obj } + { + assert(env &&"JNIEnv is nullptr"); + } + + template< typename ENV > + JavaLocalRef(ENV *env, T obj) noexcept : + m_env { env->get() }, + m_obj { obj } + { + assert(env &&"JNIEnv is nullptr"); + } + + ~JavaLocalRef() + { + if (m_obj) m_env->DeleteLocalRef(m_obj); + } + + operator bool() const noexcept { return m_obj; } + operator T() const noexcept { return m_obj; } + + jobject get() const noexcept { return m_obj; } + + JavaLocalRef(const JavaLocalRef &) = delete; + JavaLocalRef &operator=(const JavaLocalRef &) = delete; + + JavaLocalRef &operator=(JavaLocalRef && ) = delete; + + private: + JNIEnv *m_env; + T m_obj; +}; + +typedef JavaLocalRef< jobject > JavaLocalObject; +typedef JavaLocalRef< jstring > JavaLocalString; +typedef JavaLocalRef< jclass > JavaLocalClass; + +#endif // JAVA_LOCAL_REF_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/Log.h b/service/resource-container/android/resource-container/src/main/jni/util/Log.h new file mode 100644 index 0000000..cecabfd --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/Log.h @@ -0,0 +1,42 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef RCS_JNI_LOG_H +#define RCS_JNI_LOG_H + +#include + +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +#define LOGT_I(LOG_TAG, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define LOGT_D(LOG_TAG, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#define LOGT_E(LOG_TAG, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +#define EXPECT(EXP, MSG) do { if (!(EXP)) { LOGW(MSG); return; } } while(false) + +#define EXPECT_RET(EXP, MSG, RET_IF_FAILED) \ + do { if (!(EXP)) { LOGW(MSG); return RET_IF_FAILED; } } while(false) + +#define EXPECT_RET_DEF(EXP, MSG) EXPECT_RET(EXP, MSG, { }) + +#endif // RCS_JNI_LOG_H diff --git a/service/resource-container/android/resource-container/src/main/jni/util/ScopedEnv.h b/service/resource-container/android/resource-container/src/main/jni/util/ScopedEnv.h new file mode 100644 index 0000000..a8b7d4b --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/ScopedEnv.h @@ -0,0 +1,162 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef RCS_JIN_SCOPEDENV_H_ +#define RCS_JIN_SCOPEDENV_H_ + +#include + +#include + +#include "JNIEnvWrapper.h" +#include "Log.h" + +extern JavaVM *g_jvm; + +namespace Detail +{ + inline std::pair getEnv() + { + JNIEnv *env { }; + bool needToDetach { }; + + auto ret = g_jvm->GetEnv((void **) &env, JNI_VERSION_1_6); + + switch (ret) + { + case JNI_OK: + break; + + case JNI_EDETACHED: + { + auto attachRet = g_jvm->AttachCurrentThread(&env, NULL); + + if (attachRet != JNI_OK) + { + LOGT_E("JNI-ScopedEnv", "Failed to get the environment : %d", attachRet); + } + else + { + needToDetach = true; + } + break; + } + case JNI_EVERSION: + LOGT_E("JNI-ScopedEnv", "JNI version not supported"); + break; + + default: + LOGT_E("JNI-ScopedEnv", "Failed to get the environment"); + break; + } + + return { env, needToDetach }; + } +} + +class ScopedEnv +{ + public: + ScopedEnv() noexcept : + m_env { }, + m_needToDetach { false } + { + auto val = Detail::getEnv(); + + m_env = val.first; + m_needToDetach = val.second; + } + + ~ScopedEnv() + { + if (m_env && m_needToDetach) + { + g_jvm->DetachCurrentThread(); + } + } + + ScopedEnv(const ScopedEnv &) = delete; + ScopedEnv &operator=(const ScopedEnv &) = delete; + + operator bool() const noexcept + { + return m_env; + } + + JNIEnv *operator->() noexcept + { + return m_env; + } + + JNIEnv *get() noexcept + { + return m_env; + } + + private: + JNIEnv *m_env; + bool m_needToDetach; +}; + +class ScopedEnvWrapper +{ + public: + ScopedEnvWrapper() noexcept : + m_env { }, + m_needToDetach { false } + { + auto val = Detail::getEnv(); + + m_env = val.first; + m_needToDetach = val.second; + } + + ~ScopedEnvWrapper() + { + if (m_env && m_needToDetach) + { + g_jvm->DetachCurrentThread(); + } + } + + ScopedEnvWrapper(const ScopedEnvWrapper &) = delete; + ScopedEnvWrapper &operator=(const ScopedEnvWrapper &) = delete; + + operator bool() const noexcept + { + return m_env; + } + + JNIEnvWrapper *operator->() noexcept + { + return &m_env; + } + + JNIEnvWrapper *get() noexcept + { + return &m_env; + } + + private: + JNIEnvWrapper m_env; + bool m_needToDetach; +}; + +#endif // RCS_JIN_SCOPEDENV_H_ diff --git a/service/resource-container/android/resource-container/src/main/jni/util/Verify.h b/service/resource-container/android/resource-container/src/main/jni/util/Verify.h new file mode 100644 index 0000000..5a4f4c6 --- /dev/null +++ b/service/resource-container/android/resource-container/src/main/jni/util/Verify.h @@ -0,0 +1,32 @@ +/****************************************************************** + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef RCS_JNI_VERIFY_H_ +#define RCS_JNI_VERIFY_H_ + +#define VERIFY_NO_EXC(ENV) do { \ + if ((ENV)->ExceptionCheck()) { (ENV)->ExceptionDescribe(); return; } } while(false) + +#define VERIFY_NO_EXC_RET(ENV, RET) do { \ + if ((ENV)->ExceptionCheck()) { (ENV)->ExceptionDescribe(); return RET; } } while(false) + +#define VERIFY_NO_EXC_RET_DEF(ENV) VERIFY_NO_EXC_RET(ENV, { }) + +#endif // RCS_JNI_VERIFY_H_ diff --git a/service/resource-container/android/settings.gradle b/service/resource-container/android/settings.gradle new file mode 100644 index 0000000..a7c0cda --- /dev/null +++ b/service/resource-container/android/settings.gradle @@ -0,0 +1,23 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +include ':resource-container' diff --git a/service/resource-container/examples/android/RCSampleClientApp/.gitignore b/service/resource-container/examples/android/RCSampleClientApp/.gitignore new file mode 100644 index 0000000..8b41237 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/.gitignore @@ -0,0 +1,7 @@ +.gradle +/local.properties +/.idea +.DS_Store +/build +/captures +/gradle diff --git a/service/resource-container/examples/android/RCSampleClientApp/RCSampleClientApp.iml b/service/resource-container/examples/android/RCSampleClientApp/RCSampleClientApp.iml new file mode 100644 index 0000000..2a02201 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/RCSampleClientApp.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/service/resource-container/examples/android/RCSampleClientApp/README b/service/resource-container/examples/android/RCSampleClientApp/README new file mode 100644 index 0000000..5364aec --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/README @@ -0,0 +1,23 @@ +To build the app + +1. build Iotivity with TARGET_OS=android + +2. Copy aar files into app/libs folder + - {Iotivity_root}/android/android_api/base/build/outputs/aar/iotivity-{TARGET_ARCH}-base-{MODE}.aar + - {Iotivity_root}/service/resource-encapsulation/android/service/build/outputs/aar/iotivity-{TARGET_ARCH}-service-{MODE}.aar + +3. Configure dependencies for libs in app/build.gradle + - default TARGET_ARCH is armeabi + - default MODE is release + + for example, if you build Iotivity as follows, + + $scons TARGET_OS=android TARGET_ARCH=x86 RELEASE=0 + + then, dependencies should be modified like below + + dependencies { + compile(name:'iotivity-x86-service-debug', ext:'aar') + compile(name:'iotivity-x86-base-debug', ext:'aar') + } + diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/.gitignore b/service/resource-container/examples/android/RCSampleClientApp/app/.gitignore new file mode 100644 index 0000000..6a384b7 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/.gitignore @@ -0,0 +1,2 @@ +/build +/libs/* diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/app.iml b/service/resource-container/examples/android/RCSampleClientApp/app/app.iml new file mode 100644 index 0000000..8501ed3 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/app.iml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/build.gradle b/service/resource-container/examples/android/RCSampleClientApp/app/build.gradle new file mode 100644 index 0000000..a8285a4 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.iotivity.service.sample.client" + minSdkVersion 21 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + compile(name:'iotivity-service-release', ext:'aar') + compile(name:'iotivity-base-release', ext:'aar') +} diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c42c1ca --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java new file mode 100644 index 0000000..319d5e1 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java @@ -0,0 +1,75 @@ +/****************************************************************** + * Copyright 2015 Samsung Electronics All Rights Reserved. + *

+ *

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************/ + +package org.iotivity.service.sample.client; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.TextView; + +import org.iotivity.service.RcsException; +import org.iotivity.service.client.RcsAddress; +import org.iotivity.service.client.RcsDiscoveryManager; +import org.iotivity.service.client.RcsRemoteResourceObject; + +/** + * It contains the discover resource API for Discovering Container Resource + */ +public class ContainerClientActivity extends Activity implements + RcsDiscoveryManager.OnResourceDiscoveredListener { + private final String LOG_TAG = "[SampleClient] " + + this.getClass().getSimpleName(); + + private TextView mLogView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_container_client); + mLogView = (TextView) findViewById(R.id.log); + } + + public void onDiscoverResourceClick(View v) { + try { + RcsDiscoveryManager.getInstance().discoverResourceByType( + RcsAddress.multicast(), "oic.r.sensor", + ContainerClientActivity.this); + mLogView.setText(""); + } catch (RcsException e) { + e.printStackTrace(); + } + } + + @Override + public void onResourceDiscovered( + final RcsRemoteResourceObject discoveredResource) { + Log.i(LOG_TAG, "onResourceDiscovered"); + + runOnUiThread(new Runnable() { + public void run() { + try { + mLogView.setText(Utils.resourceInfo(discoveredResource)); + } catch (RcsException e) { + Utils.showError(ContainerClientActivity.this, LOG_TAG, e); + } + } + }); + } +} diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java new file mode 100644 index 0000000..a39afd1 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java @@ -0,0 +1,39 @@ +package org.iotivity.service.sample.client; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +import org.iotivity.service.RcsException; +import org.iotivity.service.client.RcsRemoteResourceObject; + +public class Utils { + public static String resourceInfo(RcsRemoteResourceObject resourceObject) + throws RcsException { + StringBuilder sb = new StringBuilder(); + + sb.append("URI : " + resourceObject.getUri() + "\n"); + sb.append("Host : " + resourceObject.getAddress() + "\n"); + for (String type : resourceObject.getTypes()) { + sb.append("resourceType : " + type + "\n"); + } + + for (String itf : resourceObject.getInterfaces()) { + sb.append("resourceInterfaces : " + itf + "\n"); + } + + sb.append("isObservable : " + resourceObject.isObservable() + "\n"); + + return sb.toString(); + } + + public static void showError(Context ctx, String tag, String msg) { + Toast.makeText(ctx, msg, Toast.LENGTH_SHORT).show(); + Log.e(tag, msg); + } + + public static void showError(Context ctx, String tag, Exception e) { + Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_SHORT).show(); + Log.e(tag, e.getMessage(), e); + } +} diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml new file mode 100644 index 0000000..09634a3 --- /dev/null +++ b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml @@ -0,0 +1,25 @@ + + + +