Merge remote-tracking branch 'origin/notification-service'
[platform/upstream/iotivity.git] / service / notification / android / notification-service / src / main / jni / provider / JniNotificationProvider.cpp
1 //******************************************************************
2 //
3 // Copyright 2016 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 "JniNotificationProvider.h"
22 #include "NSProviderService.h"
23
24 static JavaVM *g_jvm = NULL;
25
26 static jobject g_obj_subscriptionListener = NULL;
27 static jobject g_obj_syncListener = NULL;
28
29 jclass g_cls_Message;
30 jclass g_cls_Message_Type;
31 jclass g_cls_Consumer;
32 jclass g_cls_SyncInfo;
33 jclass g_cls_SyncType;
34 jclass g_cls_MediaContents;
35 jclass g_cls_Topic;
36 jclass g_cls_TopicsList;
37 jclass g_cls_TopicState;
38
39 static JNIEnv *GetJNIEnv(jint *ret)
40 {
41     JNIEnv *env = NULL;
42
43     *ret = g_jvm->GetEnv((void **) &env, JNI_CURRENT_VERSION);
44     switch (*ret)
45     {
46         case JNI_OK:
47             return env;
48         case JNI_EDETACHED:
49             if (g_jvm->AttachCurrentThread(&env, NULL) != JNI_OK)
50             {
51                 LOGE ("Failed to get the environment");
52                 return NULL;
53             }
54             else
55             {
56                 return env;
57             }
58         case JNI_EVERSION:
59             LOGE ("JNI version is not supported");
60         default:
61             LOGE ("Failed to get the environment");
62             return NULL;
63     }
64 }
65
66 OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
67 {
68     LOGD("JNIProviderService: getMessage - IN");
69
70     jclass cls = env->GetObjectClass( jMsg);
71
72     // Message type
73     jclass cls_messageType = (jclass) (env->NewLocalRef(g_cls_Message_Type));
74     if (!cls_messageType)
75     {
76         LOGE ("Failed to Get ObjectClass for Message Type");
77         return nullptr;
78     }
79     jmethodID mid = env->GetMethodID(cls_messageType, "ordinal", "()I");
80     jfieldID fid_type = env->GetFieldID( cls, "mType",
81                                          "Lorg/iotivity/service/ns/common/Message$MessageType;");
82     if (fid_type == NULL)
83     {
84         LOGE("Error: jfieldID for message type  is null");
85         return nullptr;
86     }
87     jobject jobj = env->GetObjectField( jMsg, fid_type);
88     if (jobj == NULL)
89     {
90         LOGE("Error: object of field  Message Type is null");
91         return nullptr;
92     }
93     jint jtype = env->CallIntMethod(jobj, mid);
94     OIC::Service::NSMessage::NSMessageType  type = (OIC::Service::NSMessage::NSMessageType) jtype;
95
96     LOGD("Message Type: %ld\n", (long )type);
97
98     // Message Time
99     jfieldID fid_tm = env->GetFieldID( cls, "mTime", "Ljava/lang/String;");
100     if (fid_tm == NULL)
101     {
102         LOGE("Error: jfieldID for message time is null");
103         return nullptr;
104     }
105     jstring jtime = (jstring)env->GetObjectField( jMsg, fid_tm);
106     const char *time = "";
107     if (jtime)
108     {
109         time = env->GetStringUTFChars( jtime, NULL);
110     }
111     else
112     {
113         LOGD("Info: messageTitle is null");
114     }
115     LOGD("Message Time: %s\n", time);
116
117     // Message TTL
118     jfieldID fid_ttl = env->GetFieldID( cls, "mTTL", "J");
119     if (fid_ttl == NULL)
120     {
121         LOGE("Error: jfieldID for message ttl is null");
122         return nullptr;
123     }
124     jlong jttl = (jlong) env->GetObjectField( jMsg, fid_ttl);
125     uint64_t  ttl = jttl;
126
127     LOGD("Message ID: %lld\n", ttl);
128
129     // Message Title
130     jfieldID fid_title = env->GetFieldID( cls, "mTitle", "Ljava/lang/String;");
131     if (fid_title == NULL)
132     {
133         LOGE("Error: jfieldID for message title is null");
134         return nullptr;
135     }
136     jstring jmsgTitle = (jstring)env->GetObjectField( jMsg, fid_title);
137     const char *messageTitle = "";
138     if (jmsgTitle)
139     {
140         messageTitle = env->GetStringUTFChars( jmsgTitle, NULL);
141     }
142     else
143     {
144         LOGD("Info: messageTitle is null");
145     }
146     LOGD("Message Title: %s\n", messageTitle);
147
148     // Message Content Text
149     jfieldID fid_body = env->GetFieldID( cls, "mContentText", "Ljava/lang/String;");
150     if (fid_body == NULL)
151     {
152         LOGE("Error: jfieldID for message context Text is null");
153         return nullptr;
154     }
155     jstring jmsgBody = (jstring)env->GetObjectField( jMsg, fid_body);
156     const char *messageBody = "";
157     if (jmsgBody)
158     {
159         messageBody = env->GetStringUTFChars( jmsgBody, NULL);
160     }
161     else
162     {
163         LOGD("Info: messageBody is null");
164     }
165     LOGD("Message Body: %s\n", messageBody);
166
167     // Message Source
168     jfieldID fid_source = env->GetFieldID( cls, "mSourceName", "Ljava/lang/String;");
169     if (fid_source == NULL)
170     {
171         LOGE("Error: jfieldID for message source is null");
172         return nullptr;
173     }
174     jstring jmsgSource = (jstring)env->GetObjectField( jMsg, fid_source);
175     const char *messageSource = "";
176     if (jmsgSource)
177     {
178         messageSource = env->GetStringUTFChars( jmsgSource, NULL);
179     }
180     else
181     {
182         LOGD("Info: messageSource is null");
183     }
184     LOGD("Message Source: %s\n", messageSource);
185
186     // Message MediaContents
187     jfieldID fid_media = env->GetFieldID( cls, "mMediaContents",
188                                           "Lorg/iotivity/service/ns/common/MediaContents;");
189     if (fid_media == NULL)
190     {
191         LOGE("Error: jfieldID for MediaContents is null");
192         return nullptr;
193     }
194     jobject jmedia = env->GetObjectField( jMsg, fid_media);
195     if (jmedia == NULL)
196     {
197         LOGE("Error: jmedia object of MediaContents inside Message is null");
198         return nullptr;
199     }
200     jclass cls_MediaContents = (jclass) (env->NewLocalRef(g_cls_MediaContents));
201     if (!cls_MediaContents)
202     {
203         LOGE ("Failed to Get ObjectClass for class MediaContents");
204         return nullptr;
205     }
206     jfieldID fid_icon = env->GetFieldID( cls_MediaContents, "mIconImage", "Ljava/lang/String;");
207     if (fid_icon == NULL)
208     {
209         LOGE("Error: jfieldID for iconImage is null");
210         return nullptr;
211     }
212     jstring jiconImage = (jstring)env->GetObjectField( jmedia, fid_icon);
213     const char *iconImage = "";
214     if (jiconImage)
215     {
216         iconImage = env->GetStringUTFChars( jiconImage, NULL);
217     }
218     else
219     {
220         LOGD("Info: iconImage is null");
221     }
222
223     LOGD("iconImage: %s\n", iconImage);
224
225     OIC::Service::NSMediaContents *media = new OIC::Service::NSMediaContents(std::string(iconImage));
226     OIC::Service::NSMessage *nsMsg = OIC::Service::NSProviderService::getInstance()->CreateMessage();
227
228     nsMsg->setType(type);
229     nsMsg->setTime(std::string(time));
230     nsMsg->setTTL(ttl);
231     nsMsg->setTitle(std::string(messageTitle));
232     nsMsg->setContentText(std::string(messageBody));
233     nsMsg->setSourceName(std::string(messageSource));
234     nsMsg->setMediaContents(media);
235
236     env->DeleteLocalRef(cls_messageType);
237     env->DeleteLocalRef(cls_MediaContents);
238
239     if (jtime)
240     {
241         env->ReleaseStringUTFChars(jtime, time);
242     }
243     if (jmsgTitle)
244     {
245         env->ReleaseStringUTFChars(jmsgTitle, messageTitle);
246     }
247     if (jmsgBody)
248     {
249         env->ReleaseStringUTFChars(jmsgBody, messageBody);
250     }
251     if (jmsgSource)
252     {
253         env->ReleaseStringUTFChars(jmsgSource, messageSource);
254     }
255     if (jiconImage)
256     {
257         env->ReleaseStringUTFChars(jiconImage, iconImage);
258     }
259
260     LOGD("JNIProviderService: getMessage - OUT");
261     return nsMsg;
262
263 }
264
265 jobject getJavaState(JNIEnv *env, OIC::Service::NSTopic::NSTopicState nsState)
266 {
267     LOGD("JNIProviderService: getJavaState - IN");
268
269     // TopicState
270     jclass cls_topicState = (jclass) (env->NewLocalRef(g_cls_TopicState));
271     if (!cls_topicState)
272     {
273         LOGE ("Failed to Get ObjectClass for TopicState Type");
274         return nullptr;
275     }
276
277     jobject obj_topicState;
278     switch (nsState)
279     {
280         case OIC::Service::NSTopic::NSTopicState::UNSUBSCRIBED:
281             {
282                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,
283                                           "UNSUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");
284                 obj_topicState = env->GetStaticObjectField(cls_topicState, fieldID);
285             }
286         case OIC::Service::NSTopic::NSTopicState::SUBSCRIBED:
287             {
288                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,
289                                           "SUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");
290                 obj_topicState = env->GetStaticObjectField(cls_topicState, fieldID);
291             }
292
293     }
294     if (obj_topicState == NULL)
295     {
296         LOGE("Error: object of field  TopicState  is null");
297         return NULL;
298     }
299     env->DeleteLocalRef(cls_topicState);
300     LOGD("JNIProviderService: getJavaState - OUT");
301     return obj_topicState;
302 }
303
304 jobject getJavaTopicsList(JNIEnv *env, OIC::Service::NSTopicsList *topicList)
305 {
306     LOGD("JNIProviderService: getJavaTopicsList - IN");
307     jclass cls_topicList = (jclass) (env->NewLocalRef(g_cls_TopicsList));
308     if (!cls_topicList)
309     {
310         LOGE ("Failed to Get ObjectClass for TopicsList");
311         return NULL;
312     }
313     jmethodID mid_topicList = env->GetMethodID(cls_topicList, "<init>", "()V");
314     if (!mid_topicList)
315     {
316         LOGE ("Failed to Get MethodID for TopicsList<init>");
317         return NULL;
318     }
319     jobject obj_topicList = env->NewObject(cls_topicList, mid_topicList);
320     jmethodID mid_addTopic =
321         env->GetMethodID(cls_topicList, "addTopic", "(Lorg/iotivity/service/ns/common/Topic;)V");
322     for (auto it : topicList->getTopicsList())
323     {
324         jobject jState = getJavaState(env, it->getState());
325         std::string topicName = it->getTopicName();
326         jstring jTopicName = env->NewStringUTF(topicName.c_str());
327         env->CallVoidMethod(obj_topicList, mid_addTopic, jTopicName, jState);
328     }
329     env->DeleteLocalRef(cls_topicList);
330     LOGD("JNIProviderService: getJavaTopicsList - OUT");
331     return obj_topicList;
332 }
333
334 void onSubscribeListenerCb(OIC::Service::NSConsumer *consumer)
335 {
336     LOGD("JNIProviderService_onSubscribeListenerCb - IN");
337
338     jint envRet;
339     JNIEnv *env = GetJNIEnv(&envRet);
340     if (NULL == env) return ;
341
342     jobject jSubscriptionListener = (jobject) env->NewLocalRef(g_obj_subscriptionListener);
343     if (!jSubscriptionListener)
344     {
345         LOGE ("Failed to Get jSubscriptionListener");
346         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
347         return ;
348     }
349
350     LOGD("consumer ID : %s\n", consumer->getConsumerId().c_str());
351
352     jstring jConsumerId = env->NewStringUTF( consumer->getConsumerId().c_str());
353
354     jclass cls_consumer = (jclass) (env->NewLocalRef(g_cls_Consumer));
355     if (!cls_consumer)
356     {
357         LOGE ("Failed to Get ObjectClass for Consumer");
358         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
359         return ;
360     }
361
362     jmethodID mid_consumer = env->GetMethodID(
363                                  cls_consumer,
364                                  "<init>",
365                                  "(JLjava/lang/String;Lorg/iotivity/service/ns/provider/Consumer)V");
366     if (!mid_consumer)
367     {
368         LOGE ("Failed to Get MethodID for Consumer<init>");
369         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
370         return ;
371     }
372     jobject obj_consumer = env->NewObject( cls_consumer, mid_consumer, jConsumerId);
373
374     jclass cls = env->GetObjectClass( jSubscriptionListener);
375     if (!cls)
376     {
377         LOGE("Failed to Get ObjectClass of jSubscriptionListener");
378         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
379         return;
380     }
381     jmethodID mid = env->GetMethodID(
382                         cls,
383                         "onConsumerSubscribed",
384                         "(Lorg/iotivity/service/ns/provider/Consumer;)V");
385     if (!mid)
386     {
387         LOGE("Failed to Get MethodID of onConsumerSubscribed");
388         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
389         return;
390     }
391
392     env->CallVoidMethod( jSubscriptionListener, mid, obj_consumer);
393     env->DeleteLocalRef(jSubscriptionListener);
394     env->DeleteLocalRef(cls_consumer);
395     if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
396     LOGD("JNIProviderService_onSubscribeListenerCb - OUT");
397     return;
398 }
399
400 void onSyncInfoListenerCb(OIC::Service::NSSyncInfo *sync)
401 {
402     LOGD("JNIProviderService_onSyncInfoListenerCb - IN");
403
404     jint envRet;
405     JNIEnv *env = GetJNIEnv(&envRet);
406     if (NULL == env) return ;
407
408     jobject jSyncListener = (jobject) env->NewLocalRef(g_obj_syncListener);
409     if (!jSyncListener)
410     {
411         LOGE ("Failed to Get jSyncListener");
412         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
413         return ;
414     }
415
416     LOGD("Sync ID : %ld\n", (long) sync->getMessageId());
417     LOGD("Sync STATE : %d\n", (int) sync->getState());
418
419     jlong jMessageId = (long)  sync->getMessageId();
420     jstring jProviderId = env->NewStringUTF(sync->getProviderId().c_str());
421     jobject syncType;
422
423     jclass cls_SyncType = (jclass) (env->NewLocalRef(g_cls_SyncType));
424     if (!cls_SyncType)
425     {
426         LOGE ("Failed to Get ObjectClass for SyncType");
427         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
428         return ;
429     }
430     switch (sync->getState())
431     {
432         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_UNREAD:
433             {
434                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
435                                           "UNREAD", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
436                 syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
437             }
438         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ :
439             {
440                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
441                                           "READ", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
442                 syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
443             }
444         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED :
445             {
446                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
447                                           "DELETED", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
448                 syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
449             }
450
451     }
452
453     jclass cls_SyncInfo = (jclass) (env->NewLocalRef(g_cls_SyncInfo));
454     if (!cls_SyncInfo)
455     {
456         LOGE ("Failed to Get ObjectClass for SyncInfo");
457         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
458         return ;
459     }
460     jmethodID mid_syncInfo = env->GetMethodID(
461                                  cls_SyncInfo,
462                                  "<init>",
463                                  "(JLjava/lang/String;Lorg/iotivity/service/ns/common/SyncInfo$SyncType)V");
464     if (!mid_syncInfo)
465     {
466         LOGE ("Failed to Get MethodID for SyncInfo");
467         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
468         return ;
469     }
470
471     jobject obj_syncInfo = env->NewObject( cls_SyncInfo, mid_syncInfo, jMessageId, jProviderId,
472                                            syncType);
473
474     jclass cls = env->GetObjectClass( jSyncListener);
475     if (!cls)
476     {
477         LOGE("Failed to Get ObjectClass");
478         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
479         return;
480     }
481     jmethodID mid = env->GetMethodID( cls, "onMessageSynchronized",
482                                       "(Lorg/iotivity/service/ns/common/SyncInfo)V");
483     if (!mid)
484     {
485         LOGE("Failed to Get MethodID");
486         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
487         return;
488     }
489     env->CallVoidMethod( jSyncListener, mid, obj_syncInfo);
490
491     env->DeleteLocalRef(jSyncListener);
492     env->DeleteLocalRef(cls_SyncInfo);
493     env->DeleteLocalRef(cls_SyncType);
494     if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
495
496     LOGD("JNIProviderService: OnSyncInfoListenerCb - OUT");
497     return;
498
499 }
500
501 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStart(
502     JNIEnv *env, jobject jObj, jboolean jPolicy, jobject jSubscriptionListener,
503     jobject jSyncListener)
504 {
505     LOGD("JNIProviderService: nativeStart - IN");
506     if (!jSubscriptionListener || !jSyncListener)
507     {
508         LOGE("Fail to set listeners");
509         ThrowNSException(NS_ERROR, "Listener cannot be null");
510         return (jint) OIC::Service::NSResult::ERROR;
511     }
512
513     if (g_obj_subscriptionListener != NULL)
514     {
515         env->DeleteGlobalRef(g_obj_subscriptionListener);
516     }
517     if (g_obj_syncListener != NULL)
518     {
519         env->DeleteGlobalRef(g_obj_syncListener);
520     }
521
522     g_obj_subscriptionListener = (jobject)  env->NewGlobalRef(jSubscriptionListener);
523     g_obj_syncListener = (jobject)  env->NewGlobalRef(jSyncListener);
524
525     // check access policy
526
527     OIC::Service::NSProviderService::ProviderConfig cfg;
528     cfg.m_subscribeRequestCb =  onSubscribeListenerCb;
529     cfg.m_syncInfoCb =  onSyncInfoListenerCb;
530     cfg.policy = (bool) jPolicy;
531
532     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->Start(cfg);
533     if (result != OIC::Service::NSResult::OK)
534     {
535         LOGE("Fail to start NSProviderService");
536
537     }
538
539     LOGD("JNIProviderService: nativeStart - OUT");
540     return (jint) result;
541 }
542
543 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStop(
544     JNIEnv *env, jobject jObj)
545 {
546     LOGD("JNIProviderService: nativeStop - IN");
547
548     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->Stop();
549     if (result !=  OIC::Service::NSResult::OK)
550     {
551         LOGD("Fail to stop NSProvider service");
552         return (jint) result;
553     }
554
555     env->DeleteGlobalRef( g_obj_subscriptionListener);
556     env->DeleteGlobalRef( g_obj_syncListener);
557     g_obj_subscriptionListener = NULL;
558     g_obj_syncListener = NULL;
559
560     LOGD("JNIProviderService: nativeStop - OUT");
561     return (jint) result;
562 }
563
564 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendMessage(
565     JNIEnv *env, jobject jObj, jobject jMsg)
566 {
567     LOGD("JNIProviderService: nativeSendMessage - IN");
568     if (!jMsg)
569     {
570         LOGD("Fail to send notification - Message is null");
571         ThrowNSException(NS_ERROR, "Message cannot be null");
572         return (jint) OIC::Service::NSResult::ERROR;
573     }
574     OIC::Service::NSMessage *nsMsg = getNativeMessage(env, jMsg);
575     if (nsMsg == nullptr)
576     {
577         ThrowNSException(NS_ERROR, "Message didn't have a field ID ");
578         return (jint) OIC::Service::NSResult::ERROR;
579     }
580
581     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->SendMessage(nsMsg);
582     if (result !=  OIC::Service::NSResult::OK)
583     {
584         LOGD("Fail to send NSProvider Message");
585     }
586     LOGD("JNIProviderService: nativeSendMessage - OUT");
587     return (jint) result;
588 }
589
590 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendSyncInfo(
591     JNIEnv *env, jobject jObj, jlong messageId , jint syncState)
592 {
593     LOGD("JNIProviderService: nativeSendSyncInfo - IN");
594     OIC::Service::NSProviderService::getInstance()->SendSyncInfo( messageId,
595             (OIC::Service::NSSyncInfo::NSSyncType) syncState);
596     LOGD("JNIProviderService: nativeSendSyncInfo - OUT");
597     return;
598 }
599
600 JNIEXPORT jint JNICALL
601 Java_org_iotivity_service_ns_provider_ProviderService_nativeEnableRemoteService(JNIEnv *env,
602         jobject jObj, jstring jstr)
603 {
604     LOGD("JNIProviderService: nativeEnableRemoteService - IN");
605     if (!jstr)
606     {
607         ThrowNSException(NS_ERROR, "Server Address Can't be NULL");
608         return (jint) OIC::Service::NSResult::ERROR;
609     }
610
611     const char *address = env->GetStringUTFChars( jstr, NULL);
612     std::string servAddress(address);
613     OIC::Service::NSResult result  =
614         OIC::Service::NSProviderService::getInstance()->EnableRemoteService(
615             servAddress);
616     if (result !=  OIC::Service::NSResult::OK)
617     {
618         LOGE("Fail to Enable Remote Service");
619     }
620     env->ReleaseStringUTFChars(jstr, address);
621     LOGD("JNIProviderService: nativeEnableRemoteService - OUT");
622     return (jint) result;
623 }
624
625 JNIEXPORT jint JNICALL
626 Java_org_iotivity_service_ns_provider_ProviderService_nativeDisableRemoteService(JNIEnv *env,
627         jobject jObj, jstring jstr)
628 {
629     LOGD("JNIProviderService: nativeDisableRemoteService - IN");
630     if (!jstr)
631     {
632         ThrowNSException(NS_ERROR, "Server Address Can't be NULL");
633         return (jint) OIC::Service::NSResult::ERROR;
634     }
635
636     const char *address = env->GetStringUTFChars( jstr, NULL);
637     std::string servAddress(address);
638     OIC::Service::NSResult result  =
639         OIC::Service::NSProviderService::getInstance()->DisableRemoteService(
640             servAddress);
641     if (result !=  OIC::Service::NSResult::OK)
642     {
643         LOGE("Fail to Disable Remote Service");
644     }
645     env->ReleaseStringUTFChars(jstr, address);
646     LOGD("JNIProviderService: nativeDisableRemoteService - OUT");
647     return (jint) result;
648 }
649
650 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeAddTopic
651 (JNIEnv *env, jobject jObj, jstring jTopicName)
652 {
653     LOGD("JNIProviderService: nativeAddTopic - IN");
654     if (!jTopicName)
655     {
656         ThrowNSException(NS_ERROR, "Topic Name Can't be NULL");
657         return (jint) OIC::Service::NSResult::ERROR;
658     }
659     const char *name = env->GetStringUTFChars( jTopicName, NULL);
660     std::string topicName(name);
661     OIC::Service::NSResult result  = OIC::Service::NSProviderService::getInstance()->AddTopic(
662                                          topicName);
663     if (result !=  OIC::Service::NSResult::OK)
664     {
665         LOGE("Fail to Add Topic");
666     }
667     env->ReleaseStringUTFChars(jTopicName, name);
668     LOGD("JNIProviderService: nativeAddTopic - OUT");
669     return (jint) result;
670 }
671 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeDeleteTopic
672 (JNIEnv *env, jobject jObj, jstring jTopicName)
673 {
674     LOGD("JNIProviderService: nativeDeleteTopic - IN");
675     if (!jTopicName)
676     {
677         ThrowNSException(NS_ERROR, "Topic Name Can't be NULL");
678         return (jint) OIC::Service::NSResult::ERROR;
679     }
680     const char *name = env->GetStringUTFChars( jTopicName, NULL);
681     std::string topicName(name);
682     OIC::Service::NSResult result  = OIC::Service::NSProviderService::getInstance()->DeleteTopic(
683                                          topicName);
684     if (result !=  OIC::Service::NSResult::OK)
685     {
686         LOGE("Fail to Add Topic");
687     }
688     env->ReleaseStringUTFChars(jTopicName, name);
689     LOGD("JNIProviderService: nativeDeleteTopic - OUT");
690     return (jint) result;
691 }
692
693 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeGetTopics
694 (JNIEnv *env, jobject jObj)
695 {
696     LOGD("JNIProviderService: nativeGetTopics - IN");
697
698     OIC::Service::NSTopicsList *topicList  =
699         OIC::Service::NSProviderService::getInstance()->GetTopics();
700     if (topicList == nullptr)
701     {
702         ThrowNSException(NS_ERROR, "Topic List doesn't exist");
703         return NULL;
704     }
705
706     jobject obj_topicList = getJavaTopicsList(env, topicList);
707
708     LOGD("JNIProviderService: nativeGetTopics - OUT");
709     return obj_topicList;
710 }
711
712 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeAcceptSubscription(
713     JNIEnv *env,  jobject jObj, jobject jConsumer, jboolean jAccepted)
714 {
715     LOGD("JNIProviderService: nativeAcceptSubscription - IN");
716
717     jclass consumerClass =  env->GetObjectClass( jConsumer);
718     if (!consumerClass)
719     {
720         ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Consumer");
721         return (jint) OIC::Service::NSResult::ERROR;
722     }
723
724     // Consumer ID
725     jfieldID fid_id =  env->GetFieldID(consumerClass, "mConsumerId",  "Ljava/lang/String;");
726     if (fid_id == NULL)
727     {
728         LOGE("Error: jfieldID for mConsumerId  is null");
729         ThrowNSException(NS_ERROR, "ConsumerId not found");
730         return (jint) OIC::Service::NSResult::ERROR;
731     }
732
733     jstring jconId = (jstring)env->GetObjectField( jConsumer, fid_id);
734     if (!jconId)
735     {
736         ThrowNSException(NS_ERROR, "ProviderId cannot be null");
737         return (jint) OIC::Service::NSResult::ERROR;;
738     }
739     const char *conId = env->GetStringUTFChars( jconId, NULL);
740     std::string consumerId(conId);
741     env->ReleaseStringUTFChars(jconId, conId);
742
743     LOGD("Consumer ID: %s\n", consumerId.c_str());
744
745     OIC::Service::NSConsumer *consumer =
746         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
747     int result =  consumer->acceptSubscription(consumer,  (bool)jAccepted);
748     if (jAccepted)
749     {
750         LOGD("Subscription Accepted");
751     }
752     else
753     {
754         LOGD("Subscription Denied");
755     }
756
757     LOGD("JNIProviderService: nativeAcceptSubscription - OUT");
758     return result;
759 }
760 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeSelectTopic
761 (JNIEnv *env, jobject jObj, jstring jConsumerId, jstring jTopicName)
762 {
763     LOGD("JNIProviderService: nativeSelectTopic - IN");
764     if (!jConsumerId || !jTopicName)
765     {
766         ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
767         return (jint) OIC::Service::NSResult::ERROR;
768     }
769     const char *name = env->GetStringUTFChars( jTopicName, NULL);
770     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
771     std::string topicName(name);
772     std::string consumerId(id);
773     OIC::Service::NSConsumer *nsConsumer =
774         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
775     if (!nsConsumer)
776     {
777         ThrowNSException(NS_ERROR, "Consumer does exists");
778         return (jint) OIC::Service::NSResult::ERROR;
779     }
780     OIC::Service::NSResult result  = nsConsumer->selectTopic(topicName);
781
782     if (result !=  OIC::Service::NSResult::OK)
783     {
784         LOGD("Fail to Select Topic");
785     }
786     env->ReleaseStringUTFChars(jTopicName, name);
787     env->ReleaseStringUTFChars(jConsumerId, id);
788     LOGD("JNIProviderService: nativeSelectTopic - OUT");
789     return (jint) result;
790 }
791 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeUnselectTopic
792 (JNIEnv *env, jobject jObj, jstring jConsumerId, jstring jTopicName)
793 {
794     LOGD("JNIProviderService: nativeUnselectTopic - IN");
795     if (!jConsumerId || !jTopicName)
796     {
797         ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
798         return (jint) OIC::Service::NSResult::ERROR;
799     }
800     const char *name = env->GetStringUTFChars( jTopicName, NULL);
801     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
802     std::string topicName(name);
803     std::string consumerId(id);
804     OIC::Service::NSConsumer *nsConsumer =
805         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
806     if (!nsConsumer)
807     {
808         ThrowNSException(NS_ERROR, "Consumer does exists");
809         return (jint) OIC::Service::NSResult::ERROR;
810     }
811     OIC::Service::NSResult result  = nsConsumer->unselectTopic(topicName);
812
813     if (result !=  OIC::Service::NSResult::OK)
814     {
815         LOGE("Fail to Unselect Topic");
816     }
817     env->ReleaseStringUTFChars(jTopicName, name);
818     env->ReleaseStringUTFChars(jConsumerId, id);
819     LOGD("JNIProviderService: nativeUnselectTopic - OUT");
820     return (jint) result;
821 }
822
823 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeGetConsumerTopics
824 (JNIEnv *env, jobject jObj, jstring jConsumerId)
825 {
826     LOGD("JNIProviderService: nativeGetConsumerTopics - IN");
827     if (!jConsumerId)
828     {
829         ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
830         return NULL;
831     }
832     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
833     std::string consumerId(id);
834     OIC::Service::NSConsumer *nsConsumer =
835         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
836     if (!nsConsumer)
837     {
838         ThrowNSException(NS_ERROR, "Consumer does exists");
839         return NULL;
840     }
841     OIC::Service::NSTopicsList *topicList  = nsConsumer->getConsumerTopics();
842     if (topicList == nullptr)
843     {
844         ThrowNSException(NS_ERROR, "Topic List doesn't exist");
845         return NULL;
846     }
847     jobject obj_topicList = getJavaTopicsList(env, topicList);
848
849     env->ReleaseStringUTFChars(jConsumerId, id);
850     LOGD("JNIProviderService: nativeGetConsumerTopics - OUT");
851     return obj_topicList;
852 }
853
854 // JNI OnLoad
855 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
856 {
857     LOGD("ProviderService_JNI_OnLoad");
858     g_jvm = jvm;
859
860     JNIEnv *env;
861     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)
862     {
863         LOGE("Failed to get the environment using GetEnv()");
864         return JNI_ERR;
865     }
866
867     jclass localMessage = env->FindClass(
868                               "org/iotivity/service/ns/common/Message");
869     if (!localMessage)
870     {
871         LOGE("Failed to get local Message class");
872         return JNI_ERR;
873     }
874     g_cls_Message = (jclass) (env->NewGlobalRef(localMessage));
875     if (!g_cls_Message)
876     {
877         LOGE("Failed to set Global Message reference");
878         return JNI_ERR;
879     }
880
881     jclass localMessageType = env->FindClass(
882                                   "org/iotivity/service/ns/common/Message$MessageType");
883     if (!localMessageType)
884     {
885         LOGE("Failed to get local Message Type class");
886         return JNI_ERR;
887     }
888     g_cls_Message_Type = (jclass) (env->NewGlobalRef(localMessageType));
889     if (!g_cls_Message_Type)
890     {
891         LOGE("Failed to set Global Message Type reference");
892         return JNI_ERR;
893     }
894
895     jclass localConsumer = env->FindClass(
896                                "org/iotivity/service/ns/provider/Consumer");
897     if (!localConsumer)
898     {
899         LOGE("Failed to get local Provider class");
900         return JNI_ERR;
901     }
902     g_cls_Consumer = (jclass) (env->NewGlobalRef(localConsumer));
903     if (!g_cls_Consumer)
904     {
905         LOGE("Failed to set Global Provider reference");
906         return JNI_ERR;
907     }
908
909     jclass localSyncInfo = env->FindClass(
910                                "org/iotivity/service/ns/common/SyncInfo");
911     if (!localSyncInfo)
912     {
913         LOGE("Failed to get local SyncInfo class");
914         return JNI_ERR;
915     }
916     g_cls_SyncInfo = (jclass) (env->NewGlobalRef(localSyncInfo));
917     if (!g_cls_SyncInfo)
918     {
919         LOGE("Failed to set Global SyncInfo reference");
920         return JNI_ERR;
921     }
922
923     jclass localSyncType = env->FindClass(
924                                "org/iotivity/service/ns/common/SyncInfo$SyncType");
925     if (!localSyncType)
926     {
927         LOGE("Failed to get local SyncType enum");
928         return JNI_ERR;
929     }
930     g_cls_SyncType = (jclass) (env->NewGlobalRef(localSyncType));
931     if (!g_cls_SyncType)
932     {
933         LOGE("Failed to set Global SyncType reference");
934         return JNI_ERR;
935     }
936
937     jclass localMediaContents = env->FindClass(
938                                     "org/iotivity/service/ns/common/MediaContents");
939     if (!localMediaContents)
940     {
941         LOGE("Failed to get local MediaContents class");
942         return JNI_ERR;
943     }
944     g_cls_MediaContents = (jclass) (env->NewGlobalRef(localMediaContents));
945     if (!g_cls_MediaContents)
946     {
947         LOGE("Failed to set Global MediaContents reference");
948         return JNI_ERR;
949     }
950
951     jclass localTopic = env->FindClass(
952                             "org/iotivity/service/ns/common/Topic");
953     if (!localTopic)
954     {
955         LOGE("Failed to get local Topic class");
956         return JNI_ERR;
957     }
958     g_cls_Topic = (jclass) (env->NewGlobalRef(localTopic));
959     if (!g_cls_Topic)
960     {
961         LOGE("Failed to set Global Topic reference");
962         return JNI_ERR;
963     }
964
965     jclass localTopicsList = env->FindClass(
966                                  "org/iotivity/service/ns/common/TopicsList");
967     if (!localTopicsList)
968     {
969         LOGE("Failed to get local Topic class");
970         return JNI_ERR;
971     }
972     g_cls_TopicsList = (jclass) (env->NewGlobalRef(localTopicsList));
973     if (!g_cls_TopicsList)
974     {
975         LOGE("Failed to set Global TopicsList reference");
976         return JNI_ERR;
977     }
978
979     jclass localTopicState = env->FindClass(
980                                  "org/iotivity/service/ns/common/Topic$TopicState");
981     if (!localTopicState)
982     {
983         LOGE("Failed to get local TopicState enum");
984         return JNI_ERR;
985     }
986     g_cls_TopicState = (jclass) (env->NewGlobalRef(localTopicState));
987     if (!g_cls_TopicState)
988     {
989         LOGE("Failed to set Global TopicState reference");
990         return JNI_ERR;
991     }
992
993     env->DeleteLocalRef(localMessage);
994     env->DeleteLocalRef(localMessageType);
995     env->DeleteLocalRef(localConsumer);
996     env->DeleteLocalRef(localSyncInfo);
997     env->DeleteLocalRef(localSyncType);
998     env->DeleteLocalRef(localMediaContents);
999     env->DeleteLocalRef(localTopic);
1000     env->DeleteLocalRef(localTopicsList);
1001     env->DeleteLocalRef(localTopicState);
1002
1003     return NSExceptionInit(env);
1004 }
1005
1006 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)
1007 {
1008     LOGD("ProviderService_JNI_OnUnload");
1009     JNIEnv *env;
1010
1011     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)
1012     {
1013         LOGE("Failed to get the environment using GetEnv()");
1014         return ;
1015     }
1016
1017     env->DeleteGlobalRef(g_cls_Message);
1018     env->DeleteGlobalRef(g_cls_Consumer);
1019     env->DeleteGlobalRef(g_cls_SyncInfo);
1020     env->DeleteGlobalRef(g_cls_SyncType);
1021     env->DeleteGlobalRef(g_cls_MediaContents);
1022     env->DeleteGlobalRef(g_cls_Message_Type);
1023     env->DeleteGlobalRef(g_cls_Topic);
1024     env->DeleteGlobalRef(g_cls_TopicsList);
1025     env->DeleteGlobalRef(g_cls_TopicState);
1026 }