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(),
89 bundleInfo->isActivated());
93 void initRCSResourceContainer(JNIEnvWrapper *env)
95 g_cls_RCSBundleInfo = env->FindClassAsGlobalRef(CLS_NAME_BUNDLE_INFO);
97 g_ctor_RCSBundleInfo = env->GetConstructorID(g_cls_RCSBundleInfo, "("
98 AS_SIG(CLS_NAME_STRING)
99 AS_SIG(CLS_NAME_STRING)
100 AS_SIG(CLS_NAME_STRING)
101 AS_SIG(CLS_NAME_STRING)
102 AS_SIG(CLS_NAME_STRING)
105 auto clsJniBundleResource = env->FindClass(PACKAGE_NAME "/BundleResource");
107 g_field_mNativeHandle = env->GetFieldID(clsJniBundleResource, "mNativeHandle", "J");
110 void clearRCSResourceContainer(JNIEnvWrapper *env)
112 env->DeleteGlobalRef(g_cls_RCSBundleInfo);
115 JNIEXPORT void JNICALL
116 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartContainer
117 (JNIEnv *env, jobject, jstring configFileObj)
119 LOGD("nativeStartContainer");
121 // A strange error message happens if the container is used as native library on Android
122 // and further native libraries are loaded at runtime.
124 if ((error = dlerror()) != NULL)
126 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
127 "dlerror: %s.", error);
130 EXPECT(configFileObj, "ConfigFile is null.");
132 auto configFile = toStdString(env, configFileObj);
133 // std::string nativeFilePath = env->GetStringUTFChars(configFile, NULL);
136 RCSResourceContainer::getInstance()->startContainer(configFile);
139 JNIEXPORT void JNICALL
140 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopContainer(JNIEnv *env, jobject)
142 LOGD("nativeStopContainers");
144 // A strange error message happens if the container is used as native library on Android
145 // and further native libraries are loaded at runtime.
147 if ((error = dlerror()) != NULL)
149 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
150 "dlerror: %s.", error);
153 RCSResourceContainer::getInstance()->stopContainer();
156 JNIEXPORT void JNICALL
157 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddBundle
158 (JNIEnv *env, jobject, jstring idObj, jstring uriObj, jstring pathObj, jstring activatorObj,
161 LOGD("nativeAddBundle");
163 // A strange error message happens if the container is used as native library on Android
164 // and further native libraries are loaded at runtime.
166 if ((error = dlerror()) != NULL)
168 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
169 "dlerror: %s.", error);
172 EXPECT(idObj, "BundleId is null.");
173 EXPECT(pathObj, "BundlePath is null.");
174 EXPECT(activatorObj, "Activator is null.");
176 JNIEnvWrapper envWrapper(env);
180 LOGD("nativeAddBundle before calling native");
181 RCSResourceContainer::getInstance()->addBundle(toStdString(&envWrapper, idObj),
182 toStdString(&envWrapper, uriObj), toStdString(&envWrapper, pathObj),
183 toStdString(&envWrapper, activatorObj),
184 convertJavaMapToParamsMap(&envWrapper, paramsObj));
186 LOGD("nativeAddBundle after calling native");
188 catch (const JavaException &)
190 LOGE("Failed to add bundle.");
194 JNIEXPORT void JNICALL
195 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveBundle
196 (JNIEnv *env, jobject, jstring idObj)
198 LOGD("nativeRemoveBundle");
200 // A strange error message happens if the container is used as native library on Android
201 // and further native libraries are loaded at runtime.
203 if ((error = dlerror()) != NULL)
205 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
206 "dlerror: %s.", error);
209 EXPECT(idObj, "BundleId is null.");
211 auto id = toStdString(env, idObj);
214 RCSResourceContainer::getInstance()->removeBundle(id);
218 JNIEXPORT jobject JNICALL
219 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundles
220 (JNIEnv *env, jobject)
222 LOGD("nativeListBundles");
224 // A strange error message happens if the container is used as native library on Android
225 // and further native libraries are loaded at runtime.
227 if ((error = dlerror()) != NULL)
229 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
230 "dlerror: %s.", error);
233 JNIEnvWrapper envWrapper(env);
237 auto listObj = newArrayList(&envWrapper);
239 for (const auto& bundleInfo : RCSResourceContainer::getInstance()->listBundles())
241 JavaLocalObject bundleInfoObj{ &envWrapper, newBundleInfoObj(&envWrapper, bundleInfo) };
242 invoke_Collection_add(&envWrapper, listObj, bundleInfoObj);
246 catch (const JavaException &)
248 LOGE("Failed to convert bundle info list.");
253 JNIEXPORT void JNICALL
254 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartBundle
255 (JNIEnv *env, jobject, jstring idObj)
257 LOGD("nativeStartBundle");
259 // A strange error message happens if the container is used as native library on Android
260 // and further native libraries are loaded at runtime.
262 if ((error = dlerror()) != NULL)
264 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
265 "dlerror: %s.", error);
268 EXPECT(idObj, "BundleId is null.");
270 auto id = env->GetStringUTFChars(idObj, NULL);
273 RCSResourceContainer::getInstance()->startBundle(id);
277 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopBundle
278 (JNIEnv *env, jobject, jstring idObj)
280 LOGD("nativeStopBundle");
282 // A strange error message happens if the container is used as native library on Android
283 // and further native libraries are loaded at runtime.
285 if ((error = dlerror()) != NULL)
287 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
288 "dlerror: %s.", error);
291 EXPECT(idObj, "BundleId is null.");
293 auto id = env->GetStringUTFChars(idObj, NULL);
296 RCSResourceContainer::getInstance()->stopBundle(id);
299 JNIEXPORT void JNICALL
300 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddResourceConfig
301 (JNIEnv *env, jobject, jstring idObj, jstring uriObj, jobject paramsObj)
303 LOGD("nativeAddResourceConfig");
305 EXPECT(idObj, "BundleId is null.");
306 EXPECT(uriObj, "BundleUri is null.");
307 EXPECT(paramsObj, "Params is null.");
309 JNIEnvWrapper envWrapper(env);
313 RCSResourceContainer::getInstance()->addResourceConfig(toStdString(&envWrapper, idObj),
314 toStdString(&envWrapper, uriObj), convertJavaMapToParamsMap(&envWrapper, paramsObj));
316 catch (const JavaException &)
318 LOGE("Failed to add bundle.");
322 JNIEXPORT void JNICALL
323 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveResourceConfig
324 (JNIEnv *env, jobject, jstring idObj, jstring uriObj)
326 LOGD("nativeRemoveResourceConfig");
328 EXPECT(idObj, "BundleId is null.");
329 EXPECT(uriObj, "BundleUri is null.");
331 auto id = toStdString(env, idObj);
333 auto uri = toStdString(env, uriObj);
336 RCSResourceContainer::getInstance()->removeResourceConfig(id, uri);
339 JNIEXPORT jobject JNICALL
340 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundleResources
341 (JNIEnv *env, jobject, jstring idObj)
343 LOGD("nativeListBundleResources");
345 EXPECT_RET_DEF(idObj, "BundleId is null.");
347 JNIEnvWrapper envWrapper(env);
351 auto id = toStdString(&envWrapper, idObj);
353 auto listObj = newArrayList(&envWrapper);
355 for (const auto& s : RCSResourceContainer::getInstance()->listBundleResources(id))
357 JavaLocalString strObj{ &envWrapper, newStringObject(&envWrapper, s) };
359 invoke_Collection_add(&envWrapper, listObj, strObj);
364 catch (const JavaException &)
366 LOGE("Failed to convert bundle info list.");
373 JNIEXPORT void JNICALL
374 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRegisterBundleResource
375 (JNIEnv *env, jobject obj, jobject bundleResource, jobjectArray attributes, jstring bundleId,
376 jstring uri, jstring resourceType, jstring res_name)
378 JNIEnvWrapper envWrapper(env);
379 LOGD("nativeRegisterJniBundleResource");
380 auto str_bundle_id = toStdString(&envWrapper, bundleId);
381 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer", "retrieved bundle id: %s.",
382 str_bundle_id.c_str());
383 auto str_uri = toStdString(&envWrapper, uri);
384 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer", "retrieved uri: %s.",
386 auto str_resourceType = toStdString(&envWrapper, resourceType);
387 __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer", "retrieved resource type: %s.",
388 str_resourceType.c_str());
389 auto str_res_name = toStdString(&envWrapper, res_name);
390 LOGD("retrieved res name.");
391 JniBundleResource res;
393 BundleResource::Ptr androidResource = std::make_shared< JniBundleResource >
394 (env, obj, bundleResource, str_bundle_id, attributes);
395 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
397 androidResource->m_uri = str_uri;
398 androidResource->m_resourceType = str_resourceType;
399 androidResource->m_name = str_res_name;
400 androidResource->m_bundleId = str_bundle_id;
402 // link java resource instance to c++ resource instance
403 env->SetLongField(bundleResource, g_field_mNativeHandle, reinterpret_cast< jlong >(androidResource.get()));
405 container->registerResource(androidResource);
407 android_resources[str_uri] = androidResource;
411 * Class: org_iotivity_resourcecontainer_bundle_api_BaseActivator
412 * Method: unregisterJavaResource
413 * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;)V
415 JNIEXPORT void JNICALL
416 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeUnregisterBundleResource
417 (JNIEnv *env, jobject obj, jobject bundleResource, jstring uri)
420 (void)bundleResource;
421 const char *str_uri = env->GetStringUTFChars(uri, 0);
423 if (android_resources[str_uri] != NULL)
425 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
426 container->unregisterResource(android_resources[str_uri]);
427 android_resources.erase(str_uri);
432 * Class: org_iotivity_resourcecontainer_bundle_api_BaseActivator
433 * Method: getNumberOfConfiguredResources
434 * Signature: (Ljava/lang/String;)I
436 JNIEXPORT jint JNICALL
437 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetNumberOfConfiguredResources(
438 JNIEnv *env, jobject obj, jstring bundleId)
441 LOGD("nativeGetNumberOfConfiguredResources");
442 const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
443 LOGD("retrieved bundle id");
444 __android_log_print(ANDROID_LOG_DEBUG, "CONTAINER", "getNumberOfConfiguredResources %s",str_bundleId);
445 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
446 vector< resourceInfo > resourceConfig;
447 container->getResourceConfiguration(str_bundleId, &resourceConfig);
449 return resourceConfig.size();
453 * Class: org_iotivity_resourcecontainer_bundle_api_BaseActivator
454 * Method: getConfiguredResourceParams
455 * Signature: (Ljava/lang/String;I)[Ljava/lang/String;
457 JNIEXPORT jobjectArray JNICALL
458 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetConfiguredResourceParams(
459 JNIEnv *env, jobject obj, jstring bundleId, jint resourceId)
463 ret = (jobjectArray) env->NewObjectArray(4, env->FindClass("java/lang/String"),
464 env->NewStringUTF(""));
465 if(bundleId != NULL){
466 const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
468 ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
469 vector< resourceInfo > resourceConfig;
470 container->getResourceConfiguration(str_bundleId, &resourceConfig);
472 if(resourceConfig.size() > resourceId && resourceId >=0){
473 resourceInfo conf = resourceConfig[resourceId];
474 env->SetObjectArrayElement(ret, 0, env->NewStringUTF(conf.name.c_str()));
475 env->SetObjectArrayElement(ret, 1, env->NewStringUTF(conf.uri.c_str()));
476 env->SetObjectArrayElement(ret, 2, env->NewStringUTF(conf.resourceType.c_str()));
477 env->SetObjectArrayElement(ret, 3, env->NewStringUTF(conf.address.c_str()));