Update change log and spec for wrt-plugins-tizen_0.4.11
[framework/web/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 "Logger.h"
22 #include "JSUtil.h"
23
24 using namespace std;
25
26 namespace DeviceAPI {
27 namespace Common {
28
29 MultiCallbackUserData::MultiCallbackUserData(JSContextRef globalCtx): mContext(globalCtx), mObject(NULL){
30 }
31
32 MultiCallbackUserData::MultiCallbackUserData(JSContextRef globalCtx, JSObjectRef object): mContext(globalCtx), mObject(object){
33     if( mObject )
34         JSValueProtect(mContext, mObject);
35 }
36
37 MultiCallbackUserData::~MultiCallbackUserData(){
38     if( !GlobalContextManager::getInstance()->isAliveGlobalContext(mContext)){
39         //Remove Callback functions in Native Map
40         CallbackMapT::iterator itr;
41         for( itr = mCallbacks.begin() ; itr != mCallbacks.end() ; ++itr){
42             JSObjectRef t = itr->second;
43             if( t != NULL )
44                 JSValueUnprotect(mContext, t);
45         }
46
47         //Remove Callback Object
48         if( mObject ){
49             JSValueUnprotect(mContext, mObject);
50             mObject = NULL;
51         }
52     }
53 }
54
55 void MultiCallbackUserData::setCallback(const string &key, JSObjectRef callback){
56
57     // Callback Object Case
58     if( mObject ){
59         JSUtil::setProperty(mContext, mObject, key.c_str(), callback, kJSPropertyAttributeNone);
60         return;
61     }
62
63     // Callback function Case
64     CallbackMapT::iterator itr;
65     itr = mCallbacks.find(key);
66     if( itr != mCallbacks.end() && itr->second != NULL){
67         JSValueUnprotect(mContext, itr->second);
68     }
69     
70     if( callback != NULL ){
71         JSValueProtect(mContext, callback);
72     }
73     
74     mCallbacks[key] = callback;
75 }
76
77
78 void MultiCallbackUserData::invokeCallback(const std::string &key, int count, JSValueRef obj [ ]){
79     if( !GlobalContextManager::getInstance()->isAliveGlobalContext(mContext)){
80         LOGE("context was closed");
81         return;
82     }
83
84     // Callback Object case
85     if( mObject ){
86         try{
87             // Getting callback value
88             JSValueRef callbackValue = JSUtil::getProperty(mContext, mObject, key.c_str());
89
90             // Testing existing
91             if( JSValueIsUndefined(mContext, callbackValue) ){
92                 LOGE("There is no such callback[%s]", key.c_str());
93                 return;
94             }
95
96             JSObjectRef callbackObject = JSUtil::JSValueToObject(mContext, callbackValue);
97
98             // Testing type validation
99             if( !JSObjectIsFunction( mContext, callbackObject) ){
100                 LOGE("%s is not function", key.c_str());
101                 return;
102             }
103
104             JSValueRef exception = NULL;
105             JSObjectCallAsFunction(mContext, callbackObject, NULL, count, obj, &exception);
106
107             // check Exception in function call
108             if( exception != NULL ){
109                 throw UnknownException(mContext, exception);
110             }
111         }catch( const BasePlatformException& err){
112             LOGE("Error in Callback invoke - %s:%s", err.getName().c_str(), err.getMessage().c_str());
113         }
114         return;
115     }
116
117     // Callback function case
118     CallbackMapT::iterator itr;
119     itr = mCallbacks.find(key);
120     if( itr == mCallbacks.end()){
121         LOGE("There is no such callback[%s]", key.c_str());
122         return;
123     }
124     
125     if( itr->second ){
126         JSObjectCallAsFunction(mContext, itr->second , NULL, count, obj, NULL);
127     }else{
128         LOGE("The callback[%s] is NULL", key.c_str());
129     }
130 }
131
132 void MultiCallbackUserData::invokeCallback(const std::string &key, JSValueRef obj){
133     JSValueRef args[1] = {obj};
134     invokeCallback(key, 1, args);
135 }
136
137 void MultiCallbackUserData::invokeCallback(const std::string &key){
138     invokeCallback(key, 0, NULL);
139 }
140
141 JSContextRef MultiCallbackUserData::getContext(){
142     return mContext;
143 }
144
145 }
146 }
147