From 89c8f508c9083e24739094a18566c26e436aa22f Mon Sep 17 00:00:00 2001 From: pilli manikanta Date: Wed, 28 Nov 2018 14:40:22 +0530 Subject: [PATCH] [CONPRO-1333] Fix for crash in virtual device Post response received on deleted JniOnPostListener object. Binding weak reference of JniOnPostListener gives safe way for checking the existance of JniOnPostListener object. https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/347 (cherry picked from commit 3f24e6e008ba6de12fe6ef8dd45cf4a096bc528c) Change-Id: Ie2305571e562202b69374bfc7960b2d5689b624d Signed-off-by: pilli manikanta Signed-off-by: DoHyun Pyun --- android/android_api/base/jni/JniListenerManager.h | 25 +- .../android_api/base/jni/JniOcAccountManager.cpp | 346 +++++++++++++------ android/android_api/base/jni/JniOcAccountManager.h | 8 +- android/android_api/base/jni/JniOcResource.cpp | 381 ++++++++++++++------- android/android_api/base/jni/JniOcResource.h | 14 +- android/android_api/base/jni/JniOnDeleteListener.h | 2 + android/android_api/base/jni/JniOnGetListener.h | 2 + .../android_api/base/jni/JniOnObserveListener.h | 2 + android/android_api/base/jni/JniOnPostListener.h | 2 + android/android_api/base/jni/JniOnPutListener.h | 2 + 10 files changed, 536 insertions(+), 248 deletions(-) diff --git a/android/android_api/base/jni/JniListenerManager.h b/android/android_api/base/jni/JniListenerManager.h index 8965e85..5b1a2f6 100644 --- a/android/android_api/base/jni/JniListenerManager.h +++ b/android/android_api/base/jni/JniListenerManager.h @@ -35,9 +35,9 @@ template class JniListenerManager { public: - T* addListener(JNIEnv* env, jobject jListener, JniOcResource* owner) + std::shared_ptr addListener(JNIEnv* env, jobject jListener, JniOcResource* owner) { - T *onEventListener = nullptr; + std::shared_ptr onEventListener = nullptr; m_mapMutex.lock(); @@ -57,19 +57,19 @@ public: if (!onEventListener) { - onEventListener = new T(env, jListener, owner); + onEventListener = std::make_shared(env, jListener, owner); jobject jgListener = env->NewGlobalRef(jListener); if (jgListener) { m_listenerMap.insert( std::pair>(jgListener, std::pair(onEventListener, 1))); + std::pair, int>>(jgListener, + std::pair, int>(onEventListener, 1))); } else { LOGD("OnEventListener: Failed to create global listener ref."); - delete onEventListener; m_mapMutex.unlock(); return nullptr; } @@ -81,9 +81,9 @@ public: } #ifdef WITH_CLOUD - T* addListener(JNIEnv* env, jobject jListener, JniOcAccountManager* owner) + std::shared_ptr addListener(JNIEnv* env, jobject jListener, JniOcAccountManager* owner) { - T *onEventListener = nullptr; + std::shared_ptr onEventListener = nullptr; m_mapMutex.lock(); @@ -103,19 +103,19 @@ public: if (!onEventListener) { - onEventListener = new T(env, jListener, owner); + onEventListener = std::make_shared(env, jListener, owner); jobject jgListener = env->NewGlobalRef(jListener); if (jgListener) { m_listenerMap.insert( std::pair>(jgListener, std::pair(onEventListener, 1))); + std::pair, int>>(jgListener, + std::pair, int>(onEventListener, 1))); } else { LOGD("OnEventListener: Failed to create global listener ref."); - delete onEventListener; m_mapMutex.unlock(); return nullptr; } @@ -145,8 +145,6 @@ public: else { env->DeleteGlobalRef(it->first); - T* listener = refPair.first; - delete listener; m_listenerMap.erase(it); LOGI("OnEventListener is removed"); } @@ -165,7 +163,6 @@ public: { env->DeleteGlobalRef(pair.first); auto refPair = pair.second; - delete refPair.first; } m_listenerMap.clear(); @@ -173,7 +170,7 @@ public: } private: - std::map> m_listenerMap; + std::map, int>> m_listenerMap; std::mutex m_mapMutex; }; diff --git a/android/android_api/base/jni/JniOcAccountManager.cpp b/android/android_api/base/jni/JniOcAccountManager.cpp index 2d7e861..a47278f 100644 --- a/android/android_api/base/jni/JniOcAccountManager.cpp +++ b/android/android_api/base/jni/JniOcAccountManager.cpp @@ -84,22 +84,22 @@ JniOcAccountManager* JniOcAccountManager::getJniOcAccountManagerPtr(JNIEnv *env, return accountManager; } -JniOnGetListener* JniOcAccountManager::addOnGetListener(JNIEnv* env, jobject jListener) +JniOnGetListener::Ptr JniOcAccountManager::addOnGetListener(JNIEnv* env, jobject jListener) { return this->m_onGetManager.addListener(env, jListener, this); } -JniOnPostListener* JniOcAccountManager::addOnPostListener(JNIEnv* env, jobject jListener) +JniOnPostListener::Ptr JniOcAccountManager::addOnPostListener(JNIEnv* env, jobject jListener) { return this->m_onPostManager.addListener(env, jListener, this); } -JniOnDeleteListener* JniOcAccountManager::addOnDeleteListener(JNIEnv* env, jobject jListener) +JniOnDeleteListener::Ptr JniOcAccountManager::addOnDeleteListener(JNIEnv* env, jobject jListener) { return this->m_onDeleteManager.addListener(env, jListener, this); } -JniOnObserveListener* JniOcAccountManager::addOnObserveListener(JNIEnv* env, jobject jListener) +JniOnObserveListener::Ptr JniOcAccountManager::addOnObserveListener(JNIEnv* env, jobject jListener) { return this->m_onObserveManager.addListener(env, jListener, this); } @@ -127,18 +127,25 @@ void JniOcAccountManager::removeOnObserveListener(JNIEnv* env, jobject jListener OCStackResult JniOcAccountManager::signUp(JNIEnv* env, const std::string& authProvider, const std::string& authCode, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->signUp(authProvider, authCode, postCallback); } @@ -147,18 +154,25 @@ OCStackResult JniOcAccountManager::signUp(JNIEnv* env, const std::string& authPr const std::string& authCode, const QueryParamsMap& options, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->signUp(authProvider, authCode, options, postCallback); } @@ -166,18 +180,25 @@ OCStackResult JniOcAccountManager::signUp(JNIEnv* env, const std::string& authPr OCStackResult JniOcAccountManager::signIn(JNIEnv* env, const std::string& userUuid, const std::string& accessToken, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->signIn(userUuid, accessToken, postCallback); } @@ -185,18 +206,25 @@ OCStackResult JniOcAccountManager::signIn(JNIEnv* env, const std::string& userUu OCStackResult JniOcAccountManager::signOut(JNIEnv* env, const std::string& accessToken, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->signOut(accessToken, postCallback); } @@ -205,18 +233,25 @@ OCStackResult JniOcAccountManager::refreshAccessToken(JNIEnv* env, const std::st const std::string& refreshToken, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->refreshAccessToken(userUuid, refreshToken, postCallback); } @@ -224,18 +259,25 @@ OCStackResult JniOcAccountManager::refreshAccessToken(JNIEnv* env, const std::st OCStackResult JniOcAccountManager::searchUser(JNIEnv* env, const QueryParamsMap& queryMap, jobject jListener) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); + if (nullptr == onGetListener) { LOGE("onGetListener is null"); return OC_STACK_ERROR; } - GetCallback getCallback = [onGetListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + GetCallback getCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); return m_sharedAccountManager->searchUser(queryMap, getCallback); } @@ -243,36 +285,49 @@ OCStackResult JniOcAccountManager::searchUser(JNIEnv* env, const QueryParamsMap& OCStackResult JniOcAccountManager::deleteDevice(JNIEnv* env, const std::string& accessToken, const std::string& deviceId, jobject jListener) { - JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + JniOnDeleteListener::Ptr onDeleteListener = addOnDeleteListener(env, jListener); + if (nullptr == onDeleteListener) { LOGE("onDeleteListener is null"); return OC_STACK_ERROR; } - DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, - const int eCode) + DeleteCallback deleteCallback = std::bind([](const HeaderOptions& opts, + const int eCode, + std::weak_ptr weak_ref) { - onDeleteListener->onDeleteCallback(opts, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onDeleteCallback(opts, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, onDeleteListener); return m_sharedAccountManager->deleteDevice(accessToken, deviceId, deleteCallback); } OCStackResult JniOcAccountManager::createGroup(JNIEnv* env, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->createGroup(postCallback); } @@ -280,18 +335,25 @@ OCStackResult JniOcAccountManager::createGroup(JNIEnv* env, jobject jListener) OCStackResult JniOcAccountManager::createGroup(JNIEnv* env, const QueryParamsMap& queryMap, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->createGroup(queryMap, postCallback); } @@ -299,36 +361,49 @@ OCStackResult JniOcAccountManager::createGroup(JNIEnv* env, const QueryParamsMap OCStackResult JniOcAccountManager::deleteGroup(JNIEnv* env, const std::string& groupId, jobject jListener) { - JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + JniOnDeleteListener::Ptr onDeleteListener = addOnDeleteListener(env, jListener); + if (nullptr == onDeleteListener) { LOGE("onDeleteListener is null"); return OC_STACK_ERROR; } - DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, - const int eCode) + DeleteCallback deleteCallback = std::bind([](const HeaderOptions& opts, + const int eCode, + std::weak_ptr weak_ref) { - onDeleteListener->onDeleteCallback(opts, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onDeleteCallback(opts, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, onDeleteListener); return m_sharedAccountManager->deleteGroup(groupId, deleteCallback); } OCStackResult JniOcAccountManager::getGroupInfoAll(JNIEnv* env, jobject jListener) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); + if (nullptr == onGetListener) { LOGE("onGetListener is null"); return OC_STACK_ERROR; } - GetCallback getCallback = [onGetListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + GetCallback getCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); return m_sharedAccountManager->getGroupInfoAll(getCallback); } @@ -336,18 +411,25 @@ OCStackResult JniOcAccountManager::getGroupInfoAll(JNIEnv* env, jobject jListene OCStackResult JniOcAccountManager::getGroupInfo(JNIEnv* env, const std::string& groupId, jobject jListener) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); + if (nullptr == onGetListener) { LOGE("onGetListener is null"); return OC_STACK_ERROR; } - GetCallback getCallback = [onGetListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + GetCallback getCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); return m_sharedAccountManager->getGroupInfo(groupId, getCallback); } @@ -356,18 +438,25 @@ OCStackResult JniOcAccountManager::addPropertyValueToGroup(JNIEnv* env, const st const OCRepresentation& propertyValue, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->addPropertyValueToGroup(groupId, propertyValue, postCallback); } @@ -377,18 +466,25 @@ OCStackResult JniOcAccountManager::deletePropertyValueFromGroup(JNIEnv* env, const OCRepresentation& propertyValue, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->deletePropertyValueFromGroup(groupId, propertyValue, postCallback); @@ -399,18 +495,25 @@ OCStackResult JniOcAccountManager::updatePropertyValueOnGroup(JNIEnv* env, const OCRepresentation& propertyValue, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->updatePropertyValueOnGroup(groupId, propertyValue, postCallback); @@ -418,18 +521,26 @@ OCStackResult JniOcAccountManager::updatePropertyValueOnGroup(JNIEnv* env, OCStackResult JniOcAccountManager::observeGroup(JNIEnv* env, jobject jListener) { - JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener); + JniOnObserveListener::Ptr onObserveListener = addOnObserveListener(env, jListener); + if (nullptr == onObserveListener) { LOGE("onObserveListener is null"); return OC_STACK_ERROR; } - ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + ObserveCallback observeCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int& eCode, + const int& sequenceNumber, + std::weak_ptr weak_ref) { - onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onObserveCallback(opts, rep, eCode, sequenceNumber); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, onObserveListener); return m_sharedAccountManager->observeGroup(observeCallback); } @@ -441,18 +552,26 @@ OCStackResult JniOcAccountManager::cancelObserveGroup() OCStackResult JniOcAccountManager::observeInvitation(JNIEnv* env, jobject jListener) { - JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener); + JniOnObserveListener::Ptr onObserveListener = addOnObserveListener(env, jListener); + if (nullptr == onObserveListener) { LOGE("onObserveListener is null"); return OC_STACK_ERROR; } - ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + ObserveCallback observeCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int& eCode, + const int& sequenceNumber, + std::weak_ptr weak_ref) { - onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onObserveCallback(opts, rep, eCode, sequenceNumber); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, onObserveListener); return m_sharedAccountManager->observeInvitation(observeCallback); } @@ -465,18 +584,25 @@ OCStackResult JniOcAccountManager::cancelObserveInvitation() OCStackResult JniOcAccountManager::sendInvitation(JNIEnv* env, const std::string& groupId, const std::string& userUuid, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); + if (nullptr == onPostListener) { LOGE("onPostListener is null"); return OC_STACK_ERROR; } - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedAccountManager->sendInvitation(groupId, userUuid, postCallback); } @@ -484,18 +610,24 @@ OCStackResult JniOcAccountManager::sendInvitation(JNIEnv* env, const std::string OCStackResult JniOcAccountManager::cancelInvitation(JNIEnv* env, const std::string& groupId, const std::string& userUuid, jobject jListener) { - JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + JniOnDeleteListener::Ptr onDeleteListener = addOnDeleteListener(env, jListener); + if (nullptr == onDeleteListener) { LOGE("onDeleteListener is null"); return OC_STACK_ERROR; } - DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, - const int eCode) + DeleteCallback deleteCallback = std::bind([](const HeaderOptions& opts, + const int eCode, + std::weak_ptr weak_ref) { - onDeleteListener->onDeleteCallback(opts, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onDeleteCallback(opts, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, onDeleteListener); return m_sharedAccountManager->cancelInvitation(groupId, userUuid, deleteCallback); } @@ -503,18 +635,24 @@ OCStackResult JniOcAccountManager::cancelInvitation(JNIEnv* env, const std::stri OCStackResult JniOcAccountManager::replyToInvitation(JNIEnv* env, const std::string& groupId, const bool accept, jobject jListener) { - JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + JniOnDeleteListener::Ptr onDeleteListener = addOnDeleteListener(env, jListener); + if (nullptr == onDeleteListener) { LOGE("onDeleteListener is null"); return OC_STACK_ERROR; } - DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, - const int eCode) + DeleteCallback deleteCallback = std::bind([](const HeaderOptions& opts, + const int eCode, + std::weak_ptr weak_ref) { - onDeleteListener->onDeleteCallback(opts, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onDeleteCallback(opts, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, onDeleteListener); return m_sharedAccountManager->replyToInvitation(groupId, accept, deleteCallback); } diff --git a/android/android_api/base/jni/JniOcAccountManager.h b/android/android_api/base/jni/JniOcAccountManager.h index 9eb3fee..34767dc 100644 --- a/android/android_api/base/jni/JniOcAccountManager.h +++ b/android/android_api/base/jni/JniOcAccountManager.h @@ -78,10 +78,10 @@ public: OCStackResult replyToInvitation(JNIEnv* env, const std::string& groupId, const bool accept, jobject jListener); - JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener); - JniOnPostListener* addOnPostListener(JNIEnv* env, jobject jListener); - JniOnDeleteListener* addOnDeleteListener(JNIEnv* env, jobject jListener); - JniOnObserveListener* addOnObserveListener(JNIEnv* env, jobject jListener); + JniOnGetListener::Ptr addOnGetListener(JNIEnv* env, jobject jListener); + JniOnPostListener::Ptr addOnPostListener(JNIEnv* env, jobject jListener); + JniOnDeleteListener::Ptr addOnDeleteListener(JNIEnv* env, jobject jListener); + JniOnObserveListener::Ptr addOnObserveListener(JNIEnv* env, jobject jListener); void removeOnGetListener(JNIEnv* env, jobject jListener); void removeOnPostListener(JNIEnv* env, jobject jListener); diff --git a/android/android_api/base/jni/JniOcResource.cpp b/android/android_api/base/jni/JniOcResource.cpp index 9d30ba2..73fdf1d 100644 --- a/android/android_api/base/jni/JniOcResource.cpp +++ b/android/android_api/base/jni/JniOcResource.cpp @@ -60,15 +60,20 @@ JniOcResource::~JniOcResource() OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); - GetCallback getCallback = [onGetListener]( + GetCallback getCallback = std::bind([]( const HeaderOptions& opts, const OCRepresentation& rep, - const int eCode) + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); return m_sharedResource->get(queryParametersMap, getCallback); } @@ -76,13 +81,20 @@ OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParamet OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); - GetCallback getCallback = [onGetListener](const HeaderOptions& opts, const OCRepresentation& rep, - const int eCode) + GetCallback getCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); return m_sharedResource->get(queryParametersMap, getCallback, QoS); } @@ -94,44 +106,63 @@ OCStackResult JniOcResource::get( const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); - GetCallback getCallback = [onGetListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + GetCallback getCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); - return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap, - getCallback); + return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap, getCallback); } OCStackResult JniOcResource::get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + JniOnGetListener::Ptr onGetListener = addOnGetListener(env, jListener); - GetCallback getCallback = [onGetListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + GetCallback getCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onGetListener->onGetCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onGetCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onGetListener); - return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap, - getCallback, QoS); + return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap, getCallback, QoS); } OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + JniOnPutListener::Ptr onPutListener = addOnPutListener(env, jListener); - PutCallback putCallback = [onPutListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PutCallback putCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPutListener->onPutCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPutCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPutListener); return m_sharedResource->put(representation, queryParametersMap, putCallback); } @@ -139,13 +170,20 @@ OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representa OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + JniOnPutListener::Ptr onPutListener = addOnPutListener(env, jListener); - PutCallback putCallback = [onPutListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PutCallback putCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPutListener->onPutCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPutCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPutListener); return m_sharedResource->put(representation, queryParametersMap, putCallback, QoS); } @@ -154,44 +192,65 @@ OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + JniOnPutListener::Ptr onPutListener = addOnPutListener(env, jListener); - PutCallback putCallback = [onPutListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PutCallback putCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPutListener->onPutCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPutCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPutListener); return m_sharedResource->put(resourceType, resourceInterface, representation, - queryParametersMap, putCallback); + queryParametersMap, putCallback); } OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + JniOnPutListener::Ptr onPutListener = addOnPutListener(env, jListener); - PutCallback putCallback = [onPutListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PutCallback putCallback = std::bind( []( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPutListener->onPutCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPutCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPutListener); return m_sharedResource->put(resourceType, resourceInterface, representation, - queryParametersMap, putCallback, QoS); + queryParametersMap, putCallback, QoS); } OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedResource->post(representation, queryParametersMap, postCallback); } @@ -199,13 +258,20 @@ OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &represent OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedResource->post(representation, queryParametersMap, postCallback, QoS); } @@ -214,55 +280,82 @@ OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedResource->post(resourceType, resourceInterface, representation, - queryParametersMap, postCallback); + queryParametersMap, postCallback); } OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedResource->post(resourceType, resourceInterface, representation, - queryParametersMap, postCallback, QoS); + queryParametersMap, postCallback, QoS); } OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener) { - JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + JniOnDeleteListener::Ptr onDeleteListener = addOnDeleteListener(env, jListener); - DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, - const int eCode) + DeleteCallback deleteCallback = std::bind([]( + const HeaderOptions& opts, + const int eCode, + std::weak_ptr weak_ref) { - onDeleteListener->onDeleteCallback(opts, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onDeleteCallback(opts, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, onDeleteListener); return m_sharedResource->deleteResource(deleteCallback); } OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS) { - JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + JniOnDeleteListener::Ptr onDeleteListener = addOnDeleteListener(env, jListener); - DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, const int eCode) + DeleteCallback deleteCallback = std::bind([]( + const HeaderOptions& opts, + const int eCode, + std::weak_ptr weak_ref) { - onDeleteListener->onDeleteCallback(opts, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onDeleteCallback(opts, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, onDeleteListener); return m_sharedResource->deleteResource(deleteCallback, QoS); } @@ -270,13 +363,22 @@ OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, Qual OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap, jobject jListener) { - JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener); + JniOnObserveListener::Ptr onObserveListener = addOnObserveListener(env, jListener); - ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + ObserveCallback observeCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int& eCode, + const int& sequenceNumber, + std::weak_ptr weak_ref) { - onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onObserveCallback(opts, rep, eCode, sequenceNumber); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, onObserveListener); return m_sharedResource->observe(observeType, queryParametersMap, observeCallback); } @@ -284,13 +386,22 @@ OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType, OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener); + JniOnObserveListener::Ptr onObserveListener = addOnObserveListener(env, jListener); - ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + ObserveCallback observeCallback = std::bind([]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int& eCode, + const int& sequenceNumber, + std::weak_ptr weak_ref) { - onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onObserveCallback(opts, rep, eCode, sequenceNumber); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, onObserveListener); return m_sharedResource->observe(observeType, queryParametersMap, observeCallback, QoS); } @@ -361,27 +472,27 @@ std::string JniOcResource::deviceName() const return m_sharedResource->deviceName(); } -JniOnGetListener* JniOcResource::addOnGetListener(JNIEnv* env, jobject jListener) +JniOnGetListener::Ptr JniOcResource::addOnGetListener(JNIEnv* env, jobject jListener) { return this->m_onGetManager.addListener(env, jListener, this); } -JniOnPutListener* JniOcResource::addOnPutListener(JNIEnv* env, jobject jListener) +JniOnPutListener::Ptr JniOcResource::addOnPutListener(JNIEnv* env, jobject jListener) { return this->m_onPutManager.addListener(env, jListener, this); } -JniOnPostListener* JniOcResource::addOnPostListener(JNIEnv* env, jobject jListener) +JniOnPostListener::Ptr JniOcResource::addOnPostListener(JNIEnv* env, jobject jListener) { return this->m_onPostManager.addListener(env, jListener, this); } -JniOnDeleteListener* JniOcResource::addOnDeleteListener(JNIEnv* env, jobject jListener) +JniOnDeleteListener::Ptr JniOcResource::addOnDeleteListener(JNIEnv* env, jobject jListener) { return this->m_onDeleteManager.addListener(env, jListener, this); } -JniOnObserveListener* JniOcResource::addOnObserveListener(JNIEnv* env, jobject jListener) +JniOnObserveListener::Ptr JniOcResource::addOnObserveListener(JNIEnv* env, jobject jListener) { return this->m_onObserveManager.addListener(env, jListener, this); } @@ -412,7 +523,7 @@ void JniOcResource::removeOnObserveListener(JNIEnv* env, jobject jListener) } #ifdef WITH_MQ -JniOnMQTopicFoundListener* JniOcResource::addOnTopicFoundListener(JNIEnv* env, jobject jListener) +std::shared_ptr JniOcResource::addOnTopicFoundListener(JNIEnv* env, jobject jListener) { return this->m_onFoundTopicResourceManager.addListener(env, jListener, this); } @@ -422,7 +533,7 @@ void JniOcResource::removeOnTopicFoundListener(JNIEnv* env, jobject jListener) this->m_onFoundTopicResourceManager.removeListener(env, jListener); } -JniOnMQSubscribeListener* JniOcResource::addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener) +std::shared_ptr JniOcResource::addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener) { return this->m_onSubcribeTopicManager.addListener(env, jListener, this); } @@ -456,13 +567,19 @@ JniOcResource* JniOcResource::getJniOcResourcePtr(JNIEnv *env, jobject thiz) OCStackResult JniOcResource::discoveryMQTopics(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnMQTopicFoundListener *onTopicFoundListener = addOnTopicFoundListener(env, jListener); + std::shared_ptr onTopicFoundListener = addOnTopicFoundListener(env, jListener); - MQTopicCallback findCallback = [onTopicFoundListener](const int& eCode, - const std::string& uri, std::shared_ptr resource) + MQTopicCallback findCallback = std::bind([](const int& eCode, + const std::string& uri, + std::shared_ptr resource + std::weak_ptr weak_ref) { - onTopicFoundListener->foundTopicCallback(eCode, uri, resource); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->foundTopicCallback(eCode, uri, resource); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onTopicFoundListener); return m_sharedResource->discoveryMQTopics(queryParametersMap, findCallback, QoS); } @@ -471,13 +588,19 @@ OCStackResult JniOcResource::createMQTopic(JNIEnv* env, const OCRepresentation &representation, const std::string &targetUri, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnMQTopicFoundListener *onTopicCreatedListener = addOnTopicFoundListener(env, jListener); + std::shared_ptr onTopicCreatedListener = addOnTopicFoundListener(env, jListener); - MQTopicCallback createCallback = [onTopicCreatedListener](const int& eCode, - const std::string& uri, std::shared_ptr resource) + MQTopicCallback createCallback = std::bind([](const int& eCode, + const std::string& uri, + std::shared_ptr resource, + std::weak_ptr weak_ref) { - onTopicCreatedListener->createdTopicCallback(eCode, uri, resource); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->createdTopicCallback(eCode, uri, resource); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onTopicCreatedListener); return m_sharedResource->createMQTopic(representation, targetUri, queryParametersMap, @@ -488,13 +611,21 @@ OCStackResult JniOcResource::createMQTopic(JNIEnv* env, OCStackResult JniOcResource::subscribeMQTopic(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnMQSubscribeListener *onSubscribeListener = addOnMQTopicSubscribeListener(env, jListener); + std::shared_ptr onSubscribeListener = addOnMQTopicSubscribeListener(env, jListener); - ObserveCallback subscribeCallback = [onSubscribeListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + ObserveCallback subscribeCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int& eCode, + const int& sequenceNumber, + std::weak_ptr weak_ref) { - onSubscribeListener->onSubscribeCallback(opts, rep, eCode, sequenceNumber); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onSubscribeCallback(opts, rep, eCode, sequenceNumber); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, onSubscribeListener); return m_sharedResource->subscribeMQTopic(ObserveType::Observe, queryParametersMap, subscribeCallback, QoS); @@ -508,13 +639,19 @@ OCStackResult JniOcResource::unsubscribeMQTopic(QualityOfService QoS) OCStackResult JniOcResource::requestMQPublish(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + listener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedResource->requestMQPublish(queryParametersMap, postCallback, QoS); } @@ -523,13 +660,19 @@ OCStackResult JniOcResource::requestMQPublish(JNIEnv* env, OCStackResult JniOcResource::publishMQTopic(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) { - JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + JniOnPostListener::Ptr onPostListener = addOnPostListener(env, jListener); - PostCallback postCallback = [onPostListener](const HeaderOptions& opts, - const OCRepresentation& rep, const int eCode) + PostCallback postCallback = std::bind([](const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode, + std::weak_ptr weak_ref) { - onPostListener->onPostCallback(opts, rep, eCode); - }; + auto listener = weak_ref.lock(); + if (listener) + { + onPostListener->onPostCallback(opts, rep, eCode); + } + }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, onPostListener); return m_sharedResource->publishMQTopic(representation, queryParametersMap, postCallback, QoS); diff --git a/android/android_api/base/jni/JniOcResource.h b/android/android_api/base/jni/JniOcResource.h index e05da82..c9a69f0 100644 --- a/android/android_api/base/jni/JniOcResource.h +++ b/android/android_api/base/jni/JniOcResource.h @@ -94,11 +94,11 @@ public: std::string sid() const; std::string deviceName() const; - JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener); - JniOnPutListener* addOnPutListener(JNIEnv* env, jobject jListener); - JniOnPostListener* addOnPostListener(JNIEnv* env, jobject jListener); - JniOnDeleteListener* addOnDeleteListener(JNIEnv* env, jobject jListener); - JniOnObserveListener* addOnObserveListener(JNIEnv* env, jobject jListener); + JniOnGetListener::Ptr addOnGetListener(JNIEnv* env, jobject jListener); + JniOnPutListener::Ptr addOnPutListener(JNIEnv* env, jobject jListener); + JniOnPostListener::Ptr addOnPostListener(JNIEnv* env, jobject jListener); + JniOnDeleteListener::Ptr addOnDeleteListener(JNIEnv* env, jobject jListener); + JniOnObserveListener::Ptr addOnObserveListener(JNIEnv* env, jobject jListener); void removeOnGetListener(JNIEnv* env, jobject jListener); void removeOnPutListener(JNIEnv* env, jobject jListener); @@ -111,10 +111,10 @@ public: static JniOcResource* getJniOcResourcePtr(JNIEnv *env, jobject thiz); #ifdef WITH_MQ - JniOnMQTopicFoundListener* addOnTopicFoundListener(JNIEnv* env, jobject jListener); + std::shared_ptr addOnTopicFoundListener(JNIEnv* env, jobject jListener); void removeOnTopicFoundListener(JNIEnv* env, jobject jListener); - JniOnMQSubscribeListener* addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener); + std::shared_ptr addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener); void removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener); OCStackResult discoveryMQTopics(JNIEnv* env, const QueryParamsMap &queryParametersMap, diff --git a/android/android_api/base/jni/JniOnDeleteListener.h b/android/android_api/base/jni/JniOnDeleteListener.h index 9354232..753bce1 100644 --- a/android/android_api/base/jni/JniOnDeleteListener.h +++ b/android/android_api/base/jni/JniOnDeleteListener.h @@ -34,6 +34,8 @@ class JniOcAccountManager; class JniOnDeleteListener { public: + typedef std::shared_ptr Ptr; + JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcResource* owner); #ifdef WITH_CLOUD JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner); diff --git a/android/android_api/base/jni/JniOnGetListener.h b/android/android_api/base/jni/JniOnGetListener.h index abffaa0..683a33b 100644 --- a/android/android_api/base/jni/JniOnGetListener.h +++ b/android/android_api/base/jni/JniOnGetListener.h @@ -34,6 +34,8 @@ class JniOcAccountManager; class JniOnGetListener { public: + typedef std::shared_ptr Ptr; + JniOnGetListener(JNIEnv *env, jobject listener, JniOcResource* resource); #ifdef WITH_CLOUD JniOnGetListener(JNIEnv *env, jobject listener, JniOcAccountManager* resource); diff --git a/android/android_api/base/jni/JniOnObserveListener.h b/android/android_api/base/jni/JniOnObserveListener.h index 3fc478d..0a51e8c 100644 --- a/android/android_api/base/jni/JniOnObserveListener.h +++ b/android/android_api/base/jni/JniOnObserveListener.h @@ -34,6 +34,8 @@ class JniOcAccountManager; class JniOnObserveListener { public: + typedef std::shared_ptr Ptr; + JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcResource* owner); #ifdef WITH_CLOUD JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner); diff --git a/android/android_api/base/jni/JniOnPostListener.h b/android/android_api/base/jni/JniOnPostListener.h index bf3387c..12075f5 100644 --- a/android/android_api/base/jni/JniOnPostListener.h +++ b/android/android_api/base/jni/JniOnPostListener.h @@ -34,6 +34,8 @@ class JniOcAccountManager; class JniOnPostListener { public: + typedef std::shared_ptr Ptr; + JniOnPostListener(JNIEnv *env, jobject jListener, JniOcResource* owner); #ifdef WITH_CLOUD JniOnPostListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner); diff --git a/android/android_api/base/jni/JniOnPutListener.h b/android/android_api/base/jni/JniOnPutListener.h index 80057e1..bfee5db 100644 --- a/android/android_api/base/jni/JniOnPutListener.h +++ b/android/android_api/base/jni/JniOnPutListener.h @@ -31,6 +31,8 @@ class JniOcResource; class JniOnPutListener { public: + typedef std::shared_ptr Ptr; + JniOnPutListener(JNIEnv *env, jobject jListener, JniOcResource* resource); ~JniOnPutListener(); -- 2.7.4