tizen 2.3 release
[framework/web/wearable/wrt-plugins-tizen.git] / src / Common / MultiCallbackUserData.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "MultiCallbackUserData.h"
19 #include "GlobalContextManager.h"
20 #include "PlatformException.h"
21 #include "WebKitProxy.h"
22 #include "JSUtil.h"
23 #include "Logger.h"
24
25 using namespace std;
26
27 namespace DeviceAPI {
28 namespace Common {
29
30 MultiCallbackUserData::MultiCallbackUserData(JSContextRef global_ctx) :
31         m_context(global_ctx),
32         m_object(NULL)
33 {
34 }
35
36 MultiCallbackUserData::MultiCallbackUserData(JSContextRef global_ctx,
37         JSObjectRef object) :
38     m_context(global_ctx),
39     m_object(object)
40 {
41     if(m_object) {
42         JSValueProtect(m_context, m_object);
43     }
44 }
45
46 MultiCallbackUserData::~MultiCallbackUserData()
47 {
48     if(!GlobalContextManager::getInstance()->isAliveGlobalContext(m_context)) {
49         //Remove Callback functions in Native Map
50         CallbackMapT::iterator itr;
51         for(itr = m_callbacks.begin(); itr != m_callbacks.end(); ++itr) {
52             if(itr->second) {
53                 JSValueUnprotect(m_context, itr->second);
54             }
55         }
56
57         //Remove Callback Object
58         if(m_object) {
59             JSValueUnprotect(m_context, m_object);
60         }
61     }
62 }
63
64 void MultiCallbackUserData::setCallback(const string &key, JSObjectRef callback)
65 {
66     // Callback Object Case
67     if(m_object) {
68         JSUtil::setProperty(m_context, m_object, key.c_str(), callback,
69                 kJSPropertyAttributeNone);
70         return;
71     }
72
73     // Callback function Case
74     CallbackMapT::iterator itr = m_callbacks.find(key);
75     if(itr != m_callbacks.end() && itr->second) {
76         JSValueUnprotect(m_context, itr->second);
77     }
78
79     if(callback) {
80         JSValueProtect(m_context, callback);
81     }
82
83     m_callbacks[key] = callback;
84 }
85
86
87 void MultiCallbackUserData::invokeCallback(const std::string &key, int count,
88         JSValueRef obj[])
89 {
90     if(!GlobalContextManager::getInstance()->isAliveGlobalContext(m_context)) {
91         LOGE("context was closed");
92         return;
93     }
94
95     // Callback Object case
96     if(m_object) {
97         try {
98             // Getting callback value
99             JSValueRef callbackValue = JSUtil::getProperty(m_context, m_object,
100                      key.c_str());
101
102             // Testing existing
103             if(JSValueIsUndefined(m_context, callbackValue)) {
104                 LOGE("There is no such callback: [%s]", key.c_str());
105                 return;
106             }
107
108             JSObjectRef callbackObject = JSUtil::JSValueToObject(m_context, callbackValue);
109
110             // Testing type validation
111             if(!JSObjectIsFunction(m_context, callbackObject)) {
112                 LOGE("[%s] is not function", key.c_str());
113                 return;
114             }
115
116             JSValueRef exception = NULL;
117             JSObjectCallAsFunction(m_context, callbackObject, NULL, count, obj,
118                      &exception);
119
120             if(exception){
121                 WebKitProxy::reportException(m_context, exception);
122             }
123             // check Exception in function call
124             if(exception != NULL) {
125                 throw UnknownException(m_context, exception);
126             }
127         } catch(const BasePlatformException& err) {
128             LOGE("Error in Callback invoke - %s:%s", err.getName().c_str(),
129                     err.getMessage().c_str());
130         }
131         return;
132     }
133
134     // Callback function case
135     CallbackMapT::iterator itr = m_callbacks.find(key);
136     if(itr == m_callbacks.end()) {
137         LOGE("There is no such callback: [%s]", key.c_str());
138         return;
139     }
140
141     if(itr->second) {
142         JSValueRef exception = NULL;
143         JSObjectCallAsFunction(m_context, itr->second , NULL, count, obj, &exception);
144         if(exception)
145             WebKitProxy::reportException(m_context, exception);
146     }
147     else {
148         LOGE("The callback: [%s] is NULL", key.c_str());
149     }
150 }
151
152 void MultiCallbackUserData::invokeCallback(const std::string &key, JSValueRef obj)
153 {
154     JSValueRef args[1] = {obj};
155     invokeCallback(key, 1, args);
156 }
157
158 void MultiCallbackUserData::invokeCallback(const std::string &key)
159 {
160     invokeCallback(key, 0, NULL);
161 }
162
163 JSContextRef MultiCallbackUserData::getContext() const
164 {
165     return m_context;
166 }
167
168 } // Common
169 } // DeviceAPI