Merge branch 'security-summit' into 'master'
[platform/upstream/iotivity.git] / service / resource-encapsulation / android / service / src / main / jni / JniRcsRemoteResourceObject.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 "JniRcsRemoteResourceObject.h"
22
23 #include "JniRcsObject.h"
24 #include "JniRcsResourceAttributes.h"
25 #include "JavaClasses.h"
26 #include "JavaExceptions.h"
27 #include "JavaGlobalRef.h"
28 #include "Log.h"
29 #include "ScopedEnv.h"
30 #include "Verify.h"
31
32 #include "RCSRemoteResourceObject.h"
33
34 using namespace OIC::Service;
35
36 #define LOG_TAG "JNI-RCSRemoteResourceObject"
37
38 #define CLS_NAME_RESOURCE_STATE CLS_NAME_REMOTERESOURCEOBJECT "$ResourceState"
39 #define CLS_NAME_CACHE_STATE CLS_NAME_REMOTERESOURCEOBJECT "$CacheState"
40
41 #define CLS_NAME_ON_STATE_CHANGED_LISTENER CLS_NAME_REMOTERESOURCEOBJECT "$OnStateChangedListener"
42 #define CLS_NAME_ON_CACHE_UPDATED_LISTENER CLS_NAME_REMOTERESOURCEOBJECT "$OnCacheUpdatedListener"
43 #define CLS_NAME_ON_REMOTE_ATTRIBUTES_RECEIVED_LISTENER \
44     CLS_NAME_REMOTERESOURCEOBJECT "$OnRemoteAttributesReceivedListener"
45
46 namespace
47 {
48     jclass g_cls_RCSRemoteResourceObject;
49     jclass g_cls_ResourceState;
50
51     jmethodID g_ctor_RCSRemoteResourceObject;
52
53     jmethodID g_method_onStateChanged;
54     jmethodID g_method_onCacheUpdated;
55     jmethodID g_method_onAttributesReceived;
56
57     jobject g_obj_ResourceState_None;
58     jobject g_obj_ResourceState_Requested;
59     jobject g_obj_ResourceState_Alive;
60     jobject g_obj_ResourceState_LostSignal;
61     jobject g_obj_ResourceState_Destoryed;
62
63     jobject g_obj_CacheState_None;
64     jobject g_obj_CacheState_Unready;
65     jobject g_obj_CacheState_Ready;
66     jobject g_obj_CacheState_LostSignal;
67
68
69     inline jobjectArray toJavaStringArray(JNIEnv* env, const std::vector< std::string >& vec)
70     {
71         jobjectArray arrayObj = env->NewObjectArray(vec.size(), g_cls_String, nullptr);
72         if (!arrayObj) return nullptr;
73         for (size_t i = 0; i < vec.size(); ++i)
74         {
75             jstring strObj = env->NewStringUTF(vec[i].c_str());
76             VERIFY_NO_EXC_RET_DEF(env);
77
78             env->SetObjectArrayElement(arrayObj, i, strObj);
79             VERIFY_NO_EXC_RET_DEF(env);
80
81             env->DeleteLocalRef(strObj);
82         }
83         return arrayObj;
84     }
85
86     template < typename ENV >
87     inline jobject convertResourceState(ENV* env, ResourceState state)
88     {
89         switch (state)
90         {
91             case ResourceState::NONE: return g_obj_ResourceState_None;
92             case ResourceState::REQUESTED: return g_obj_ResourceState_Requested;
93             case ResourceState::ALIVE: return g_obj_ResourceState_Alive;
94             case ResourceState::LOST_SIGNAL: return g_obj_ResourceState_LostSignal;
95             case ResourceState::DESTROYED: return g_obj_ResourceState_Destoryed;
96         }
97
98         throwRCSException(env, "Failed to convert ResourceState");
99         return { };
100     }
101
102     inline jobject convertCacheState(JNIEnv* env, CacheState state)
103     {
104         switch (state)
105         {
106             case CacheState::NONE: return g_obj_CacheState_None;
107             case CacheState::UNREADY: return g_obj_CacheState_Unready;
108             case CacheState::READY: return g_obj_CacheState_Ready;
109             case CacheState::LOST_SIGNAL: return g_obj_CacheState_LostSignal;
110         }
111
112         throwRCSException(env, "Failed to convert CacheState");
113         return { };
114     }
115
116     inline RCSRemoteResourceObject::Ptr& getResource(JNIEnv* env, jobject obj) noexcept
117     {
118         return getNativeHandleAs< RCSRemoteResourceObject::Ptr >(env, obj);
119     }
120
121     void onStateChanged(ResourceState newState, const JavaGlobalRef& listener)
122     {
123         ScopedEnvWrapper env;
124         EXPECT(env, "env is null!");
125
126         try
127         {
128             env->CallVoidMethod(listener, g_method_onStateChanged,
129                     convertResourceState(env.get(), newState));
130         }
131         catch (const JavaException&)
132         {
133             env->ExceptionDescribe();
134             env->ExceptionClear();
135         }
136     }
137
138     void onCacheUpdated(const RCSResourceAttributes& attrs, const JavaGlobalRef& listener)
139     {
140         LOGD("onCacheUpdated");
141
142         ScopedEnvWrapper env;
143         EXPECT(env, "env is null!");
144
145         try
146         {
147             env->CallVoidMethod(listener, g_method_onCacheUpdated,
148                     newAttributesObject(env.get(), attrs));
149         }
150         catch (const JavaException&)
151         {
152             env->ExceptionDescribe();
153             env->ExceptionClear();
154         }
155     }
156
157     void onRemoteAttributesReceived(const RCSResourceAttributes& attrs, int errorCode,
158             const JavaGlobalRef& listener)
159     {
160         ScopedEnvWrapper env;
161         EXPECT(env, "env is null!");
162
163         try
164         {
165             env->CallVoidMethod(listener, g_method_onAttributesReceived,
166                     newAttributesObject(env.get(), attrs), errorCode);
167         }
168         catch (const JavaException&)
169         {
170             env->ExceptionDescribe();
171             env->ExceptionClear();
172         }
173     }
174 }
175
176
177 void initRCSRemoteResourceObject(JNIEnvWrapper* env)
178 {
179     g_cls_RCSRemoteResourceObject = env->FindClassAsGlobalRef(CLS_NAME_REMOTERESOURCEOBJECT);
180
181     g_ctor_RCSRemoteResourceObject = env->GetConstructorID(g_cls_RCSRemoteResourceObject, "()V");
182
183     auto clsOnStateChangedListener = env->FindClass(CLS_NAME_ON_STATE_CHANGED_LISTENER);
184     g_method_onStateChanged = env->GetMethodID(clsOnStateChangedListener, "onStateChanged",
185             "(" AS_SIG(CLS_NAME_RESOURCE_STATE) ")V");
186
187     auto clsOnCacheUpdatedListener = env->FindClass(CLS_NAME_ON_CACHE_UPDATED_LISTENER);
188     g_method_onCacheUpdated = env->GetMethodID(clsOnCacheUpdatedListener, "onCacheUpdated",
189             "(" AS_SIG(CLS_NAME_RESOURCEATTRIBUTES) ")V");
190
191     auto clsOnRemoteAttributesReceivedListener =
192             env->FindClass(CLS_NAME_ON_REMOTE_ATTRIBUTES_RECEIVED_LISTENER);
193     g_method_onAttributesReceived = env->GetMethodID(clsOnRemoteAttributesReceivedListener,
194             "onAttributesReceived", "(" AS_SIG(CLS_NAME_RESOURCEATTRIBUTES) "I)V");
195
196     auto clsResourceState = env->FindClass(CLS_NAME_RESOURCE_STATE);
197
198     g_obj_ResourceState_None = env->NewGlobalRef(env->GetStaticObjectField(clsResourceState,
199             "NONE", AS_SIG(CLS_NAME_RESOURCE_STATE)));
200
201     g_obj_ResourceState_Requested = env->NewGlobalRef(env->GetStaticObjectField(clsResourceState,
202             "REQUESTED", AS_SIG(CLS_NAME_RESOURCE_STATE)));
203
204     g_obj_ResourceState_Alive = env->NewGlobalRef(env->GetStaticObjectField(clsResourceState,
205             "ALIVE", AS_SIG(CLS_NAME_RESOURCE_STATE)));
206
207     g_obj_ResourceState_LostSignal = env->NewGlobalRef(env->GetStaticObjectField(clsResourceState,
208             "LOST_SIGNAL", AS_SIG(CLS_NAME_RESOURCE_STATE)));
209
210     g_obj_ResourceState_Destoryed = env->NewGlobalRef(env->GetStaticObjectField(clsResourceState,
211             "DESTROYED", AS_SIG(CLS_NAME_RESOURCE_STATE)));
212
213     auto clsCacheState = env->FindClass(CLS_NAME_CACHE_STATE);
214
215     g_obj_CacheState_None = env->NewGlobalRef(env->GetStaticObjectField(clsCacheState,
216             "NONE", AS_SIG(CLS_NAME_CACHE_STATE)));
217
218     g_obj_CacheState_Unready = env->NewGlobalRef(env->GetStaticObjectField(clsCacheState,
219             "UNREADY", AS_SIG(CLS_NAME_CACHE_STATE)));
220
221     g_obj_CacheState_Ready = env->NewGlobalRef(env->GetStaticObjectField(clsCacheState,
222             "READY", AS_SIG(CLS_NAME_CACHE_STATE)));
223
224     g_obj_CacheState_LostSignal = env->NewGlobalRef(env->GetStaticObjectField(clsCacheState,
225             "LOST_SIGNAL", AS_SIG(CLS_NAME_CACHE_STATE)));
226
227
228 }
229
230 void clearRCSRemoteResourceObject(JNIEnvWrapper* env)
231 {
232     env->DeleteGlobalRef(g_cls_RCSRemoteResourceObject);
233     env->DeleteGlobalRef(g_cls_ResourceState);
234
235     env->DeleteGlobalRef(g_obj_ResourceState_None);
236     env->DeleteGlobalRef(g_obj_ResourceState_Requested);
237     env->DeleteGlobalRef(g_obj_ResourceState_Alive);
238     env->DeleteGlobalRef(g_obj_ResourceState_LostSignal);
239     env->DeleteGlobalRef(g_obj_ResourceState_Destoryed);
240
241     env->DeleteGlobalRef(g_obj_CacheState_None);
242     env->DeleteGlobalRef(g_obj_CacheState_Unready);
243     env->DeleteGlobalRef(g_obj_CacheState_Ready);
244     env->DeleteGlobalRef(g_obj_CacheState_LostSignal);
245 }
246
247 jobject newRemoteResourceObject(JNIEnvWrapper* env)
248 {
249     return env->NewObject(g_cls_RCSRemoteResourceObject, g_ctor_RCSRemoteResourceObject);
250 }
251
252 JNIEXPORT jboolean JNICALL
253 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeIsMonitoring
254 (JNIEnv* env, jobject obj)
255 {
256     LOGD("nativeIsMonitoring");
257     auto res = getResource(env, obj);
258     VERIFY_NO_EXC_RET_DEF(env);
259
260     return res->isMonitoring();
261 }
262
263 JNIEXPORT jboolean JNICALL
264 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeIsCaching
265 (JNIEnv* env, jobject obj)
266 {
267     LOGD("nativeIsCaching");
268     auto res = getResource(env, obj);
269     VERIFY_NO_EXC_RET_DEF(env);
270
271     return res->isCaching();
272 }
273
274 JNIEXPORT jboolean JNICALL
275 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeIsObservable
276 (JNIEnv* env, jobject obj)
277 {
278     LOGD("nativeIsObservable");
279     auto res = getResource(env, obj);
280     VERIFY_NO_EXC_RET_DEF(env);
281
282     return res->isObservable();
283 }
284
285 JNIEXPORT void JNICALL
286 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeStartMonitoring
287 (JNIEnv* env, jobject obj, jobject listener)
288 {
289     LOGD("nativeStartMonitoring");
290     EXPECT(listener, "listener is null.");
291
292     auto res = getResource(env, obj);
293     VERIFY_NO_EXC(env);
294
295     try
296     {
297         res->startMonitoring(
298                 std::bind(onStateChanged, std::placeholders::_1, JavaGlobalRef{ env, listener }));
299     }
300     catch (const BadRequestException& e)
301     {
302         env->ThrowNew(env->FindClass(EXC_NAME_ILLEGAL_STATE), e.what());
303     }
304 }
305
306 JNIEXPORT void JNICALL
307 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeStopMonitoring
308 (JNIEnv* env, jobject obj)
309 {
310     LOGD("nativeStopMonitoring");
311
312     auto res = getResource(env, obj);
313     VERIFY_NO_EXC(env);
314
315     res->stopMonitoring();
316 }
317
318 JNIEXPORT jobject JNICALL
319 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetState
320 (JNIEnv* env, jobject obj)
321 {
322     LOGD("nativeGetState");
323
324     auto res = getResource(env, obj);
325     VERIFY_NO_EXC_RET_DEF(env);
326
327     return convertResourceState(env, res->getState());
328 }
329
330 JNIEXPORT void JNICALL
331 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeStartCaching
332 (JNIEnv* env, jobject obj, jobject listener)
333 {
334     LOGD("nativeStartCaching");
335
336     auto res = getResource(env, obj);
337     VERIFY_NO_EXC(env);
338
339     try
340     {
341         if (listener)
342         {
343             res->startCaching(std::bind(onCacheUpdated,
344                     std::placeholders::_1, JavaGlobalRef{ env, listener }));
345         }
346         else
347         {
348             res->startCaching();
349         }
350     }
351     catch (const BadRequestException& e)
352     {
353         env->ThrowNew(env->FindClass(EXC_NAME_ILLEGAL_STATE), e.what());
354     }
355 }
356
357 JNIEXPORT void JNICALL
358 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeStopCaching
359 (JNIEnv* env, jobject obj)
360 {
361     LOGD("nativeStopCaching");
362
363     auto res = getResource(env, obj);
364     VERIFY_NO_EXC(env);
365
366     res->stopCaching();
367 }
368
369 JNIEXPORT jobject JNICALL
370 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetCacheState
371 (JNIEnv* env, jobject obj)
372 {
373     LOGD("nativeGetCacheState");
374
375     auto res = getResource(env, obj);
376     VERIFY_NO_EXC_RET_DEF(env);
377
378     return convertCacheState(env, res->getCacheState());
379 }
380
381 JNIEXPORT jboolean JNICALL
382 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeIsCachedAvailable
383 (JNIEnv* env, jobject obj)
384 {
385     LOGD("nativeIsCachedAvailable");
386
387     auto res = getResource(env, obj);
388     VERIFY_NO_EXC_RET_DEF(env);
389
390     try
391     {
392         return res->isCachedAvailable();
393     }
394     catch (const BadRequestException& e)
395     {
396         env->ThrowNew(env->FindClass(EXC_NAME_ILLEGAL_STATE), e.what());
397         return false;
398     }
399 }
400
401 JNIEXPORT jobject JNICALL
402 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetCachedAttributes
403 (JNIEnv* env, jobject obj)
404 {
405     LOGD("nativeGetCachedAttributes");
406
407     auto res = getResource(env, obj);
408     VERIFY_NO_EXC_RET_DEF(env);
409
410     try
411     {
412         auto attrs = res->getCachedAttributes();
413         VERIFY_NO_EXC_RET_DEF(env);
414
415         return newAttributesObject(env, attrs);
416     }
417     catch (const BadRequestException& e)
418     {
419         env->ThrowNew(env->FindClass(EXC_NAME_ILLEGAL_STATE), e.what());
420         return { };
421     }
422 }
423
424 JNIEXPORT void JNICALL
425 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetRemoteAttributes
426 (JNIEnv* env, jobject obj, jobject listener)
427 {
428     LOGD("nativeGetRemoteAttributes");
429     EXPECT(listener, "listener is null.");
430
431     auto res = getResource(env, obj);
432     VERIFY_NO_EXC(env);
433
434     try
435     {
436         res->getRemoteAttributes(std::bind(onRemoteAttributesReceived,
437                 std::placeholders::_1, std::placeholders::_2, JavaGlobalRef{ env, listener }));
438     }
439     catch (const PlatformException& e) {
440         throwPlatformException(env, e);
441     }
442 }
443
444 JNIEXPORT void JNICALL
445 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeSetRemoteAttributes
446 (JNIEnv* env, jobject obj, jobject attrsObj, jobject listener)
447 {
448     LOGD("nativeSetRemoteAttributes");
449     auto res = getResource(env, obj);
450     VERIFY_NO_EXC(env);
451
452     RCSResourceAttributes attrs = toNativeAttributes(env, attrsObj);
453     VERIFY_NO_EXC(env);
454
455     try
456     {
457         res->setRemoteAttributes(attrs, std::bind(onRemoteAttributesReceived,
458                 std::placeholders::_1, std::placeholders::_2, JavaGlobalRef{ env, listener }));
459     }
460     catch (const PlatformException& e) {
461         throwPlatformException(env, e);
462     }
463 }
464
465 JNIEXPORT jstring JNICALL
466 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetUri
467 (JNIEnv* env, jobject obj)
468 {
469     LOGD("nativeGetUri");
470
471     auto res = getResource(env, obj);
472     VERIFY_NO_EXC_RET_DEF(env);
473
474     return env->NewStringUTF(res->getUri().c_str());
475 }
476
477 JNIEXPORT jstring JNICALL
478 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetAddress
479 (JNIEnv* env, jobject obj)
480 {
481     LOGD("nativeGetAddress");
482     auto res = getResource(env, obj);
483     VERIFY_NO_EXC_RET_DEF(env);
484
485     return env->NewStringUTF(res->getAddress().c_str());
486 }
487
488 JNIEXPORT jobjectArray JNICALL
489 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetTypes
490 (JNIEnv* env, jobject obj)
491 {
492     LOGD("nativeGetTypes");
493     auto res = getResource(env, obj);
494     VERIFY_NO_EXC_RET_DEF(env);
495
496     return toJavaStringArray(env, res->getTypes());
497 }
498
499 JNIEXPORT jobjectArray JNICALL
500 Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeGetInterfaces
501 (JNIEnv* env, jobject obj)
502 {
503     LOGD("nativeGetInterfaces");
504
505     auto res = getResource(env, obj);
506     VERIFY_NO_EXC_RET_DEF(env);
507
508     return toJavaStringArray(env, res->getInterfaces());
509 }
510