1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 #include "JniRcsResourceContainer.h"
23 #include "JavaClasses.h"
24 #include "JavaLocalRef.h"
25 #include "JNIEnvWrapper.h"
30 #include "ResourceContainerBundleAPI.h"
31 #include "JniBundleResource.h"
32 #include "RCSResourceContainer.h"
36 #define LOG_TAG "JNI-RCSResourceContainer"
38 using namespace OIC::Service;
40 #define CLS_NAME_BUNDLE_INFO "org/iotivity/service/resourcecontainer/RcsBundleInfo"
42 std::map< string, BundleResource::Ptr > android_resources;
46 jclass g_cls_RCSBundleInfo;
47 jfieldID g_field_mNativeHandle;
49 jmethodID g_ctor_RCSBundleInfo;
51 std::map< std::string, std::string > convertJavaMapToParamsMap(JNIEnvWrapper *env,
54 EXPECT_RET_DEF(mapObj, "map is null");
56 auto setObj = invoke_Map_entrySet(env, mapObj);
57 auto iterObj = invoke_Set_iterator(env, setObj);
59 std::map< std::string, std::string > ret;
61 while (invoke_Iterator_hasNext(env, iterObj))
63 JavaLocalObject entryObj { env, invoke_Iterator_next(env, iterObj) };
65 JavaLocalString keyObj { env,
66 static_cast< jstring >(invoke_MapEntry_getKey(env, entryObj)) };
68 JavaLocalString valueObj { env,
69 static_cast< jstring >(invoke_MapEntry_getValue(env, entryObj)) };
71 ret.emplace(toStdString(env, keyObj), toStdString(env, valueObj));
77 jobject newBundleInfoObj(JNIEnvWrapper *env, const std::unique_ptr< RCSBundleInfo > &bundleInfo)
79 LOGD("new bundle info");
80 __android_log_print(ANDROID_LOG_DEBUG, "CONTAINER", "newBundleInfoObj %s",bundleInfo->getActivatorName().c_str());
81 JavaLocalString id{env, newStringObject(env, bundleInfo->getID()) };
82 JavaLocalString path{env, newStringObject(env, bundleInfo->getPath()) };
83 JavaLocalString activatorName{env, newStringObject(env, bundleInfo->getActivatorName()) };
84 JavaLocalString libraryPath{env, newStringObject(env, bundleInfo->getLibraryPath()) };
85 JavaLocalString version{env, newStringObject(env, bundleInfo->getVersion()) };
87 return env->NewObject(g_cls_RCSBundleInfo, g_ctor_RCSBundleInfo,
88 id.get(), path.get(), activatorName.get(), libraryPath.get(), version.get());
92 void initRCSResourceContainer(JNIEnvWrapper *env)
94 g_cls_RCSBundleInfo = env->FindClassAsGlobalRef(CLS_NAME_BUNDLE_INFO);
96 g_ctor_RCSBundleInfo = env->GetConstructorID(g_cls_RCSBundleInfo, "("
97 AS_SIG(CLS_NAME_STRING)
98 AS_SIG(CLS_NAME_STRING)
99 AS_SIG(CLS_NAME_STRING)
100 AS_SIG(CLS_NAME_STRING)
101 AS_SIG(CLS_NAME_STRING)
104 auto clsJniBundleResource = env->FindClass(PACKAGE_NAME "/BundleResource");
106 g_field_mNativeHandle = env->GetFieldID(clsJniBundleResource, "mNativeHandle", "J");
109 void clearRCSResourceContainer(JNIEnvWrapper *env)
111 env->DeleteGlobalRef(g_cls_RCSBundleInfo);
114 JNIEXPORT void JNICALL
115 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartContainer
116 (JNIEnv *env, jobject, jstring configFileObj)
118 LOGD("nativeStartContainer");
120 // A strange error message happens if the container is used as native library on Android
121 // and further native libraries are loaded at runtime.
123 if ((error = dlerror()) != NULL)
125 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
126 "dlerror: %s.", error);
129 EXPECT(configFileObj, "ConfigFile is null.");
131 auto configFile = toStdString(env, configFileObj);
132 // std::string nativeFilePath = env->GetStringUTFChars(configFile, NULL);
135 RCSResourceContainer::getInstance()->startContainer(configFile);
138 JNIEXPORT void JNICALL
139 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopContainer(JNIEnv *env, jobject)
141 LOGD("nativeStopContainers");
143 // A strange error message happens if the container is used as native library on Android
144 // and further native libraries are loaded at runtime.
146 if ((error = dlerror()) != NULL)
148 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
149 "dlerror: %s.", error);
152 RCSResourceContainer::getInstance()->stopContainer();
155 JNIEXPORT void JNICALL
156 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddBundle
157 (JNIEnv *env, jobject, jstring idObj, jstring uriObj, jstring pathObj, jstring activatorObj,
160 LOGD("nativeAddBundle");
162 // A strange error message happens if the container is used as native library on Android
163 // and further native libraries are loaded at runtime.
165 if ((error = dlerror()) != NULL)
167 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
168 "dlerror: %s.", error);
171 EXPECT(idObj, "BundleId is null.");
172 EXPECT(pathObj, "BundlePath is null.");
173 EXPECT(activatorObj, "Activator is null.");
175 JNIEnvWrapper envWrapper(env);
179 LOGD("nativeAddBundle before calling native");
180 RCSResourceContainer::getInstance()->addBundle(toStdString(&envWrapper, idObj),
181 toStdString(&envWrapper, uriObj), toStdString(&envWrapper, pathObj),
182 toStdString(&envWrapper, activatorObj),
183 convertJavaMapToParamsMap(&envWrapper, paramsObj));
185 LOGD("nativeAddBundle after calling native");
187 catch (const JavaException &)
189 LOGE("Failed to add bundle.");
193 JNIEXPORT void JNICALL
194 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveBundle
195 (JNIEnv *env, jobject, jstring idObj)
197 LOGD("nativeRemoveBundle");
199 // A strange error message happens if the container is used as native library on Android
200 // and further native libraries are loaded at runtime.
202 if ((error = dlerror()) != NULL)
204 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
205 "dlerror: %s.", error);
208 EXPECT(idObj, "BundleId is null.");
210 auto id = toStdString(env, idObj);
213 RCSResourceContainer::getInstance()->removeBundle(id);
217 JNIEXPORT jobject JNICALL
218 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundles
219 (JNIEnv *env, jobject)
221 LOGD("nativeListBundles");
223 // A strange error message happens if the container is used as native library on Android
224 // and further native libraries are loaded at runtime.
226 if ((error = dlerror()) != NULL)
228 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
229 "dlerror: %s.", error);
232 JNIEnvWrapper envWrapper(env);
236 auto listObj = newArrayList(&envWrapper);
238 for (const auto& bundleInfo : RCSResourceContainer::getInstance()->listBundles())
240 JavaLocalObject bundleInfoObj{ &envWrapper, newBundleInfoObj(&envWrapper, bundleInfo) };
241 invoke_Collection_add(&envWrapper, listObj, bundleInfoObj);
245 catch (const JavaException &)
247 LOGE("Failed to convert bundle info list.");
252 JNIEXPORT void JNICALL
253 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartBundle
254 (JNIEnv *env, jobject, jstring idObj)
256 LOGD("nativeStartBundle");
258 // A strange error message happens if the container is used as native library on Android
259 // and further native libraries are loaded at runtime.
261 if ((error = dlerror()) != NULL)
263 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
264 "dlerror: %s.", error);
267 EXPECT(idObj, "BundleId is null.");
269 auto id = env->GetStringUTFChars(idObj, NULL);
272 RCSResourceContainer::getInstance()->startBundle(id);
276 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopBundle
277 (JNIEnv *env, jobject, jstring idObj)
279 LOGD("nativeStopBundle");
281 // A strange error message happens if the container is used as native library on Android
282 // and further native libraries are loaded at runtime.
284 if ((error = dlerror()) != NULL)
286 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
287 "dlerror: %s.", error);
290 EXPECT(idObj, "BundleId is null.");
292 auto id = env->GetStringUTFChars(idObj, NULL);
295 RCSResourceContainer::getInstance()->stopBundle(id);
298 JNIEXPORT void JNICALL
299 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddResourceConfig
300 (JNIEnv *env, jobject, jstring idObj, jstring uriObj, jobject paramsObj)
302 LOGD("nativeAddResourceConfig");
304 EXPECT(idObj, "BundleId is null.");
305 EXPECT(uriObj, "BundleUri is null.");
306 EXPECT(paramsObj, "Params is null.");
308 JNIEnvWrapper envWrapper(env);
312 RCSResourceContainer::getInstance()->addResourceConfig(toStdString(&envWrapper, idObj),
313 toStdString(&envWrapper, uriObj), convertJavaMapToParamsMap(&envWrapper, paramsObj));
315 catch (const JavaException &)
317 LOGE("Failed to add bundle.");
321 JNIEXPORT void JNICALL
322 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveResourceConfig
323 (JNIEnv *env, jobject, jstring idObj, jstring uriObj)
325 LOGD("nativeRemoveResourceConfig");
327 EXPECT(idObj, "BundleId is null.");
328 EXPECT(uriObj, "BundleUri is null.");
330 auto id = toStdString(env, idObj);
332 auto uri = toStdString(env, uriObj);
335 RCSResourceContainer::getInstance()->removeResourceConfig(id, uri);
338 JNIEXPORT jobject JNICALL
339 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundleResources
340 (JNIEnv *env, jobject, jstring idObj)
342 LOGD("nativeListBundleResources");
344 EXPECT_RET_DEF(idObj, "BundleId is null.");
346 JNIEnvWrapper envWrapper(env);
350 auto id = toStdString(&envWrapper, idObj);
352 auto listObj = newArrayList(&envWrapper);
354 for (const auto& s : RCSResourceContainer::getInstance()->listBundleResources(id))
356 JavaLocalString strObj{ &envWrapper, newStringObject(&envWrapper, s) };
358 invoke_Collection_add(&envWrapper, listObj, strObj);
363 catch (const JavaException &)
365 LOGE("Failed to convert bundle info list.");
372 JNIEXPORT void JNICALL
373 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRegisterBundleResource
374 (JNIEnv *env, jobject obj, jobject bundleResource, jobjectArray attributes, jstring bundleId,
375 jstring uri, jstring resourceType, jstring res_name)
377 JNIEnvWrapper envWrapper(env);
378 LOGD("nativeRegisterJniBundleResource");
379 auto str_bundle_id = toStdString(&envWrapper, bundleId);
380 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer", "retrieved bundle id: %s.",
381 str_bundle_id.c_str());
382 auto str_uri = toStdString(&envWrapper, uri);
383 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer", "retrieved uri: %s.",
385 auto str_resourceType = toStdString(&envWrapper, resourceType);
386 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer", "retrieved resource type: %s.",
387 str_resourceType.c_str());
388 auto str_res_name = toStdString(&envWrapper, res_name);
389 LOGD("retrieved res name.");
390 JniBundleResource res;
392 BundleResource::Ptr androidResource = std::make_shared< JniBundleResource >
393 (env, obj, bundleResource, str_bundle_id, attributes);
394 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
396 androidResource->m_uri = str_uri;
397 androidResource->m_resourceType = str_resourceType;
398 androidResource->m_name = str_res_name;
399 androidResource->m_bundleId = str_bundle_id;
401 // link java resource instance to c++ resource instance
402 env->SetLongField(bundleResource, g_field_mNativeHandle, reinterpret_cast< jlong >(androidResource.get()));
404 container->registerResource(androidResource);
406 android_resources[str_uri] = androidResource;
410 * Class: org_iotivity_resourcecontainer_bundle_api_BaseActivator
411 * Method: unregisterJavaResource
412 * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;)V
414 JNIEXPORT void JNICALL
415 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeUnregisterBundleResource
416 (JNIEnv *env, jobject obj, jobject bundleResource, jstring uri)
419 (void)bundleResource;
420 const char *str_uri = env->GetStringUTFChars(uri, 0);
422 if (android_resources[str_uri] != NULL)
424 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
425 container->unregisterResource(android_resources[str_uri]);
426 android_resources.erase(str_uri);
431 * Class: org_iotivity_resourcecontainer_bundle_api_BaseActivator
432 * Method: getNumberOfConfiguredResources
433 * Signature: (Ljava/lang/String;)I
435 JNIEXPORT jint JNICALL
436 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetNumberOfConfiguredResources(
437 JNIEnv *env, jobject obj, jstring bundleId)
440 LOGD("nativeGetNumberOfConfiguredResources");
441 const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
442 LOGD("retrieved bundle id");
443 __android_log_print(ANDROID_LOG_DEBUG, "CONTAINER", "getNumberOfConfiguredResources %s",str_bundleId);
444 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
445 vector< resourceInfo > resourceConfig;
446 container->getResourceConfiguration(str_bundleId, &resourceConfig);
448 return resourceConfig.size();
452 * Class: org_iotivity_resourcecontainer_bundle_api_BaseActivator
453 * Method: getConfiguredResourceParams
454 * Signature: (Ljava/lang/String;I)[Ljava/lang/String;
456 JNIEXPORT jobjectArray JNICALL
457 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetConfiguredResourceParams(
458 JNIEnv *env, jobject obj, jstring bundleId, jint resourceId)
462 const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
464 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
465 vector< resourceInfo > resourceConfig;
466 container->getResourceConfiguration(str_bundleId, &resourceConfig);
467 resourceInfo conf = resourceConfig[resourceId];
468 ret = (jobjectArray) env->NewObjectArray(4, env->FindClass("java/lang/String"),
469 env->NewStringUTF(""));
471 env->SetObjectArrayElement(ret, 0, env->NewStringUTF(conf.name.c_str()));
472 env->SetObjectArrayElement(ret, 1, env->NewStringUTF(conf.uri.c_str()));
473 env->SetObjectArrayElement(ret, 2, env->NewStringUTF(conf.resourceType.c_str()));
474 env->SetObjectArrayElement(ret, 3, env->NewStringUTF(conf.address.c_str()));