Implementation of JNI for publishing resource to RD
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Sun, 7 Aug 2016 23:44:12 +0000 (08:44 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Tue, 16 Aug 2016 11:05:39 +0000 (11:05 +0000)
Added JNI code for publishResourceToRD() of OCPlatform for converting
from Java to C++ and vice versa.

Change-Id: Ieb941ab2ce37c1aa39f44c8e51bbf49e3025a273
Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9911
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Habib Virji <habib.virji@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
android/android_api/SConscript
android/android_api/base/build.gradle
android/android_api/base/jni/Android.mk
android/android_api/base/jni/JniOcPlatform.cpp
android/android_api/base/jni/JniOcPlatform.h
android/android_api/base/jni/JniOnPublishResourceListener.cpp [new file with mode: 0644]
android/android_api/base/jni/JniOnPublishResourceListener.h [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java

index 5680548..af7bda9 100644 (file)
@@ -14,6 +14,7 @@ ANDROID_MQ = env.get('WITH_MQ')
 ANDROID_MQ_SUB = 0
 ANDROID_MQ_PUB = 0
 ANDROID_MQ_BROKER = 0
+ANDROID_RD_MODE = env.get('RD_MODE')
 
 if 'SUB' in ANDROID_MQ:
        ANDROID_MQ_SUB = 1
@@ -21,7 +22,7 @@ if 'PUB' in ANDROID_MQ:
        ANDROID_MQ_PUB = 1
 if 'BROKER' in ANDROID_MQ:
        ANDROID_MQ_BROKER = 1
-       
+
 os.environ['ANDROID_HOME'] = env.get('ANDROID_HOME')
 os.environ['ANDROID_NDK_HOME'] = env.get('ANDROID_NDK')
 
@@ -59,11 +60,11 @@ def ensure_libs(target, source, env):
 
 # build android_api
 jdk_env = Environment(ENV=os.environ)
-jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s -PWITH_MQ_PUB=%s -PWITH_MQ_SUB=%s -PWITH_MQ_BROKER=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED, ANDROID_MQ_PUB, ANDROID_MQ_SUB, ANDROID_MQ_BROKER), emitter = ensure_libs)
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s -PRD_MODE=%s -PWITH_MQ_PUB=%s -PWITH_MQ_SUB=%s -PWITH_MQ_BROKER=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED, ANDROID_RD_MODE, ANDROID_MQ_PUB, ANDROID_MQ_SUB, ANDROID_MQ_BROKER), emitter = ensure_libs)
 jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
 cmdBuildApi=jdk_env.Gradle(target="base/objs", source="base/src/main/java/org/iotivity/base/OcResource.java")
 
-jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + 'android/examples/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s -PWITH_MQ_PUB=%s -PWITH_MQ_SUB=%s -PWITH_MQ_BROKER=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED, ANDROID_MQ_PUB, ANDROID_MQ_SUB, ANDROID_MQ_BROKER))
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + 'android/examples/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s -PRD_MODE=%s -PWITH_MQ_PUB=%s -PWITH_MQ_SUB=%s -PWITH_MQ_BROKER=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED, ANDROID_RD_MODE, ANDROID_MQ_PUB, ANDROID_MQ_SUB, ANDROID_MQ_BROKER))
 cmdBuildExamples=jdk_env.Gradle(target="../examples/devicediscoveryclient/apk", source="../examples/devicediscoveryclient/src/main/java/org/iotivity/base/examples/DeviceDiscoveryClient.java")
 
 # android examples require android api to be built before being invoked
