Merge "Merge remote-tracking branch 'origin/master' into notification-service" into...
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniOnPresenceListener.cpp
1 /*
2 * //******************************************************************
3 * //
4 * // Copyright 2015 Intel Corporation.
5 * //
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 * //
8 * // Licensed under the Apache License, Version 2.0 (the "License");
9 * // you may not use this file except in compliance with the License.
10 * // You may obtain a copy of the License at
11 * //
12 * //      http://www.apache.org/licenses/LICENSE-2.0
13 * //
14 * // Unless required by applicable law or agreed to in writing, software
15 * // distributed under the License is distributed on an "AS IS" BASIS,
16 * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * // See the License for the specific language governing permissions and
18 * // limitations under the License.
19 * //
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 */
22 #include "JniOnPresenceListener.h"
23 #include "JniUtils.h"
24
25 JniOnPresenceListener::JniOnPresenceListener(JNIEnv *env, jobject jListener,
26     RemoveListenerCallback removeListenerCallback)
27 {
28     m_jwListener = env->NewWeakGlobalRef(jListener);
29     m_removeListenerCallback = removeListenerCallback;
30 }
31
32 JniOnPresenceListener::~JniOnPresenceListener()
33 {
34     LOGD("~JniOnPresenceListener");
35     if (m_jwListener)
36     {
37         jint ret = JNI_ERR;
38         JNIEnv *env = GetJNIEnv(ret);
39         if (nullptr == env)
40         {
41             return;
42         }
43
44         env->DeleteWeakGlobalRef(m_jwListener);
45         m_jwListener = nullptr;
46
47         if (JNI_EDETACHED == ret)
48         {
49             g_jvm->DetachCurrentThread();
50         }
51     }
52 }
53
54 void JniOnPresenceListener::onPresenceCallback(OCStackResult result, const unsigned int nonce,
55     const std::string& hostAddress)
56 {
57     LOGI("JniOnPresenceListener::onPresenceCallback");
58     if (!m_jwListener)
59     {
60         return;
61     }
62
63     jint ret = JNI_ERR;
64     JNIEnv *env = GetJNIEnv(ret);
65     if (nullptr == env)
66     {
67         return;
68     }
69
70     if (OC_STACK_OK != result && OC_STACK_PRESENCE_STOPPED != result &&
71         OC_STACK_PRESENCE_TIMEOUT != result &&  OC_STACK_PRESENCE_DO_NOT_HANDLE != result)
72     {
73         ThrowOcException(result, "onPresenceCallback: stack failure");
74         if (JNI_EDETACHED == ret)
75         {
76             g_jvm->DetachCurrentThread();
77         }
78         return;
79     }
80
81     std::string enumField = JniUtils::stackResultToStr(result);
82     if (enumField.empty())
83     {
84         ThrowOcException(JNI_INVALID_VALUE, "Unexpected OCStackResult value");
85         if (JNI_EDETACHED == ret)
86         {
87             g_jvm->DetachCurrentThread();
88         }
89         return;
90     }
91
92     jobject jPresenceStatus = env->CallStaticObjectMethod(g_cls_OcPresenceStatus,
93         g_mid_OcPresenceStatus_get, env->NewStringUTF(enumField.c_str()));
94     if (!jPresenceStatus)
95     {
96         checkExAndRemoveListener(env);
97         if (JNI_EDETACHED == ret)
98         {
99             g_jvm->DetachCurrentThread();
100         }
101         return;
102     }
103
104     jobject jListener = env->NewLocalRef(m_jwListener);
105     if (!jListener)
106     {
107         checkExAndRemoveListener(env);
108         if (JNI_EDETACHED == ret)
109         {
110             g_jvm->DetachCurrentThread();
111         }
112         return;
113     }
114
115     jclass clsL = env->GetObjectClass(jListener);
116     if (!clsL)
117     {
118         checkExAndRemoveListener(env);
119         if (JNI_EDETACHED == ret)
120         {
121             g_jvm->DetachCurrentThread();
122         }
123         return;
124     }
125     jmethodID midL = env->GetMethodID(clsL, "onPresence",
126         "(Lorg/iotivity/base/OcPresenceStatus;ILjava/lang/String;)V");
127     if (!midL)
128     {
129         checkExAndRemoveListener(env);
130         if (JNI_EDETACHED == ret)
131         {
132             g_jvm->DetachCurrentThread();
133         }
134         return;
135     }
136
137     env->CallVoidMethod(jListener, midL, jPresenceStatus,
138         (jint)nonce, env->NewStringUTF(hostAddress.c_str()));
139     if (env->ExceptionCheck())
140     {
141         LOGE("Java exception is thrown");
142         checkExAndRemoveListener(env);
143     }
144
145     if (JNI_EDETACHED == ret)
146     {
147         g_jvm->DetachCurrentThread();
148     }
149 }
150
151 void JniOnPresenceListener::checkExAndRemoveListener(JNIEnv* env)
152 {
153     if (env->ExceptionCheck())
154     {
155         jthrowable ex = env->ExceptionOccurred();
156         env->ExceptionClear();
157         m_removeListenerCallback(env, m_jwListener);
158         env->Throw((jthrowable)ex);
159     }
160     else
161     {
162         m_removeListenerCallback(env, m_jwListener);
163     }
164 }
165
166 jweak JniOnPresenceListener::getJWListener()
167 {
168     return this->m_jwListener;
169 }