Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / service / resource-container / android / resource-container / src / main / jni / JniRcsResourceContainer.cpp
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 #include "JniRcsResourceContainer.h"
22
23 #include "JavaClasses.h"
24 #include "JavaLocalRef.h"
25 #include "JNIEnvWrapper.h"
26 #include "Log.h"
27 #include "Verify.h"
28 #include <dlfcn.h>
29
30 #include "ResourceContainerBundleAPI.h"
31 #include "JniBundleResource.h"
32 #include "RCSResourceContainer.h"
33
34
35
36 #define LOG_TAG "JNI-RCSResourceContainer"
37
38 using namespace OIC::Service;
39
40 #define CLS_NAME_BUNDLE_INFO "org/iotivity/service/resourcecontainer/RcsBundleInfo"
41
42 std::map< string, BundleResource::Ptr > android_resources;
43
44 namespace
45 {
46     jclass g_cls_RCSBundleInfo;
47     jfieldID g_field_mNativeHandle;
48
49     jmethodID g_ctor_RCSBundleInfo;
50
51     std::map< std::string, std::string > convertJavaMapToParamsMap(JNIEnvWrapper *env,
52             jobject mapObj)
53     {
54         EXPECT_RET_DEF(mapObj, "map is null");
55
56         auto setObj = invoke_Map_entrySet(env, mapObj);
57         auto iterObj = invoke_Set_iterator(env, setObj);
58
59         std::map< std::string, std::string > ret;
60
61         while (invoke_Iterator_hasNext(env, iterObj))
62         {
63             JavaLocalObject entryObj { env, invoke_Iterator_next(env, iterObj) };
64
65             JavaLocalString keyObj { env,
66                 static_cast< jstring >(invoke_MapEntry_getKey(env, entryObj)) };
67
68             JavaLocalString valueObj { env,
69                 static_cast< jstring >(invoke_MapEntry_getValue(env, entryObj)) };
70
71             ret.emplace(toStdString(env, keyObj), toStdString(env, valueObj));
72         }
73
74         return ret;
75     }
76
77     jobject newBundleInfoObj(JNIEnvWrapper *env, const std::unique_ptr< RCSBundleInfo > &bundleInfo)
78     {
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()) };
86
87         return env->NewObject(g_cls_RCSBundleInfo, g_ctor_RCSBundleInfo,
88                 id.get(), path.get(), activatorName.get(), libraryPath.get(), version.get(),
89                 bundleInfo->isActivated());
90     }
91 }
92
93 void initRCSResourceContainer(JNIEnvWrapper *env)
94 {
95     g_cls_RCSBundleInfo = env->FindClassAsGlobalRef(CLS_NAME_BUNDLE_INFO);
96
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)
103             ")V");
104
105     auto clsJniBundleResource = env->FindClass(PACKAGE_NAME "/BundleResource");
106
107     g_field_mNativeHandle = env->GetFieldID(clsJniBundleResource, "mNativeHandle", "J");
108 }
109
110 void clearRCSResourceContainer(JNIEnvWrapper *env)
111 {
112     env->DeleteGlobalRef(g_cls_RCSBundleInfo);
113 }
114
115 JNIEXPORT void JNICALL
116 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartContainer
117 (JNIEnv *env, jobject, jstring configFileObj)
118 {
119     LOGD("nativeStartContainer");
120
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.
123     const char *error;
124     if ((error = dlerror()) != NULL)
125     {
126         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
127                 "dlerror: %s.", error);
128     }
129
130     EXPECT(configFileObj, "ConfigFile is null.");
131
132     auto configFile = toStdString(env, configFileObj);
133     //  std::string nativeFilePath = env->GetStringUTFChars(configFile, NULL);
134     VERIFY_NO_EXC(env);
135
136     RCSResourceContainer::getInstance()->startContainer(configFile);
137 }
138
139 JNIEXPORT void JNICALL
140 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopContainer(JNIEnv *env, jobject)
141 {
142     LOGD("nativeStopContainers");
143
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.
146     const char *error;
147     if ((error = dlerror()) != NULL)
148     {
149         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
150                 "dlerror: %s.", error);
151     }
152
153     RCSResourceContainer::getInstance()->stopContainer();
154 }
155
156 JNIEXPORT void JNICALL
157 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddBundle
158 (JNIEnv *env, jobject, jstring idObj, jstring uriObj, jstring pathObj, jstring activatorObj,
159  jobject paramsObj)
160 {
161     LOGD("nativeAddBundle");
162
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.
165     const char *error;
166     if ((error = dlerror()) != NULL)
167     {
168         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
169                 "dlerror: %s.", error);
170     }
171
172     EXPECT(idObj, "BundleId is null.");
173     EXPECT(pathObj, "BundlePath is null.");
174     EXPECT(activatorObj, "Activator is null.");
175
176     JNIEnvWrapper envWrapper(env);
177
178     try
179     {
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));
185
186         LOGD("nativeAddBundle after calling native");
187     }
188     catch (const JavaException &)
189     {
190         LOGE("Failed to add bundle.");
191     }
192 }
193
194 JNIEXPORT void JNICALL
195 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveBundle
196 (JNIEnv *env, jobject, jstring idObj)
197 {
198     LOGD("nativeRemoveBundle");
199
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.
202     const char *error;
203     if ((error = dlerror()) != NULL)
204     {
205         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
206                 "dlerror: %s.", error);
207     }
208
209     EXPECT(idObj, "BundleId is null.");
210
211     auto id = toStdString(env, idObj);
212     VERIFY_NO_EXC(env);
213
214     RCSResourceContainer::getInstance()->removeBundle(id);
215 }
216
217
218 JNIEXPORT jobject JNICALL
219 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundles
220 (JNIEnv *env, jobject)
221 {
222     LOGD("nativeListBundles");
223
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.
226     const char *error;
227     if ((error = dlerror()) != NULL)
228     {
229         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
230                 "dlerror: %s.", error);
231     }
232
233     JNIEnvWrapper envWrapper(env);
234
235     try
236     {
237         auto listObj = newArrayList(&envWrapper);
238
239         for (const auto& bundleInfo : RCSResourceContainer::getInstance()->listBundles())
240         {
241             JavaLocalObject bundleInfoObj{ &envWrapper, newBundleInfoObj(&envWrapper, bundleInfo) };
242             invoke_Collection_add(&envWrapper, listObj, bundleInfoObj);
243         }
244         return listObj;
245     }
246     catch (const JavaException &)
247     {
248         LOGE("Failed to convert bundle info list.");
249     }
250     return nullptr;
251 }
252
253 JNIEXPORT void JNICALL
254 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartBundle
255 (JNIEnv *env, jobject, jstring idObj)
256 {
257     LOGD("nativeStartBundle");
258
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.
261     const char *error;
262     if ((error = dlerror()) != NULL)
263     {
264         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
265                 "dlerror: %s.", error);
266     }
267
268     EXPECT(idObj, "BundleId is null.");
269
270     auto id = env->GetStringUTFChars(idObj, NULL);
271     VERIFY_NO_EXC(env);
272
273     RCSResourceContainer::getInstance()->startBundle(id);
274 }
275 JNICALL
276 JNIEXPORT void
277 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStopBundle
278 (JNIEnv *env, jobject, jstring idObj)
279 {
280     LOGD("nativeStopBundle");
281
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.
284     const char *error;
285     if ((error = dlerror()) != NULL)
286     {
287         __android_log_print(ANDROID_LOG_DEBUG, "JNI-RCSResourceContainer",
288                 "dlerror: %s.", error);
289     }
290
291     EXPECT(idObj, "BundleId is null.");
292
293     auto id = env->GetStringUTFChars(idObj, NULL);
294     VERIFY_NO_EXC(env);
295
296     RCSResourceContainer::getInstance()->stopBundle(id);
297 }
298
299 JNIEXPORT void JNICALL
300 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeAddResourceConfig
301 (JNIEnv *env, jobject, jstring idObj, jstring uriObj, jobject paramsObj)
302 {
303     LOGD("nativeAddResourceConfig");
304
305     EXPECT(idObj, "BundleId is null.");
306     EXPECT(uriObj, "BundleUri is null.");
307     EXPECT(paramsObj, "Params is null.");
308
309     JNIEnvWrapper envWrapper(env);
310
311     try
312     {
313         RCSResourceContainer::getInstance()->addResourceConfig(toStdString(&envWrapper, idObj),
314                 toStdString(&envWrapper, uriObj), convertJavaMapToParamsMap(&envWrapper, paramsObj));
315     }
316     catch (const JavaException &)
317     {
318         LOGE("Failed to add bundle.");
319     }
320 }
321
322 JNIEXPORT void JNICALL
323 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRemoveResourceConfig
324 (JNIEnv *env, jobject, jstring idObj, jstring uriObj)
325 {
326     LOGD("nativeRemoveResourceConfig");
327
328     EXPECT(idObj, "BundleId is null.");
329     EXPECT(uriObj, "BundleUri is null.");
330
331     auto id = toStdString(env, idObj);
332     VERIFY_NO_EXC(env);
333     auto uri = toStdString(env, uriObj);
334     VERIFY_NO_EXC(env);
335
336     RCSResourceContainer::getInstance()->removeResourceConfig(id, uri);
337 }
338
339 JNIEXPORT jobject JNICALL
340 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundleResources
341 (JNIEnv *env, jobject, jstring idObj)
342 {
343     LOGD("nativeListBundleResources");
344
345     EXPECT_RET_DEF(idObj, "BundleId is null.");
346
347     JNIEnvWrapper envWrapper(env);
348
349     try
350     {
351         auto id = toStdString(&envWrapper, idObj);
352
353         auto listObj = newArrayList(&envWrapper);
354
355         for (const auto& s : RCSResourceContainer::getInstance()->listBundleResources(id))
356         {
357             JavaLocalString strObj{ &envWrapper, newStringObject(&envWrapper, s) };
358
359             invoke_Collection_add(&envWrapper, listObj, strObj);
360         }
361
362         return listObj;
363     }
364     catch (const JavaException &)
365     {
366         LOGE("Failed to convert bundle info list.");
367     }
368
369     return nullptr;
370 }
371
372
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)
377 {
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.",
385             str_uri.c_str());
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;
392
393     BundleResource::Ptr androidResource = std::make_shared< JniBundleResource >
394             (env, obj, bundleResource, str_bundle_id, attributes);
395     ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
396
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;
401
402     // link java resource instance to c++ resource instance
403     env->SetLongField(bundleResource, g_field_mNativeHandle, reinterpret_cast< jlong >(androidResource.get()));
404
405     container->registerResource(androidResource);
406
407     android_resources[str_uri] = androidResource;
408 }
409
410 /*
411  * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
412  * Method:    unregisterJavaResource
413  * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;)V
414  */
415 JNIEXPORT void JNICALL
416 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeUnregisterBundleResource
417 (JNIEnv *env, jobject obj, jobject bundleResource, jstring uri)
418 {
419     (void)obj;
420     (void)bundleResource;
421     const char *str_uri = env->GetStringUTFChars(uri, 0);
422
423     if (android_resources[str_uri] != NULL)
424     {
425         ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
426         container->unregisterResource(android_resources[str_uri]);
427         android_resources.erase(str_uri);
428     }
429 }
430
431 /*
432  * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
433  * Method:    getNumberOfConfiguredResources
434  * Signature: (Ljava/lang/String;)I
435  */
436 JNIEXPORT jint JNICALL
437 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetNumberOfConfiguredResources(
438     JNIEnv *env, jobject obj, jstring bundleId)
439 {
440     (void)obj;
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);
448
449     return resourceConfig.size();
450 }
451
452 /*
453  * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
454  * Method:    getConfiguredResourceParams
455  * Signature: (Ljava/lang/String;I)[Ljava/lang/String;
456  */
457 JNIEXPORT jobjectArray JNICALL
458 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetConfiguredResourceParams(
459     JNIEnv *env, jobject obj, jstring bundleId, jint resourceId)
460 {
461     (void)obj;
462     jobjectArray ret;
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);
467
468         ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
469         vector< resourceInfo > resourceConfig;
470         container->getResourceConfiguration(str_bundleId, &resourceConfig);
471
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()));
478         }
479     }
480     return ret;
481 }
482