index 7acf8c4..257377f 100755 (executable)
@@ -46,6 +46,7 @@ android {
         buildConfigField "int", 'WITH_MQ_PUB', WITH_MQ_PUB\r
         buildConfigField "int", 'WITH_MQ_SUB', WITH_MQ_SUB\r
         buildConfigField "int", 'WITH_MQ_BROKER', WITH_MQ_BROKER\r
+        buildConfigField "String", 'RD_MODE', "\"RD_MODE\""\r
     }\r
     buildTypes {\r
         release {\r
@@ -98,7 +99,7 @@ task buildNative(type: Exec) {
         //for windows use 'ndk-build.cmd'\r
         //def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd')\r
         def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build')\r
-        commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", "SECURE=$SECURED", "WITH_MQ_PUB=$WITH_MQ_PUB", "WITH_MQ_SUB=$WITH_MQ_SUB", "WITH_MQ_BROKER=$WITH_MQ_BROKER"\r
+        commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", "SECURE=$SECURED", "RD_MODE=$RD_MODE", "WITH_MQ_PUB=$WITH_MQ_PUB", "WITH_MQ_SUB=$WITH_MQ_SUB", "WITH_MQ_BROKER=$WITH_MQ_BROKER"
     } else {\r
         println '##################'\r
         println 'Skipping NDK build'\r
index 811768d..d9b3048 100644 (file)
@@ -4,6 +4,7 @@ SECURED := $(SECURE)
 WITH_MQ_PUB := $(WITH_MQ_PUB)\r
 WITH_MQ_SUB := $(WITH_MQ_SUB)\r
 WITH_MQ_BROKER := $(WITH_MQ_BROKER)\r
+RD_MODE := $(RD_MODE)\r
 \r
 include $(CLEAR_VARS)\r
 OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)\r
@@ -93,12 +94,13 @@ LOCAL_SRC_FILES :=  JniOcStack.cpp \
                     JniOcSecurity.cpp \\r
                     JniOnDPDevicesFoundListener.cpp \\r
                     JniOnDirectPairingListener.cpp \\r
-                    JniOcDirectPairDevice.cpp\r
+                    JniOcDirectPairDevice.cpp \\r
+                    JniOnPublishResourceListener.cpp\r
 \r
 ifeq ($(MQ_FLAG), 1)\r
 #new listener will be added.\r
 endif\r
-\r
+
 ifeq ($(SECURED), 1)\r
     LOCAL_SRC_FILES +=  JniOcSecureResource.cpp \\r
                         JniOcProvisioning.cpp \\r
@@ -120,6 +122,9 @@ LOCAL_STATIC_LIBRARIES += android-ocprovision
 LOCAL_STATIC_LIBRARIES += android-ocpmapi\r
 endif\r
 \r
+ifeq "$(RD_MODE)" "CLIENT"\r
+LOCAL_CPPFLAGS += -DRD_CLIENT\r
+endif\r
 LOCAL_CPPFLAGS += -std=c++0x\r
 LOCAL_CPP_FEATURES := rtti exceptions\r
 LOCAL_C_INCLUDES := $(OIC_SRC_PATH)/include\r
index 12ec701..e5058c4 100644 (file)
@@ -464,6 +464,89 @@ void RemoveOnDirectPairingListener(JNIEnv* env, jobject jListener)
     directPairingListenerMapLock.unlock();
 }
 
+JniOnPublishResourceListener* AddOnPublishResourceListener(JNIEnv* env, jobject jListener)
+{
+    if (!env)
+    {
+        LOGD("env is null");
+        return nullptr;
+    }
+
+    JniOnPublishResourceListener *onPublishResourceListener = nullptr;
+
+    publishResourceListenerMapLock.lock();
+
+    for (auto it = onPublishResourceListenerMap.begin(); it !=
+            onPublishResourceListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            onPublishResourceListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            onPublishResourceListenerMap.insert(*it);
+            LOGD("onPublishResourceListener: ref. count incremented");
+            break;
+        }
+    }
+    if (!onPublishResourceListener)
+    {
+        onPublishResourceListener = new JniOnPublishResourceListener(env, jListener,
+                RemoveOnPublishResourceListener);
+        jobject jgListener = env->NewGlobalRef(jListener);
+        onPublishResourceListenerMap.insert(
+                std::pair<jobject, std::pair<JniOnPublishResourceListener*, int>>(
+                    jgListener,
+                    std::pair<JniOnPublishResourceListener*, int>(onPublishResourceListener, 1)));
+        LOGI("onPublishResourceListener: new listener");
+    }
+    publishResourceListenerMapLock.unlock();
+    return onPublishResourceListener;
+}
+
+void RemoveOnPublishResourceListener(JNIEnv* env, jobject jListener)
+{
+    if (!env)
+    {
+        ThrowOcException(JNI_EXCEPTION, "env is null");
+        return;
+    }
+
+    publishResourceListenerMapLock.lock();
+    bool isFound = false;
+    for (auto it = onPublishResourceListenerMap.begin(); it !=
+            onPublishResourceListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                onPublishResourceListenerMap.insert(*it);
+                LOGI("onPublishResourceListener: ref. count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniOnPublishResourceListener* listener = refPair.first;
+                delete listener;
+                onPublishResourceListenerMap.erase(it);
+                LOGI("onPublishResourceListener is removed");
+            }
+            isFound = true;
+            break;
+        }
+    }
+    if (!isFound)
+    {
+        ThrowOcException(JNI_EXCEPTION, "onPublishResourceListener not found");
+    }
+    publishResourceListenerMapLock.unlock();
+}
+
 /*
 * Class:     org_iotivity_base_OcPlatform
 * Method:    configure
@@ -2307,3 +2390,155 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendResponse0(
         ThrowOcException(e.code(), e.reason().c_str());
     }
 }
+
+/*
+ * Class:     org_iotivity_base_OcPlatform
+ * Method:    publishResourceToRD0
+ * Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPublishResourceListener;I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_publishResourceToRD0(
+        JNIEnv *env,
+        jclass clazz,
+        jstring jHost,
+        jint jConnectivityType,
+        jobject jListener,
+        jint jQoS)
+{
+    LOGD("OcPlatform_publishResourceToRD");
+#ifdef RD_CLIENT
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, nullptr);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onPublishResourceListener cannot be null");
+        return;
+    }
+    JniOnPublishResourceListener *onPubResListener = AddOnPublishResourceListener(env, jListener);
+
+    PublishResourceCallback pubResCallback = [onPubResListener](
+            const OCRepresentation& ocRepresentation,
+            const int eCode)
+    {
+        onPubResListener->onPublishResourceCallback(ocRepresentation, eCode);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::publishResourceToRD(
+            host,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            pubResCallback,
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Publish resource has failed");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
+#else
+    ThrowOcException(OC_STACK_ERROR, "Publish resource has failed");
+    return;
+#endif
+}
+
+/*
+ * Class:     org_iotivity_base_OcPlatform
+ * Method:    publishResourceToRD1
+ * Signature: (Ljava/lang/String;I[Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcPlatform/OnPublishResourceListener;I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_publishResourceToRD1(
+        JNIEnv *env,
+        jclass clazz,
+        jstring jHost,
+        jint jConnectivityType,
+        jobjectArray jResourceHandleArray,
+        jint jQoS,
+        jobject jListener)
+{
+    LOGD("OcPlatform_publishResourceToRD");
+#ifdef RD_CLIENT
+    if (!env)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "env is null");
+        return;
+    }
+    std::string host;
+    if (jHost)
+    {
+        host = env->GetStringUTFChars(jHost, nullptr);
+    }
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onPublishResourceListener cannot be null");
+        return;
+    }
+    if (!jResourceHandleArray)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null");
+        return;
+    }
+    JniOnPublishResourceListener *onPubResListener = AddOnPublishResourceListener(env, jListener);
+
+    PublishResourceCallback pubResCallback = [onPubResListener](
+            const OCRepresentation& ocRepresentation,
+            const int eCode)
+    {
+        onPubResListener->onPublishResourceCallback(ocRepresentation, eCode);
+    };
+
+    std::vector<OCResourceHandle> resourceHandleList;
+    size_t len = env->GetArrayLength(jResourceHandleArray);
+    for (size_t i = 0; i < len; ++i)
+    {
+        jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i);
+        if (!jResourceHandle)
+        {
+            ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null");
+            return;
+        }
+
+        JniOcResourceHandle* jniOcResourceHandle =
+            JniOcResourceHandle::getJniOcResourceHandlePtr(env, jResourceHandle);
+        if (!jniOcResourceHandle)
+        {
+            ThrowOcException(OC_STACK_INVALID_PARAM, "resource handle is invalid");
+            return;
+        }
+
+        resourceHandleList.push_back(jniOcResourceHandle->getOCResourceHandle());
+    }
+
+    try
+    {
+        OCStackResult result = OCPlatform::publishResourceToRD(
+            host,
+            static_cast<OCConnectivityType>(jConnectivityType),
+            resourceHandleList,
+            pubResCallback,
+            JniUtils::getQOS(env, static_cast<int>(jQoS)));
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Publish resource has failed");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
+#else
+    ThrowOcException(OC_STACK_ERROR, "Publish resource has failed");
+    return;
+#endif
+}
index a45f059..9c02910 100644 (file)
@@ -26,6 +26,7 @@
 #include "JniOnDPDevicesFoundListener.h"
 #include "JniOnDirectPairingListener.h"
 #include "JniOnPresenceListener.h"
+#include "JniOnPublishResourceListener.h"
 #include <mutex>
 
 #ifndef _Included_org_iotivity_base_OcPlatform
@@ -51,6 +52,8 @@ void RemoveOnDPDevicesFoundListener(JNIEnv* env, jobject jListener);
 JniOnDirectPairingListener* AddOnDirectPairingListener(JNIEnv* env, jobject jListener);
 void RemoveOnDirectPairingListener(JNIEnv* env, jobject jListener);
 
+JniOnPublishResourceListener* AddOnPublishResourceListener(JNIEnv* env, jobject jListener);
+void RemoveOnPublishResourceListener(JNIEnv* env, jobject jListener);
 
 std::map<jobject, std::pair<JniOnResourceFoundListener*, int>> onResourceFoundListenerMap;
 std::map<jobject, std::pair<JniOnDeviceInfoListener*, int>> onDeviceInfoListenerMap;
@@ -58,6 +61,7 @@ std::map<jobject, std::pair<JniOnPlatformInfoListener*, int>> onPlatformInfoList
 std::map<jobject, std::pair<JniOnPresenceListener*, int>> onPresenceListenerMap;
 std::map<jobject, std::pair<JniOnDPDevicesFoundListener*, int>> onDPDevicesFoundListenerMap;
 std::map<jobject, std::pair<JniOnDirectPairingListener*, int>> directPairingListenerMap;
+std::map<jobject, std::pair<JniOnPublishResourceListener*, int>> onPublishResourceListenerMap;
 
 std::mutex resourceFoundMapLock;
 std::mutex deviceInfoMapLock;
@@ -65,6 +69,7 @@ std::mutex platformInfoMapLock;
 std::mutex presenceMapLock;
 std::mutex dpDevicesFoundListenerMapLock;
 std::mutex directPairingListenerMapLock;
+std::mutex publishResourceListenerMapLock;
 
 #ifdef __cplusplus
 extern "C" {
@@ -325,6 +330,23 @@ extern "C" {
      */
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_doDirectPairing0
         (JNIEnv *, jclass, jobject, jint, jstring, jobject);
