[Resource-Container] Java SDK and Sample applications
authorMarkus Jung <markus.jung@samsung.com>
Tue, 6 Oct 2015 17:10:51 +0000 (22:40 +0530)
committerUze Choi <uzchoi@samsung.com>
Wed, 7 Oct 2015 02:19:39 +0000 (02:19 +0000)
- Java SDK for Resource Container.
- Android Sample Applications for Resource Container.

Change-Id: I1138ea7c82a155b18b8951d2bcdd94b24f1bd579
Signed-off-by: Markus Jung <markus.jung@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/3659
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
80 files changed:
service/SConscript
service/resource-container/SConscript
service/resource-container/android/.gitignore [new file with mode: 0644]
service/resource-container/android/SConscript [new file with mode: 0644]
service/resource-container/android/android.iml [new file with mode: 0644]
service/resource-container/android/build.gradle [new file with mode: 0644]
service/resource-container/android/gradle.properties [new file with mode: 0644]
service/resource-container/android/gradlew [new file with mode: 0644]
service/resource-container/android/gradlew.bat [new file with mode: 0644]
service/resource-container/android/service/base.iml [new file with mode: 0644]
service/resource-container/android/service/build.gradle [new file with mode: 0644]
service/resource-container/android/service/proguard-rules.pro [new file with mode: 0644]
service/resource-container/android/service/src/main/AndroidManifest.xml [new file with mode: 0644]
service/resource-container/android/service/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java [new file with mode: 0644]
service/resource-container/android/service/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java [new file with mode: 0644]
service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsException.java [new file with mode: 0644]
service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsIllegalStateException.java [new file with mode: 0644]
service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsObject.java [new file with mode: 0644]
service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsPlatformException.java [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/Android.mk [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/Application.mk [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniMain.cpp [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniRcsBundleInfo.cpp [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniRcsBundleInfo.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniRcsObject.cpp [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniRcsObject.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniRcsResourceContainer.cpp [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/JniRcsResourceContainer.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JNIEnvWrapper.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JavaClasses.cpp [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JavaClasses.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JavaExceptions.cpp [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JavaExceptions.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JavaGlobalRef.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/JavaLocalRef.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/Log.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/ScopedEnv.h [new file with mode: 0644]
service/resource-container/android/service/src/main/jni/util/Verify.h [new file with mode: 0644]
service/resource-container/android/settings.gradle [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/.gitignore [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/RCSampleClientApp.iml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/README [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/.gitignore [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/app.iml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/build.gradle [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-hdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-mdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values-v21/styles.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/strings.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/styles.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/build.gradle [new file with mode: 0644]
service/resource-container/examples/android/RCSampleClientApp/settings.gradle [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/.gitignore [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/RCSampleServerApp.iml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/README [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/.gitignore [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/app.iml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/build.gradle [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/AndroidManifest.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/assets/lib/ResourceContainerConfig.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainer.java [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainerActivity.java [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/group.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/list_item.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/resource_container.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-hdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-mdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values-v21/styles.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/strings.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/styles.xml [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/build.gradle [new file with mode: 0644]
service/resource-container/examples/android/RCSampleServerApp/settings.gradle [new file with mode: 0644]

index 3be6df2..b8dc0eb 100644 (file)
@@ -37,8 +37,7 @@ if target_os not in ['arduino','darwin']:
     SConscript('resource-encapsulation/SConscript')
 
     # Build resource-container project
-    if target_os not in ['android']:
-        SConscript('resource-container/SConscript')
+    SConscript('resource-container/SConscript')
 
     # Build simulator module
     if target_os in ['linux'] and env.get('SIMULATOR', False):
index aaded92..45382d4 100644 (file)
@@ -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 (file)
index 0000000..49ffed7
--- /dev/null
@@ -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 (file)
index 0000000..41af943
--- /dev/null
@@ -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=<YOUR_PORT_NUMBER>                                        *
+*    sdkman.monitor.density=108                                               *
+*    http.proxyHost=<YOUR_HTTP_PROXY_ADDRESS>                                 *
+*    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="service/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 (file)
index 0000000..2a02201
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/classes/main" />
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/service/resource-container/android/build.gradle b/service/resource-container/android/build.gradle
new file mode 100644 (file)
index 0000000..cbfddfd
--- /dev/null
@@ -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 (file)
index 0000000..dff37f4
--- /dev/null
@@ -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 (file)
index 0000000..91a7e26
--- /dev/null
@@ -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 (file)
index 0000000..8a0b282
--- /dev/null
@@ -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/service/base.iml b/service/resource-container/android/service/base.iml
new file mode 100644 (file)
index 0000000..3bf0877
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="android_api" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":base" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+        <option name="LIBRARY_PROJECT" value="true" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/native-libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/service/resource-container/android/service/build.gradle b/service/resource-container/android/service/build.gradle
new file mode 100644 (file)
index 0000000..50c7205
--- /dev/null
@@ -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<File>()
+    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/service/proguard-rules.pro b/service/resource-container/android/service/proguard-rules.pro
new file mode 100644 (file)
index 0000000..c5f9a5b
--- /dev/null
@@ -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/service/src/main/AndroidManifest.xml b/service/resource-container/android/service/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..d641087
--- /dev/null
@@ -0,0 +1,10 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.rcsdk"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="21" />
+
+</manifest>
diff --git a/service/resource-container/android/service/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java b/service/resource-container/android/service/src/main/java/org/iotivity/service/resourcecontainer/RcsBundleInfo.java
new file mode 100644 (file)
index 0000000..670ceca
--- /dev/null
@@ -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/service/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java b/service/resource-container/android/service/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java
new file mode 100644 (file)
index 0000000..bb19810
--- /dev/null
@@ -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<String, String> params);
+
+    private native void nativeRemoveBundle(String bundleId);
+
+    private native List<RcsBundleInfo> nativeListBundles();
+
+    private native void nativeStartBundle(String bundleId);
+
+    private native void nativeStopBundle(String bundleId);
+
+    private native void nativeAddResourceConfig(String bundleId,
+            String resourceUri, Map<String, String> params);
+
+    private native void nativeRemoveResourceConfig(String bundleId,
+            String resourceUri);
+
+    private native List<String> nativeListBundleResources(String bundleId);
+
+    /**
+     * API for getting the Instance of ResourceContainer class
+     *
+     */
+    public static RcsResourceContainer getInstance() {
+        return sInstance;
+    }
+
+    /**
+     * API for starting the Container
+     *
+     * <p>
+     * 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<RCSBundleInfo> -List of BundleInfo objects each associated
+     *         with a bundle
+     *
+     *         {@link RcsBundleInfo}
+     */
+    public List<RcsBundleInfo> 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
+     *
+     *            <p>
+     *            It is dynamic configuration
+     */
+    public void addBundle(String bundleId, String bundleUri, String bundlePath,
+            String activator, Map<String, String> 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<String, String> 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<String> All the bundle resources
+     */
+    public List<String> listBundleResources(String bundleId) {
+        return nativeListBundleResources(bundleId);
+    }
+}
diff --git a/service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsException.java b/service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsException.java
new file mode 100644 (file)
index 0000000..70b46c7
--- /dev/null
@@ -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/service/src/main/java/org/iotivity/service/utils/RcsIllegalStateException.java b/service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsIllegalStateException.java
new file mode 100644 (file)
index 0000000..c6150f5
--- /dev/null
@@ -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/service/src/main/java/org/iotivity/service/utils/RcsObject.java b/service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsObject.java
new file mode 100644 (file)
index 0000000..203651c
--- /dev/null
@@ -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/service/src/main/java/org/iotivity/service/utils/RcsPlatformException.java b/service/resource-container/android/service/src/main/java/org/iotivity/service/utils/RcsPlatformException.java
new file mode 100644 (file)
index 0000000..52297be
--- /dev/null
@@ -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/service/src/main/jni/Android.mk b/service/resource-container/android/service/src/main/jni/Android.mk
new file mode 100644 (file)
index 0000000..6a5bb1b
--- /dev/null
@@ -0,0 +1,50 @@
+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_common
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_common.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := rcs_client
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_client.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := rcs_server
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_server.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := rcs_container
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_container.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+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_common
+LOCAL_SHARED_LIBRARIES += rcs_client
+LOCAL_SHARED_LIBRARIES += rcs_server
+LOCAL_SHARED_LIBRARIES += rcs_container
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/service/resource-container/android/service/src/main/jni/Application.mk b/service/resource-container/android/service/src/main/jni/Application.mk
new file mode 100644 (file)
index 0000000..c177a13
--- /dev/null
@@ -0,0 +1,2 @@
+NDK_TOOLCHAIN_VERSION := 4.9
+APP_STL               := gnustl_shared
diff --git a/service/resource-container/android/service/src/main/jni/JniMain.cpp b/service/resource-container/android/service/src/main/jni/JniMain.cpp
new file mode 100644 (file)
index 0000000..16b6894
--- /dev/null
@@ -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/service/src/main/jni/JniRcsBundleInfo.cpp b/service/resource-container/android/service/src/main/jni/JniRcsBundleInfo.cpp
new file mode 100644 (file)
index 0000000..7bbac93
--- /dev/null
@@ -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/service/src/main/jni/JniRcsBundleInfo.h b/service/resource-container/android/service/src/main/jni/JniRcsBundleInfo.h
new file mode 100644 (file)
index 0000000..83b5dcd
--- /dev/null
@@ -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 <jni.h>
+
+#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/service/src/main/jni/JniRcsObject.cpp b/service/resource-container/android/service/src/main/jni/JniRcsObject.cpp
new file mode 100644 (file)
index 0000000..7a3c014
--- /dev/null
@@ -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/service/src/main/jni/JniRcsObject.h b/service/resource-container/android/service/src/main/jni/JniRcsObject.h
new file mode 100644 (file)
index 0000000..cfa7a71
--- /dev/null
@@ -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 <jni.h>
+
+#include <memory>
+
+#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/service/src/main/jni/JniRcsResourceContainer.cpp b/service/resource-container/android/service/src/main/jni/JniRcsResourceContainer.cpp
new file mode 100644 (file)
index 0000000..02944a6
--- /dev/null
@@ -0,0 +1,290 @@
+/******************************************************************
+ *
+ * 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 <android/log.h>
+
+
+
+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();
+            // FIXME we need a safe way to keep bundle info in java obj!!
+            // because we currently put raw pointer in the java obj.
+
+            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/service/src/main/jni/JniRcsResourceContainer.h b/service/resource-container/android/service/src/main/jni/JniRcsResourceContainer.h
new file mode 100644 (file)
index 0000000..2474b7e
--- /dev/null
@@ -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 <jni.h>
+
+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/service/src/main/jni/util/JNIEnvWrapper.h b/service/resource-container/android/service/src/main/jni/util/JNIEnvWrapper.h
new file mode 100644 (file)
index 0000000..9a4d413
--- /dev/null
@@ -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 <jni.h>
+
+#include <exception>
+
+#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<typename T>
+        T NewGlobalRef(T obj)
+        {
+            auto ret = static_cast< T >(m_env->NewGlobalRef(obj));
+            if (m_env->ExceptionCheck()) throw JavaException();
+            return ret;
+        }
+
+        template<typename T>
+        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, "<init>", 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/service/src/main/jni/util/JavaClasses.cpp b/service/resource-container/android/service/src/main/jni/util/JavaClasses.cpp
new file mode 100644 (file)
index 0000000..f84f4d9
--- /dev/null
@@ -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/service/src/main/jni/util/JavaClasses.h b/service/resource-container/android/service/src/main/jni/util/JavaClasses.h
new file mode 100644 (file)
index 0000000..b91ffea
--- /dev/null
@@ -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 <jni.h>
+
+#include <string>
+
+#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/service/src/main/jni/util/JavaExceptions.cpp b/service/resource-container/android/service/src/main/jni/util/JavaExceptions.cpp
new file mode 100644 (file)
index 0000000..4774a72
--- /dev/null
@@ -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/service/src/main/jni/util/JavaExceptions.h b/service/resource-container/android/service/src/main/jni/util/JavaExceptions.h
new file mode 100644 (file)
index 0000000..40b8999
--- /dev/null
@@ -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 <jni.h>
+
+#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/service/src/main/jni/util/JavaGlobalRef.h b/service/resource-container/android/service/src/main/jni/util/JavaGlobalRef.h
new file mode 100644 (file)
index 0000000..812fb41
--- /dev/null
@@ -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 <memory>
+#include <cassert>
+
+#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/service/src/main/jni/util/JavaLocalRef.h b/service/resource-container/android/service/src/main/jni/util/JavaLocalRef.h
new file mode 100644 (file)
index 0000000..34e7d1e
--- /dev/null
@@ -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 <jni.h>
+#include <cassert>
+
+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/service/src/main/jni/util/Log.h b/service/resource-container/android/service/src/main/jni/util/Log.h
new file mode 100644 (file)
index 0000000..cecabfd
--- /dev/null
@@ -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 <android/log.h>
+
+#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/service/src/main/jni/util/ScopedEnv.h b/service/resource-container/android/service/src/main/jni/util/ScopedEnv.h
new file mode 100644 (file)
index 0000000..a8b7d4b
--- /dev/null
@@ -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 <utility>
+
+#include <jni.h>
+
+#include "JNIEnvWrapper.h"
+#include "Log.h"
+
+extern JavaVM *g_jvm;
+
+namespace Detail
+{
+    inline std::pair<JNIEnv *, bool> 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/service/src/main/jni/util/Verify.h b/service/resource-container/android/service/src/main/jni/util/Verify.h
new file mode 100644 (file)
index 0000000..5a4f4c6
--- /dev/null
@@ -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 (file)
index 0000000..5b8f4d4
--- /dev/null
@@ -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 ':service'
diff --git a/service/resource-container/examples/android/RCSampleClientApp/.gitignore b/service/resource-container/examples/android/RCSampleClientApp/.gitignore
new file mode 100644 (file)
index 0000000..8b41237
--- /dev/null
@@ -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 (file)
index 0000000..2a02201
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/classes/main" />
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/service/resource-container/examples/android/RCSampleClientApp/README b/service/resource-container/examples/android/RCSampleClientApp/README
new file mode 100644 (file)
index 0000000..5364aec
--- /dev/null
@@ -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 (file)
index 0000000..6a384b7
--- /dev/null
@@ -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 (file)
index 0000000..8501ed3
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":app" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="iotivity-service-release-" level="project" />
+    <orderEntry type="library" exported="" name="iotivity-base-release-" level="project" />
+  </component>
+</module>
+
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 (file)
index 0000000..a8285a4
--- /dev/null
@@ -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 (file)
index 0000000..c42c1ca
--- /dev/null
@@ -0,0 +1,21 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.service.sample.client">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+    <application android:allowBackup="true" android:label="@string/app_name"
+        android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme">
+        <activity
+            android:name=".ContainerClientActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    <!--    <activity android:name=".ContainerClientActivity" /> -->
+    </application>
+
+</manifest>
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 (file)
index 0000000..319d5e1
--- /dev/null
@@ -0,0 +1,75 @@
+/******************************************************************
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ * <p>
+ * <p>
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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 (file)
index 0000000..a39afd1
--- /dev/null
@@ -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 (file)
index 0000000..09634a3
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:id="@+id/main"
+    android:weightSum="1">
+
+    <Button
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:onClick="onDiscoverResourceClick"
+        android:text="@string/discover_resource"
+        android:id="@+id/di" />
+
+    <TextView
+        android:id="@+id/log"
+        android:layout_width="fill_parent"
+        android:layout_height="250dp"
+        android:ems="10"
+        android:layout_weight="0.26"
+        android:layout_below="@+id/di"
+        android:layout_alignParentStart="true" />
+
+</RelativeLayout>
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-hdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..cde69bc
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-mdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..c133a0c
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..bfa42f0
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..324e72c
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values-v21/styles.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values-v21/styles.xml
new file mode 100644 (file)
index 0000000..dba3c41
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="AppTheme" parent="android:Theme.Material.Light">
+    </style>
+</resources>
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/strings.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..c5bd024
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>
+    <string name="app_name">RCSampleClientApp</string>
+    <string name="container_resource">Discover Container Resource</string>
+    <string name="discover_resource">Discover Resource</string>
+</resources>
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/styles.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..ff6c9d2
--- /dev/null
@@ -0,0 +1,8 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+    </style>
+
+</resources>
diff --git a/service/resource-container/examples/android/RCSampleClientApp/build.gradle b/service/resource-container/examples/android/RCSampleClientApp/build.gradle
new file mode 100644 (file)
index 0000000..34a7ef9
--- /dev/null
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.0.0'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+
+        flatDir {
+            dirs 'libs'
+        }
+    }
+}
diff --git a/service/resource-container/examples/android/RCSampleClientApp/settings.gradle b/service/resource-container/examples/android/RCSampleClientApp/settings.gradle
new file mode 100644 (file)
index 0000000..e7b4def
--- /dev/null
@@ -0,0 +1 @@
+include ':app'
diff --git a/service/resource-container/examples/android/RCSampleServerApp/.gitignore b/service/resource-container/examples/android/RCSampleServerApp/.gitignore
new file mode 100644 (file)
index 0000000..8b41237
--- /dev/null
@@ -0,0 +1,7 @@
+.gradle
+/local.properties
+/.idea
+.DS_Store
+/build
+/captures
+/gradle
diff --git a/service/resource-container/examples/android/RCSampleServerApp/RCSampleServerApp.iml b/service/resource-container/examples/android/RCSampleServerApp/RCSampleServerApp.iml
new file mode 100644 (file)
index 0000000..2a02201
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/classes/main" />
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/service/resource-container/examples/android/RCSampleServerApp/README b/service/resource-container/examples/android/RCSampleServerApp/README
new file mode 100644 (file)
index 0000000..4a87b04
--- /dev/null
@@ -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-container/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/RCSampleServerApp/app/.gitignore b/service/resource-container/examples/android/RCSampleServerApp/app/.gitignore
new file mode 100644 (file)
index 0000000..6a384b7
--- /dev/null
@@ -0,0 +1,2 @@
+/build
+/libs/*
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/app.iml b/service/resource-container/examples/android/RCSampleServerApp/app/app.iml
new file mode 100644 (file)
index 0000000..8501ed3
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":app" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="iotivity-service-release-" level="project" />
+    <orderEntry type="library" exported="" name="iotivity-base-release-" level="project" />
+  </component>
+</module>
+
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/build.gradle b/service/resource-container/examples/android/RCSampleServerApp/app/build.gradle
new file mode 100644 (file)
index 0000000..2ba29fc
--- /dev/null
@@ -0,0 +1,26 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        applicationId "org.iotivity.service.sample.server"
+        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/RCSampleServerApp/app/src/main/AndroidManifest.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..d12abc4
--- /dev/null
@@ -0,0 +1,22 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.service.sample.container">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+    <application android:allowBackup="true" android:label="@string/app_name"
+        android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme">
+
+        <activity
+            android:name="org.iotivity.service.sample.container.ResourceContainerActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/assets/lib/ResourceContainerConfig.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/assets/lib/ResourceContainerConfig.xml
new file mode 100644 (file)
index 0000000..bd04739
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<container>
+    <bundle>
+        <id>oic.bundle.discomfortIndexSensor</id>
+        <path>data/data/org.iotivity.service.sample.server/files/libDISensorBundle.so</path>
+        <activator>disensor</activator>
+        <version>1.0.0</version>
+        <resources>
+            <resourceInfo>
+                <name>DiscomfortIndexSensor1</name>
+                <resourceType>oic.r.sensor</resourceType>
+                <outputs>
+                    <output>
+                        <name>discomfortIndex</name>
+                        <type>int</type>
+                    </output>
+                    <output>
+                        <name>humidity</name>
+                        <type>double</type>
+                    </output>
+                    <output>
+                        <name>temperature</name>
+                        <type>double</type>
+                    </output>
+                </outputs>
+                <inputs>
+                    <input>
+                        <name>humidity</name>
+                        <type>double</type>
+                        <resourceType>oic.r.humidity</resourceType>
+                    </input>
+                    <input>
+                        <name>temperature</name>
+                        <type>double</type>
+                        <resourceType>oic.r.temperature</resourceType>
+                    </input>
+                </inputs>
+            </resourceInfo>
+        </resources>
+    </bundle>
+</container>
\ No newline at end of file
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainer.java b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainer.java
new file mode 100644 (file)
index 0000000..e8ab3fa
--- /dev/null
@@ -0,0 +1,400 @@
+/******************************************************************
+ *
+ * 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.container;
+
+import android.os.Message;
+
+import android.util.Log;
+
+import org.iotivity.service.resourcecontainer.RcsBundleInfo;
+import org.iotivity.service.resourcecontainer.RcsResourceContainer;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * For calling the Resource Container APIs as per user selection on UI and for
+ * updating the UI
+ *
+ * It contains all the Resource Container APIs.
+ */
+public class ResourceContainer {
+
+    private RcsResourceContainer             containerInstance;
+    public static String                     logMessage;
+
+    private static ResourceContainerActivity resourceContainerActivityInstance;
+    private static Message                   msg;
+    public static boolean                    startBundleFlag;
+    private static boolean                   isStarted     = false;
+    public static boolean                    isInitialized = false;
+
+    // constructor
+    public ResourceContainer() {
+        resourceContainerActivityInstance = ResourceContainerActivity
+                .getResourceContainerActivityObj();
+        containerInstance = RcsResourceContainer.getInstance();
+    }
+
+    // Start Container
+    public void startContainer(String sdCardPath) {
+
+        String configFile = sdCardPath + "/ResourceContainerConfig.xml";
+        Log.i("startContainer : config path : ", configFile);
+
+        if (!isStarted) {
+            for (int i = 0; i < 2; i++) {
+                containerInstance.startContainer(configFile);
+                isStarted = true;
+            }
+        } else {
+            containerInstance.startContainer(configFile);
+        }
+
+        logMessage = "Container Started ";
+        logMessage += "with one Bundle" + "\n";
+        logMessage += "ID : oic.bundle.discomfortIndexSensor";
+
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+
+        msg = Message.obtain();
+        msg.what = 0;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Stop Container
+    public void stopContainer() {
+
+        if (isStarted) {
+            containerInstance.stopContainer();
+            logMessage = "Container stopped";
+            isStarted = false;
+        } else {
+            logMessage = "Container not started";
+        }
+
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // List Bundle Resources
+    public void listDIBundleResources() {
+
+        List<String> bundleResources = containerInstance
+                .listBundleResources("oic.bundle.discomfortIndexSensor");
+        Iterator<String> it = bundleResources.iterator();
+        logMessage = "";
+
+        if (0 == bundleResources.size()) {
+            logMessage = logMessage + "No resource found in the bundle" + "\n";
+        } else {
+            while (it.hasNext()) {
+                String element = (String) it.next();
+                logMessage = logMessage + element + "\n";
+            }
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // List Bundles
+    public void listBundles() {
+
+        List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+        Iterator<RcsBundleInfo> it = bundleList.iterator();
+        int i = 0;
+        logMessage = "";
+        logMessage = logMessage + "size of bundleList : " + bundleList.size()
+                + "\n\n";
+
+        while (it.hasNext()) {
+            i++;
+            RcsBundleInfo object = (RcsBundleInfo) it.next();
+            logMessage += "Bundle : " + i + " -: \n";
+            logMessage += "ID : " + object.getID() + "\n";
+            logMessage += "Lib Path: " + object.getPath() + "\n";
+            if (!(object.getVersion().equalsIgnoreCase("")))
+                logMessage += "version : " + object.getVersion() + "\n\n";
+            else
+                logMessage += "\n";
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Add BMI Bundles
+    public void addBMIBundle() {
+
+        Map<String, String> bundleParams = null;
+        List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+        if (1 < bundleList.size()) {
+            logMessage = "Bundle already added" + "\n";
+
+        } else {
+            for (int i = 0; i < 2; i++) {
+                containerInstance
+                        .addBundle(
+                                "oic.bundle.BMISensor",
+                                "xyz",
+                                "data/data/org.iotivity.service.sample.server/files/libBMISensorBundle.so",
+                                "bmisensor", bundleParams);
+            }
+
+            logMessage = "bundle to add : " + "\n";
+            logMessage = logMessage + "ID :" + "oic.bundle.BMISensor" + "\n";
+            logMessage = logMessage + "Uri: " + "xyz" + "\n";
+            logMessage = logMessage
+                    + "Path : "
+                    + "data/data/org.iotivity.service.sample.server/files/libBMISensorBundle.so"
+                    + "\n\n";
+            logMessage = logMessage + "bundle added successfully" + "\n";
+        }
+
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Remove Bundle BMI
+    public void removeBMIBundle() {
+
+        List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+        if (0 == bundleList.size()) {
+            logMessage = "No bundle to remove" + "\n";
+
+        } else {
+
+            for (int i = 0; i < 2; i++) {
+                containerInstance.removeBundle("oic.bundle.BMISensor");
+            }
+            startBundleFlag = false;
+            logMessage = "bundle to remove : " + "\n";
+            logMessage = logMessage + "ID :" + "oic.bundle.BMISensor" + "\n\n";
+            logMessage = logMessage + " bundle removed  successfully" + "\n";
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Start Bundle BMI
+    public void startBMIBundle() {
+
+        List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+        if (1 == bundleList.size()) {
+            logMessage = "BMI bundle not added" + "\n";
+        } else if (true == startBundleFlag) {
+            logMessage = "Bundle already started" + "\n";
+        } else {
+            startBundleFlag = true;
+            containerInstance.startBundle("oic.bundle.BMISensor");
+
+            logMessage = " bundle to start" + "\n";
+            logMessage += " ID : oic.bundle.BMISensor" + "\n\n";
+            logMessage += " bundle started successfully" + "\n";
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Stop Bundle BMI
+    public void stopBMIBundle() {
+
+        if (false == startBundleFlag) {
+            logMessage = "Bundle is not Started" + "\n";
+        } else {
+
+            List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+            if (0 == bundleList.size()) {
+                logMessage = "No bundle to Stop" + "\n";
+
+            } else {
+                containerInstance.stopBundle("oic.bundle.BMISensor");
+                startBundleFlag = false;
+                logMessage = " bundle to stop" + "\n";
+                logMessage = logMessage + " ID : oic.bundle.BMISensor" + "\n\n";
+                logMessage = logMessage + " bundle stopped successfully" + "\n";
+            }
+        }
+
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Add Resource Configuration DI
+    public void addDIResourceConfig() {
+
+        List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+        List<String> bundleResources = containerInstance
+                .listBundleResources("oic.bundle.discomfortIndexSensor");
+
+        if (0 == bundleList.size()) {
+            logMessage = "No bundle found" + "\n";
+        } else if ((0 == bundleList.size()) && (0 == bundleResources.size())) {
+
+            logMessage = "No bundle found" + "\n";
+        } else {
+
+            Map<String, String> params = new HashMap<String, String>();
+            params.put("resourceType", "oic.r.sensor");
+            params.put("address",
+                    "http://192.168.0.2/api/newdeveloper/sensor/22");
+            containerInstance.addResourceConfig(
+                    "oic.bundle.discomfortIndexSensor", "", params);
+            logMessage = "resource added successfully" + "\n";
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Remove Resource Configuration DI
+    public void removeDIResourceConfig() {
+
+        List<String> bundleResources = containerInstance
+                .listBundleResources("oic.bundle.discomfortIndexSensor");
+        if (bundleResources.size() >= 1) {
+            String element = bundleResources.get(0);
+            containerInstance.removeResourceConfig(
+                    "oic.bundle.discomfortIndexSensor", element);
+            Message msg;
+            logMessage = "resource removed successfully: \n" + element + "\n";
+            ResourceContainerActivity.setMessageLog(logMessage);
+            msg = Message.obtain();
+            msg.what = 1;
+            resourceContainerActivityInstance.getHandler().sendMessage(msg);
+        } else {
+            logMessage = "No resource to remove" + "\n";
+            ResourceContainerActivity.setMessageLog(logMessage);
+            msg = Message.obtain();
+            msg.what = 1;
+            resourceContainerActivityInstance.getHandler().sendMessage(msg);
+        }
+    }
+
+    // Add Resource Configuration BMI
+    public void addBMIResourceConfig() {
+
+        if (false == startBundleFlag) {
+            logMessage = "Bundle is not started" + "\n";
+        } else {
+            List<RcsBundleInfo> bundleList = containerInstance.listBundles();
+            List<String> bundleResources = containerInstance
+                    .listBundleResources("oic.bundle.BMISensor");
+
+            if (0 == bundleList.size()) {
+                logMessage = "No bundle found" + "\n";
+            } else if ((0 == bundleList.size())
+                    && (0 == bundleResources.size())) {
+
+                logMessage = "No bundle found" + "\n";
+            } else {
+
+                Map<String, String> params = new HashMap<String, String>();
+                params.put("resourceType", "oic.r.sensor");
+                params.put("address",
+                        "http://192.168.0.2/api/newdeveloper/sensor/22");
+                containerInstance.addResourceConfig("oic.bundle.BMISensor", "",
+                        params);
+                logMessage = "resource added successfully" + "\n";
+            }
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // Remove Resource Configuration BMI
+    public void removeBMIResourceConfig() {
+
+        if (false == startBundleFlag) {
+            logMessage = "Bundle is not started" + "\n";
+
+        } else {
+            List<String> bundleResources = containerInstance
+                    .listBundleResources("oic.bundle.BMISensor");
+            if (bundleResources.size() >= 1) {
+                String element = bundleResources.get(0);
+                containerInstance.removeResourceConfig("oic.bundle.BMISensor",
+                        element);
+                Message msg;
+                logMessage = "resource removed successfully: \n" + element
+                        + "\n";
+
+            } else {
+                logMessage = "No resource to remove" + "\n";
+            }
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+
+    // List Bundle Resources
+    public void listBMIBundleResources() {
+
+        if (false == startBundleFlag) {
+            logMessage = "Bundle is not started" + "\n";
+
+        } else {
+            List<String> bundleResources = containerInstance
+                    .listBundleResources("oic.bundle.BMISensor");
+            Iterator<String> it = bundleResources.iterator();
+            logMessage = "";
+
+            if (0 == bundleResources.size()) {
+                logMessage = logMessage + "No resource found in the bundle"
+                        + "\n";
+            } else {
+                while (it.hasNext()) {
+                    String element = (String) it.next();
+                    logMessage = logMessage + element + "\n";
+                }
+            }
+
+        }
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+    }
+}
+
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainerActivity.java b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainerActivity.java
new file mode 100644 (file)
index 0000000..7da5645
--- /dev/null
@@ -0,0 +1,447 @@
+/******************************************************************
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ * <p/>
+ * <p/>
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.container;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.AssetManager;
+import android.graphics.Typeface;
+import android.net.ConnectivityManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.iotivity.base.ModeType;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Activity for handling user's selection on UI for Resource container APIs. &
+ * for updating UI.
+ */
+public class ResourceContainerActivity extends Activity {
+    // private static final String LOG_TAG =
+    // ResourceContainerActivity.class.getSimpleName();
+
+    private final String                     LOG_TAG = "[ContainerSampleApp] "
+                                                             + this.getClass()
+                                                                     .getSimpleName();
+    private static ResourceContainerActivity resourceContainerActivityInstance;
+    private ResourceContainer                resourceContainerInstance;
+    private static String                    logMessage;
+
+    private Context                          context;
+    public ExpandableListAdapter             listAdapter;
+    public ExpandableListView                expListView;
+    public List<String>                      sensors;
+    public List<String>                      diApiList;
+    public List<String>                      bmiApiList;
+    HashMap<String, List<String>>            listChild;
+
+    private static Handler                   mHandler;
+    private Button                           startContainer;
+    private Button                           listBundles;
+    private static EditText                  logs;
+    private static String                    sdCardPath;
+
+    public static void setMessageLog(String message) {
+        logMessage = message;
+    }
+
+    public static ResourceContainerActivity getResourceContainerActivityObj() {
+        return resourceContainerActivityInstance;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+
+        super.onCreate(savedInstanceState);
+        context = this;
+
+        if (!isWifiConnected()) {
+            showWifiUnavailableDialog();
+            return;
+        }
+
+        configurePlatform();
+        CopyAssetsToSDCard();
+
+        setContentView(R.layout.resource_container);
+        resourceContainerActivityInstance = this;
+
+        resourceContainerInstance = new ResourceContainer();
+
+        expListView = (ExpandableListView) findViewById(R.id.lvExp);
+        startContainer = (Button) findViewById(R.id.startContainer);
+        listBundles = (Button) findViewById(R.id.listBundles);
+        listBundles.setEnabled(false);
+        logs = (EditText) findViewById(R.id.log);
+
+        sensors = new ArrayList<String>();
+        diApiList = new ArrayList<String>();
+        bmiApiList = new ArrayList<String>();
+        listChild = new HashMap<String, List<String>>();
+
+        // Adding list items (header)
+        sensors.add("Discomfort Index Sensor");
+        sensors.add("BMI Sensor");
+
+        // Adding child data [discomfort Index sensor]
+        diApiList.add("1. List bundle resources");
+        diApiList.add("2. Add Resource");
+        diApiList.add("3. Remove Resource");
+
+        // Adding child data [BMI sensor]
+        bmiApiList.add("1. Add Bundle");
+        bmiApiList.add("2. Start Bundle");
+        bmiApiList.add("3. List bundle resources");
+        bmiApiList.add("4. Add Resource ");
+        bmiApiList.add("5. Remove Resource");
+        bmiApiList.add("6. Stop Bundle");
+        bmiApiList.add("7. Remove Bundle");
+
+        listChild.put(sensors.get(0), diApiList);
+        listChild.put(sensors.get(1), bmiApiList);
+        listAdapter = new ExpandableList(this, sensors, listChild);
+
+        // getting the sd card path
+        sdCardPath = this.getFilesDir().getPath();
+
+        // handler for updating the UI i.e. MessageLog (TextBox) & ListView
+        mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case 0:
+                        expListView.setAdapter(listAdapter);
+                        expListView.bringToFront();
+                        break;
+                    case 1:
+                        logs.setText("");
+                        logs.setText(logMessage);
+                        Log.i(LOG_TAG, logMessage);
+                        break;
+                    case 2:
+                        listAdapter = null;
+                        expListView.setAdapter(listAdapter);
+                        break;
+                }
+            }
+        };
+        setHandler(mHandler);
+
+        // StartContainer/stopContainer Button Listener
+        startContainer.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+
+                String text = (String) startContainer.getText();
+                if (text.contains("Start")) {
+                    resourceContainerInstance.startContainer(sdCardPath);
+                    listAdapter = new ExpandableList(ResourceContainerActivity
+                            .getResourceContainerActivityObj(), sensors,
+                            listChild);
+                    listBundles.setEnabled(true);
+                    startContainer.setText("Stop Container");
+                } else {
+                    resourceContainerInstance.stopContainer();
+                    startContainer.setText("Start Container");
+                    listBundles.setEnabled(false);
+                    Message msg;
+                    msg = Message.obtain();
+                    msg.what = 2;
+                    resourceContainerActivityInstance.getHandler().sendMessage(
+                            msg);
+                }
+            }
+        });
+
+        // List Bundles Button Listener
+        listBundles.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                resourceContainerInstance.listBundles();
+            }
+        });
+
+        // Listener for the expandable list
+        expListView
+                .setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
+
+                    @Override
+                    public boolean onChildClick(ExpandableListView parent,
+                            View v, int groupPosition, int childPosition,
+                            long id) {
+
+                        if (0 == groupPosition) {
+                            if (childPosition == 0) {
+                                resourceContainerInstance
+                                        .listDIBundleResources();
+                            } else if (childPosition == 1) {
+                                resourceContainerInstance.addDIResourceConfig();
+                            } else if (childPosition == 2) {
+                                resourceContainerInstance
+                                        .removeDIResourceConfig();
+                            }
+                        } else {
+                            if (childPosition == 0) {
+                                resourceContainerInstance.addBMIBundle();
+                            } else if (childPosition == 1) {
+                                resourceContainerInstance.startBMIBundle();
+                            } else if (childPosition == 2) {
+                                resourceContainerInstance
+                                        .listBMIBundleResources();
+                            } else if (childPosition == 3) {
+                                resourceContainerInstance
+                                        .addBMIResourceConfig();
+                            } else if (childPosition == 4) {
+                                resourceContainerInstance
+                                        .removeBMIResourceConfig();
+                            } else if (childPosition == 5) {
+                                resourceContainerInstance.stopBMIBundle();
+                            } else if (childPosition == 6) {
+                                resourceContainerInstance.removeBMIBundle();
+                            }
+                        }
+                        return false;
+                    }
+                });
+    }
+
+    private void CopyAssetsToSDCard() {
+        AssetManager assetManager = getAssets();
+        String[] files = null;
+        try {
+            files = assetManager.list("lib");
+        } catch (IOException e) {
+            Log.e(LOG_TAG, e.getMessage());
+        }
+
+        for (String filename : files) {
+            InputStream in = null;
+            OutputStream out = null;
+            try {
+                in = assetManager.open("lib/" + filename);
+                out = new FileOutputStream(context.getFilesDir().getParent()
+                        + "/files/" + filename);
+                copyIndividualFile(in, out);
+                in.close();
+                in = null;
+                out.flush();
+                out.close();
+                out = null;
+            } catch (Exception e) {
+                Log.e(LOG_TAG, e.getMessage());
+            }
+        }
+    }
+
+    private void copyIndividualFile(InputStream in, OutputStream out)
+            throws IOException {
+
+        Log.i(LOG_TAG, "copyIndividualFile");
+        byte[] buffer = new byte[2048];
+        int read;
+        while ((read = in.read(buffer)) != -1) {
+            out.write(buffer, 0, read);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        listAdapter = null;
+        expListView.setAdapter(listAdapter);
+        resourceContainerInstance.stopContainer();
+        ResourceContainer.startBundleFlag = false;
+        super.onBackPressed();
+    }
+
+    // class for handling expandable list items
+    public class ExpandableList extends BaseExpandableListAdapter {
+
+        private Context                       mContext;
+        private HashMap<String, List<String>> mListDataChild;
+        private List<String>                  mListDataHeader;
+
+        // constructor
+        public ExpandableList(Context context, List<String> dataHeader,
+                HashMap<String, List<String>> childData) {
+            this.mContext = context;
+            this.mListDataHeader = dataHeader;
+            this.mListDataChild = childData;
+        }
+
+        // get the child ID
+        @Override
+        public long getChildId(int grpPosition, int childPosition) {
+            return childPosition;
+        }
+
+        // get the child
+        @Override
+        public Object getChild(int grpPosition, int childPosititon) {
+            return this.mListDataChild.get(
+                    this.mListDataHeader.get(grpPosition)).get(childPosititon);
+        }
+
+        // get Group View
+        @Override
+        public View getGroupView(int grpPosition, boolean isExpandable,
+                View changeView, ViewGroup head) {
+            String mainHeading = (String) getGroup(grpPosition);
+            if (changeView == null) {
+                LayoutInflater flater;
+                flater = (LayoutInflater) this.mContext
+                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                changeView = flater.inflate(R.layout.group, null);
+            }
+
+            TextView listHeader = (TextView) changeView
+                    .findViewById(R.id.ListHead);
+            listHeader.setTypeface(null, Typeface.BOLD);
+            listHeader.setText(mainHeading);
+            return changeView;
+        }
+
+        // get Children count
+        @Override
+        public int getChildrenCount(int grpPosition) {
+            int count = this.mListDataChild.get(
+                    this.mListDataHeader.get(grpPosition)).size();
+            return count;
+        }
+
+        // Get Group
+        @Override
+        public Object getGroup(int grpPosition) {
+            return this.mListDataHeader.get(grpPosition);
+        }
+
+        // get Group size
+        @Override
+        public int getGroupCount() {
+            int size = this.mListDataHeader.size();
+            return size;
+        }
+
+        // get Group ID
+        @Override
+        public long getGroupId(int grpPosition) {
+            return grpPosition;
+        }
+
+        // get Group View
+        @Override
+        public View getChildView(int grpPosition, final int childPosition,
+                boolean isLastItem, View changeView, ViewGroup head) {
+
+            final String innerText = (String) getChild(grpPosition,
+                    childPosition);
+
+            if (changeView == null) {
+                LayoutInflater flater = (LayoutInflater) this.mContext
+                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                changeView = flater.inflate(R.layout.list_item, null);
+            }
+
+            TextView textListChild = (TextView) changeView
+                    .findViewById(R.id.listItem);
+
+            textListChild.setText(innerText);
+            return changeView;
+        }
+
+        // To check whether child is selectable or not
+        @Override
+        public boolean isChildSelectable(int grpPosition, int childPosition) {
+            return true;
+        }
+
+        // To check the stable IDs
+        @Override
+        public boolean hasStableIds() {
+            return false;
+        }
+    }
+
+    private void showWifiUnavailableDialog() {
+        new AlertDialog.Builder(this)
+                .setTitle("Error")
+                .setMessage(
+                        "WiFi is not enabled/connected! Please connect the WiFi and start application again...")
+                .setCancelable(false)
+                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        finish();
+                    }
+                }).create().show();
+    }
+
+    private boolean isWifiConnected() {
+        ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
+        return connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
+                .isConnected();
+    }
+
+    private void configurePlatform() {
+        OcPlatform.Configure(new PlatformConfig(getApplicationContext(),
+                ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0", 0,
+                QualityOfService.LOW));
+        Log.i(LOG_TAG, "Configuration done successfully");
+    }
+
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    public void setHandler(Handler mHandler) {
+        ResourceContainerActivity.mHandler = mHandler;
+    }
+
+    public void displayToastMessage(String message) {
+        Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
+        toast.show();
+        Log.i(LOG_TAG, message);
+    }
+}
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/group.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/group.xml
new file mode 100644 (file)
index 0000000..2636052
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:padding="8dp" >
+
+    <TextView
+        android:id="@+id/ListHead"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
+        android:textSize="20dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/list_item.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/list_item.xml
new file mode 100644 (file)
index 0000000..7e7bf61
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="55dip"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/listItem"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:paddingBottom="5dp"
+        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
+        android:paddingTop="5dp"
+        android:textSize="20dip" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/resource_container.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/resource_container.xml
new file mode 100644 (file)
index 0000000..50456c4
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <Button
+        android:id="@+id/startContainer"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:text="Start Container" />
+
+    <ExpandableListView
+        android:id="@+id/lvExp"
+        android:layout_width="match_parent"
+        android:layout_height="300dp"
+        android:layout_below="@id/startContainer" />
+
+    <Button
+        android:id="@+id/listBundles"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:text="List Bundles" />
+
+    <EditText
+        android:id="@+id/log"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@id/lvExp"
+        android:editable="false"
+        android:ems="10" />
+
+</RelativeLayout>
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-hdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..cde69bc
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-mdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..c133a0c
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..bfa42f0
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..324e72c
Binary files /dev/null and b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values-v21/styles.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values-v21/styles.xml
new file mode 100644 (file)
index 0000000..dba3c41
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="AppTheme" parent="android:Theme.Material.Light">
+    </style>
+</resources>
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/strings.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..351e820
--- /dev/null
@@ -0,0 +1,4 @@
+<resources>
+    <string name="app_name">RCSampleServerApp</string>
+    <string name="resource_container">Resource Container</string>
+</resources>
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/styles.xml b/service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..18f919d
--- /dev/null
@@ -0,0 +1,4 @@
+<resources>
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+    </style>
+</resources>
diff --git a/service/resource-container/examples/android/RCSampleServerApp/build.gradle b/service/resource-container/examples/android/RCSampleServerApp/build.gradle
new file mode 100644 (file)
index 0000000..34a7ef9
--- /dev/null
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.0.0'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+
+        flatDir {
+            dirs 'libs'
+        }
+    }
+}
diff --git a/service/resource-container/examples/android/RCSampleServerApp/settings.gradle b/service/resource-container/examples/android/RCSampleServerApp/settings.gradle
new file mode 100644 (file)
index 0000000..e7b4def
--- /dev/null
@@ -0,0 +1 @@
+include ':app'