Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniListenerManager.h
1 /*\r
2 * //******************************************************************\r
3 * //\r
4 * // Copyright 2015 Intel Corporation.\r
5 * //\r
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
7 * //\r
8 * // Licensed under the Apache License, Version 2.0 (the "License");\r
9 * // you may not use this file except in compliance with the License.\r
10 * // You may obtain a copy of the License at\r
11 * //\r
12 * //      http://www.apache.org/licenses/LICENSE-2.0\r
13 * //\r
14 * // Unless required by applicable law or agreed to in writing, software\r
15 * // distributed under the License is distributed on an "AS IS" BASIS,\r
16 * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17 * // See the License for the specific language governing permissions and\r
18 * // limitations under the License.\r
19 * //\r
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
21 */\r
22 \r
23 #include "JniOcStack.h"\r
24 #include <mutex>\r
25 \r
26 #ifndef _JniListenerManager\r
27 #define _JniListenerManager\r
28 \r
29 class JniOcResource;\r
30 \r
31 template <class T>\r
32 class JniListenerManager\r
33 {\r
34 public:\r
35     T* addListener(JNIEnv* env, jobject jListener, JniOcResource* owner)\r
36     {\r
37         T *onEventListener = NULL;\r
38 \r
39         m_mapMutex.lock();\r
40 \r
41         for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it)\r
42         {\r
43             if (env->IsSameObject(jListener, it->first))\r
44             {\r
45                 auto refPair = it->second;\r
46                 onEventListener = refPair.first;\r
47                 refPair.second++;\r
48                 it->second = refPair;\r
49                 m_listenerMap.insert(*it);\r
50                 LOGD("OnEventListener: ref. count is incremented");\r
51                 break;\r
52             }\r
53         }\r
54         if (!onEventListener)\r
55         {\r
56             onEventListener = new T(env, jListener, owner);\r
57             jobject jgListener = env->NewGlobalRef(jListener);\r
58 \r
59             if (jgListener)\r
60             {\r
61                 m_listenerMap.insert(std::pair<jobject, std::pair<T*, int>>(jgListener, std::pair<T*, int>(onEventListener, 1)));\r
62             }\r
63             else\r
64             {\r
65                 LOGD("OnEventListener: Failed to create global listener ref.");\r
66                 delete onEventListener;\r
67             }\r
68             LOGD("OnEventListener: new listener");\r
69         }\r
70         m_mapMutex.unlock();\r
71         return onEventListener;\r
72     }\r
73 \r
74     void removeListener(JNIEnv* env, jobject jListener)\r
75     {\r
76         m_mapMutex.lock();\r
77         for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it)\r
78         {\r
79             if (env->IsSameObject(jListener, it->first))\r
80             {\r
81                 auto refPair = it->second;\r
82                 if (refPair.second > 1)\r
83                 {\r
84                     refPair.second--;\r
85                     it->second = refPair;\r
86                     m_listenerMap.insert(*it);\r
87                     LOGI("OnEventListener: ref. count is decremented");\r
88                 }\r
89                 else\r
90                 {\r
91                     env->DeleteGlobalRef(it->first);\r
92                     T* listener = refPair.first;\r
93                     delete listener;\r
94                     m_listenerMap.erase(it);\r
95 \r
96                     LOGI("OnEventListener is removed");\r
97                 }\r
98                 break;\r
99             }\r
100         }\r
101         m_mapMutex.unlock();\r
102     }\r
103 \r
104     void removeAllListeners(JNIEnv* env)\r
105     {\r
106         m_mapMutex.lock();\r
107 \r
108         for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it)\r
109         {\r
110             env->DeleteGlobalRef(it->first);\r
111             auto refPair = it->second;\r
112             T* listener = refPair.first;\r
113             delete listener;\r
114             m_listenerMap.erase(it);\r
115         }\r
116 \r
117         m_mapMutex.unlock();\r
118     }\r
119 \r
120 private:\r
121     std::map<jobject, std::pair<T*, int>> m_listenerMap;\r
122     std::mutex m_mapMutex;\r
123 };\r
124 \r
125 #endif\r