+
+    /*
+     * Class:     org_iotivity_base_OcPlatform
+     * Method:    publishResourceToRD0
+     * Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPublishResourceListener;I)V
+     */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_publishResourceToRD0
+        (JNIEnv *, jclass, jstring, jint, jobject, jint);
+
+    /*
+     * Class:     org_iotivity_base_OcPlatform
+     * Method:    publishResourceToRD1
+     * Signature: (Ljava/lang/String;I[Lorg/iotivity/base/OcResourceHandle
+     *            ;Lorg/iotivity/base/OcPlatform/OnPublishResourceListener;I)V
+     */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_publishResourceToRD1
+        (JNIEnv *, jclass, jstring, jint, jobjectArray, jobject, jint);
 #ifdef __cplusplus
 }
 #endif
diff --git a/android/android_api/base/jni/JniOnPublishResourceListener.cpp b/android/android_api/base/jni/JniOnPublishResourceListener.cpp
new file mode 100644 (file)
index 0000000..0204d86
--- /dev/null
@@ -0,0 +1,148 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 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 "JniOnPublishResourceListener.h"
+
+JniOnPublishResourceListener::JniOnPublishResourceListener(JNIEnv *env, jobject jListener,
+    RemoveListenerCallback removeListenerCallback)
+{
+    m_jwListener = env->NewWeakGlobalRef(jListener);
+    m_removeListenerCallback = removeListenerCallback;
+}
+
+JniOnPublishResourceListener::~JniOnPublishResourceListener()
+{
+    LOGI("~JniOnPublishResourceListener()");
+    if (m_jwListener)
+    {
+        jint ret = JNI_ERR;
+        JNIEnv *env = GetJNIEnv(ret);
+        if (nullptr == env)
+        {
+            return;
+        }
+        env->DeleteWeakGlobalRef(m_jwListener);
+        m_jwListener = nullptr;
+        if (JNI_EDETACHED == ret)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+    }
+}
+
+void JniOnPublishResourceListener::onPublishResourceCallback(
+        const OCRepresentation& ocRepresentation,
+        const int eCode)
+{
+    jint envRet = JNI_ERR;
+    JNIEnv *env = GetJNIEnv(envRet);
+    if (nullptr == env)
+    {
+        return;
+    }
+
+    jobject jListener = env->NewLocalRef(m_jwListener);
+    if (!jListener)
+    {
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+        return;
+    }
+    jclass clsL = env->GetObjectClass(jListener);
+
+    if (!clsL)
+    {
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+        return;
+    }
+
+    if (OC_STACK_OK != eCode && OC_STACK_RESOURCE_CREATED != eCode
+            && OC_STACK_RESOURCE_DELETED != eCode && OC_STACK_CONTINUE != eCode
+            && OC_STACK_RESOURCE_CHANGED != eCode)
+    {
+        jobject ex = GetOcException(eCode, "stack error in onPublishResourceCallback");
+        if (!ex)
+        {
+            goto CLEANUP;
+        }
+        jmethodID midL = env->GetMethodID(clsL, "onPublishResourceFailed",
+            "(Ljava/lang/Throwable;)V");
+        if (!midL)
+        {
+            goto CLEANUP;
+        }
+        env->CallVoidMethod(jListener, midL, ex);
+    }
+    else
+    {
+        OCRepresentation* rep = new OCRepresentation(ocRepresentation);
+        jlong handle = reinterpret_cast<jlong>(rep);
+        jobject jRepresentation = env->NewObject(g_cls_OcRepresentation,
+                                                 g_mid_OcRepresentation_N_ctor_bool,
+                                                 handle, true);
+        if (!jRepresentation)
+        {
+            delete rep;
+            goto CLEANUP;
+        }
+
+        jmethodID midL = env->GetMethodID(clsL, "onPublishResourceCompleted",
+            "(Lorg/iotivity/base/OcRepresentation;)V");
+        if (!midL)
+        {
+            delete rep;
+            goto CLEANUP;
+        }
+        env->CallVoidMethod(jListener, midL, jRepresentation);
+        if (env->ExceptionCheck())
+        {
+            LOGE("Java exception is thrown");
+            delete rep;
+        }
+    }
+
+CLEANUP:
+    checkExAndRemoveListener(env);
+    if (JNI_EDETACHED == envRet)
+    {
+        g_jvm->DetachCurrentThread();
+    }
+}
+
+void JniOnPublishResourceListener::checkExAndRemoveListener(JNIEnv* env)
+{
+    if (env->ExceptionCheck())
+    {
+        jthrowable ex = env->ExceptionOccurred();
+        env->ExceptionClear();
+        m_removeListenerCallback(env, m_jwListener);
+        env->Throw((jthrowable)ex);
+    }
+    else
+    {
+        m_removeListenerCallback(env, m_jwListener);
+    }
+}
diff --git a/android/android_api/base/jni/JniOnPublishResourceListener.h b/android/android_api/base/jni/JniOnPublishResourceListener.h
new file mode 100644 (file)
index 0000000..a147ba2
--- /dev/null
@@ -0,0 +1,40 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 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 "JniOcStack.h"
+
+#ifndef _Included_org_iotivity_base_OcPlatform_OnPublishResourceListener
+#define _Included_org_iotivity_base_OcPlatform_OnPublishResourceListener
+
+using namespace OC;
+
+class JniOnPublishResourceListener
+{
+public:
+    JniOnPublishResourceListener(JNIEnv *env, jobject listener,
+                                 RemoveListenerCallback removeListenerCallback);
+    ~JniOnPublishResourceListener();
+    void onPublishResourceCallback(const OCRepresentation& rep, const int eCode);
+private:
+    RemoveListenerCallback m_removeListenerCallback;
+    jweak m_jwListener;
+    void checkExAndRemoveListener(JNIEnv* env);
+};
+
+#endif
index e8f4a69..45a3e98 100644 (file)
@@ -950,6 +950,160 @@ public final class OcPlatform {
     throws OcException;
 
     /**
+     * API to publish resource to remote resource-directory.
+     *
+     * @param host                        Host Address of a service to publish resource.
+     * @param connectivityTypeSet         Set of types of connectivity. Example: IP
+     * @param onPublishResourceListener   Handles events, success states and failure states.
+     * @throws OcException if failure
+     */
+    public static void publishResourceToRD(
+            String host,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnPublishResourceListener onPublishResourceListener) throws OcException {
+        OcPlatform.initCheck();
+
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType)) {
+                connTypeInt |= connType.getValue();
+            }
+        }
+
+        OcPlatform.publishResourceToRD0(
+                host,
+                connTypeInt,
+                onPublishResourceListener,
+                sPlatformQualityOfService.getValue()
+        );
+    }
+
+    /**
+     * API to publish resource to remote resource-directory.
+     *
+     * @param host                        Host Address of a service to publish resource.
+     * @param connectivityTypeSet         Set of types of connectivity. Example: IP
+     * @param onPublishResourceListener   Handles events, success states and failure states.
+     * @param qualityOfService            the quality of communication.
+     * @throws OcException if failure
+     */
+    public static void publishResourceToRD(
+            String host,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            OnPublishResourceListener onPublishResourceListener,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType)) {
+                connTypeInt |= connType.getValue();
+            }
+        }
+
+        OcPlatform.publishResourceToRD0(
+                host,
+                connTypeInt,
+                onPublishResourceListener,
+                qualityOfService.getValue()
+        );
+    }
+
+    private static native void publishResourceToRD0(
+            String host,
+            int connectivityType,
+            OnPublishResourceListener onPublishResourceListener,
+            int qualityOfService) throws OcException;
+
+    /**
+     * API to publish resource to remote resource-directory.
+     *
+     * @param host                        Host Address of a service to publish resource.
+     * @param connectivityTypeSet         Set of types of connectivity. Example: IP
+     * @param ocResourceHandleList        reference to list of resource handles to be published.
+     * @param onPublishResourceListener   Handles events, success states and failure states.
+     * @throws OcException if failure
+     */
+    public static void publishResourceToRD(
+            String host,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            List<OcResourceHandle> ocResourceHandleList,
+            OnPublishResourceListener onPublishResourceListener) throws OcException {
+        OcPlatform.initCheck();
+
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType)) {
+                connTypeInt |= connType.getValue();
+            }
+        }
+
+        OcPlatform.publishResourceToRD1(
+                host,
+                connTypeInt,
+                ocResourceHandleList.toArray(
+                        new OcResourceHandle[ocResourceHandleList.size()]),
+                onPublishResourceListener,
+                sPlatformQualityOfService.getValue()
+        );
+    }
+
+    /**
+     * API to publish resource to remote resource-directory.
+     *
+     * @param host                        Host IP Address of a service to publish resource.
+     * @param connectivityTypeSet         Set of types of connectivity. Example: IP
+     * @param ocResourceHandleList        reference to list of resource handles to be published.
+     * @param onPublishResourceListener   Handles events, success states and failure states.
+     * @param qualityOfService            the quality of communication
+     * @throws OcException if failure
+     */
+    public static void publishResourceToRD(
+            String host,
+            EnumSet<OcConnectivityType> connectivityTypeSet,
+            List<OcResourceHandle> ocResourceHandleList,
+            OnPublishResourceListener onPublishResourceListener,
+            QualityOfService qualityOfService) throws OcException {
+        OcPlatform.initCheck();
+
+        int connTypeInt = 0;
+
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (connectivityTypeSet.contains(connType)) {
+                connTypeInt |= connType.getValue();
+            }
+        }
+
+        OcPlatform.publishResourceToRD1(
+            host,
+            connTypeInt,
+            ocResourceHandleList.toArray(
+                    new OcResourceHandle[ocResourceHandleList.size()]),
+            onPublishResourceListener,
+            qualityOfService.getValue()
+        );
+    }
+
+    private static native void publishResourceToRD1(
+            String host,
+            int connectivityType,
+            OcResourceHandle[] ocResourceHandleArray,
+            OnPublishResourceListener onPublishResourceListener,
+            int qualityOfService) throws OcException;
+
+    /**
+     * An OnPublishResourceListener can be registered via the OcPlatform.publishResourceToRD call.
+     * Event listeners are notified asynchronously
+     */
+    public interface OnPublishResourceListener {
+        public void onPublishResourceCompleted(OcRepresentation ocRepresentation);
+        public void onPublishResourceFailed(Throwable ex);
+    }
+
+    /**
      * An FindDirectPairingListener can be registered via the OcPlatform.findDirectPairingDevices call.
      * Event listeners are notified asynchronously
      */