Merge tizen_5.0 codes into tizen_4.0
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniListenerManager.h
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
23 #include "JniOcStack.h"
24 #include <mutex>
25
26 #ifndef _JniListenerManager
27 #define _JniListenerManager
28
29 class JniOcResource;
30
31 template <class T>
32 class JniListenerManager
33 {
34 public:
35     T* addListener(JNIEnv* env, jobject jListener, RemoveListenerCallback removeListener)
36     {
37         T *onEventListener = nullptr;
38
39         m_mapMutex.lock();
40
41         for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it)
42         {
43             if (env->IsSameObject(jListener, it->first))
44             {
45                 auto refPair = it->second;
46                 onEventListener = refPair.first;
47                 refPair.second++;
48                 it->second = refPair;
49                 m_listenerMap.insert(*it);
50                 LOGD("OnEventListener: ref. count is incremented");
51                 break;
52             }
53         }
54
55         if (!onEventListener)
56         {
57             onEventListener = new T(env, jListener, removeListener);
58             jobject jgListener = env->NewGlobalRef(jListener);
59
60             if (jgListener)
61             {
62                 m_listenerMap.insert(
63                         std::pair<jobject,
64                         std::pair<T*, int>>(jgListener, std::pair<T*, int>(onEventListener, 1)));
65             }
66             else
67             {
68                 LOGD("OnEventListener: Failed to create global listener ref.");
69                 delete onEventListener;
70                 m_mapMutex.unlock();
71                 return nullptr;
72             }
73             LOGD("OnEventListener: new listener");
74         }
75
76         m_mapMutex.unlock();
77         return onEventListener;
78     }
79
80     void removeListener(JNIEnv* env, jobject jListener)
81     {
82         m_mapMutex.lock();
83         for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it)
84         {
85             if (env->IsSameObject(jListener, it->first))
86             {
87                 auto refPair = it->second;
88                 if (refPair.second > 1)
89                 {
90                     refPair.second--;
91                     it->second = refPair;
92                     m_listenerMap.insert(*it);
93                     LOGI("OnEventListener: ref. count is decremented");
94                 }
95                 else
96                 {
97                     env->DeleteGlobalRef(it->first);
98                     T* listener = refPair.first;
99                     delete listener;
100                     m_listenerMap.erase(it);
101                     LOGI("OnEventListener is removed");
102                 }
103                 break;
104             }
105         }
106         m_mapMutex.unlock();
107     }
108
109     void removeAllListeners(JNIEnv* env)
110     {
111         m_mapMutex.lock();
112         LOGI("All listeners are removed");
113
114         for (auto& pair : m_listenerMap)
115         {
116             env->DeleteGlobalRef(pair.first);
117             auto refPair = pair.second;
118             delete refPair.first;
119         }
120         m_listenerMap.clear();
121
122         m_mapMutex.unlock();
123     }
124
125 private:
126     std::map<jobject, std::pair<T*, int>> m_listenerMap;
127     std::mutex m_mapMutex;
128 };
129
130 #endif