Update change log and spec for wrt-plugins-tizen_0.4.70
[framework/web/wrt-plugins-tizen.git] / src / Bluetooth / JSBluetoothHealthChannel.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 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 <vector>
19
20 #include <SecurityExceptions.h>
21 #include <JSUtil.h>
22 #include <ArgumentValidator.h>
23 #include <GlobalContextManager.h>
24 #include <PlatformException.h>
25 #include <MultiCallbackUserData.h>
26
27 #include "plugin_config.h"
28 #include "JSBluetoothHealthChannel.h"
29 #include "BluetoothHealthProfileHandler.h"
30
31 #include <TimeTracer.h>
32 #include <Logger.h>
33
34 using namespace WrtDeviceApis::Commons;
35 using namespace DeviceAPI::Common;
36
37 namespace DeviceAPI {
38 namespace Bluetooth {
39
40 JSClassDefinition JSBluetoothHealthChannel::m_classInfo = {
41     0,
42     kJSClassAttributeNone,
43     "BluetoothHealthChannel",
44     NULL, //ParentClass
45     m_property, //StaticValues
46     m_function, //StaticFunctions
47     initialize, //Initialize
48     finalize, //Finalize
49     NULL, //HasProperty,
50     NULL, //GetProperty,
51     NULL, //SetProperty,
52     NULL, //DeleteProperty,
53     NULL, //GetPropertyNames,
54     NULL, //CallAsFunction,
55     NULL, //CallAsConstructor,
56     NULL, //HasInstance,
57     NULL //ConvertToType
58 };
59
60 JSStaticValue JSBluetoothHealthChannel::m_property[] = {
61     { BLUETOOTH_HEALTH_CHANNEL_PEER, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
62     { BLUETOOTH_HEALTH_CHANNEL_TYPE, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
63     { BLUETOOTH_HEALTH_CHANNEL_APP, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
64     { BLUETOOTH_HEALTH_CHANNEL_IS_CONNECTED, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeDontDelete },
65     { 0, 0, 0, 0 }
66 };
67
68 JSStaticFunction JSBluetoothHealthChannel::m_function[] = {
69     { BLUETOOTH_HEALTH_CHANNEL_API_SEND_DATA, sendData, kJSPropertyAttributeNone },
70     { "close", close, kJSPropertyAttributeNone },
71     { BLUETOOTH_HEALTH_CHANNEL_API_SET_LISTENER, setListener, kJSPropertyAttributeNone },
72     { BLUETOOTH_HEALTH_CHANNEL_API_UNSET_LISTENER, unsetListener, kJSPropertyAttributeNone },    
73     { 0, 0, 0 }
74 };
75
76 JSClassRef JSBluetoothHealthChannel::m_jsClassRef = JSClassCreate(JSBluetoothHealthChannel::getClassInfo());
77
78 const JSClassRef JSBluetoothHealthChannel::getClassRef()
79 {
80     if (!m_jsClassRef) {
81         m_jsClassRef = JSClassCreate(&m_classInfo);
82     }
83     return m_jsClassRef;
84 }
85
86 const JSClassDefinition* JSBluetoothHealthChannel::getClassInfo()
87 {
88     return &m_classInfo;
89 }
90
91 JSObjectRef JSBluetoothHealthChannel::createJSObject(JSContextRef context, BluetoothHealthChannelPtr channel)
92 {
93     return JSObjectMake(context, getClassRef(), static_cast<void*>(channel));
94 }
95
96 void JSBluetoothHealthChannel::initialize(JSContextRef context, JSObjectRef object)
97 {
98     // do nothing
99 }
100
101 void JSBluetoothHealthChannel::finalize(JSObjectRef object)
102 {
103     BluetoothHealthChannelPtr priv = static_cast<BluetoothHealthChannelPtr>(JSObjectGetPrivate(object));
104     if (priv) {
105         JSObjectSetPrivate(object, NULL);
106         delete priv;
107     }
108 }
109
110 JSValueRef JSBluetoothHealthChannel::getProperty(JSContextRef context,
111         JSObjectRef object,
112         JSStringRef propertyName,
113         JSValueRef* exception)
114 {
115     try {
116         BluetoothHealthChannelPtr priv = static_cast<BluetoothHealthChannelPtr>(JSObjectGetPrivate(object));
117         if (!priv) {
118             throw TypeMismatchException("Private object is NULL");
119         }
120
121         if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_HEALTH_CHANNEL_PEER)) {
122             return priv->getPeer(context);
123         }
124         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_HEALTH_CHANNEL_TYPE)) {
125             return JSUtil::toJSValueRef(context, priv->getChannelTypeStr());
126         }
127         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_HEALTH_CHANNEL_APP)) {
128             return priv->getApp(context);
129         }
130         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_HEALTH_CHANNEL_IS_CONNECTED)) {
131             return JSUtil::toJSValueRef(context, priv->getConnectionState());
132         }
133     } catch (const BasePlatformException &err) {
134         LoggerW("Getting property is failed: " << err.getMessage().c_str());
135     }
136
137     return NULL;
138 }
139
140 JSValueRef JSBluetoothHealthChannel::sendData(JSContextRef context,
141         JSObjectRef object,
142         JSObjectRef thisObject,
143         size_t argumentCount,
144         const JSValueRef arguments[],
145         JSValueRef* exception)
146 {
147     LoggerD("Enter");
148
149     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);;
150
151     try {
152         // Private Object
153         BluetoothHealthChannelPtr priv = static_cast<BluetoothHealthChannelPtr>(JSObjectGetPrivate(thisObject));
154         if (!priv) {
155             throw DeviceAPI::Common::UnknownException("Private object is NULL.");
156         }
157             // Access Check
158             TIME_TRACER_ITEM_BEGIN("sendData::ACE", 1);;
159                 TIZEN_CHECK_ACCESS(context, exception, priv, BLUETOOTH_HEALTH_CHANNEL_API_SEND_DATA);           
160             TIME_TRACER_ITEM_END("sendData::ACE", 1);;
161         
162         ArgumentValidator validator(context, argumentCount, arguments);
163
164         JSObjectRef dataArrayObj  = validator.toArrayObject(0);  // data
165         size_t size = JSGetArrayLength(context, dataArrayObj);
166         char *buffer = new char[size];
167         for(size_t i = 0; i < size; ++i) {
168             JSValueRef element = JSGetArrayElement(context, dataArrayObj, i);
169             buffer[i] = static_cast<char>(JSUtil::JSValueToByte(context, element));
170         }
171
172         JSValueRef result = JSUtil::toJSValueRef(context, priv->sendData(buffer, size));
173         delete buffer;
174         TIME_TRACER_ITEM_END(__FUNCTION__, 1);;
175
176         return result;
177     } catch (const BasePlatformException &err) {
178         return JSWebAPIErrorFactory::postException(context, exception, err);
179     } catch (...) {
180         DeviceAPI::Common::UnknownException err("Unknown Error");
181         return JSWebAPIErrorFactory::postException(context, exception, err);
182     }
183 }
184
185 JSValueRef JSBluetoothHealthChannel::close(JSContextRef context,
186         JSObjectRef object,
187         JSObjectRef thisObject,
188         size_t argumentCount,
189         const JSValueRef arguments[],
190         JSValueRef* exception)
191 {
192     LoggerD("Enter");
193
194     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
195     
196
197
198     try {
199         // Private Object
200         BluetoothHealthChannelPtr priv = static_cast<BluetoothHealthChannelPtr>(JSObjectGetPrivate(thisObject));
201         if (!priv) {
202             throw DeviceAPI::Common::UnknownException("Private object is NULL.");
203         }
204             // Access Check
205             TIME_TRACER_ITEM_BEGIN("close::ACE", 1);;
206                 TIZEN_CHECK_ACCESS(context, exception, priv, BLUETOOTH_HEALTH_CHANNEL_API_CLOSE);
207             TIME_TRACER_ITEM_END("close::ACE", 1);;
208
209         priv->close();
210         TIME_TRACER_ITEM_END(__FUNCTION__, 1);;
211         
212         return JSValueMakeUndefined(context);
213     } catch (const BasePlatformException &err) {
214         return JSWebAPIErrorFactory::postException(context, exception, err);
215     } catch (...) {
216         DeviceAPI::Common::UnknownException err("Unknown Error");
217         return JSWebAPIErrorFactory::postException(context, exception, err);
218     }
219 }
220
221 JSValueRef JSBluetoothHealthChannel::setListener(JSContextRef context,
222         JSObjectRef object,
223         JSObjectRef thisObject,
224         size_t argumentCount,
225         const JSValueRef arguments[],
226         JSValueRef* exception)
227 {
228     LoggerD("Enter");
229
230     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);;
231     
232
233
234     try {
235         // Private Object
236         BluetoothHealthChannelPtr priv = static_cast<BluetoothHealthChannelPtr>(JSObjectGetPrivate(thisObject));
237         if (!priv) {
238             throw DeviceAPI::Common::UnknownException("Private object is NULL.");
239         }
240
241                 // Access Check
242                 TIME_TRACER_ITEM_BEGIN("setListener::ACE", 1);;
243                 TIZEN_CHECK_ACCESS(context, exception, priv, BLUETOOTH_HEALTH_CHANNEL_API_SET_LISTENER);
244                 TIME_TRACER_ITEM_END("setListener::ACE", 1);;
245                 
246
247         // Validate arguments
248         ArgumentValidator validator(context, argumentCount, arguments);
249
250         // successCallback
251         JSObjectRef successCallback = validator.toCallbackObject(0, false, "onmessage", "onclose", NULL);
252
253         MultiCallbackUserDataPtr callback(
254                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
255         if(!callback){
256             LoggerW("Can't create MultiMultiCallbackUserData");
257         }
258         else {
259             // onmessage
260             JSValueRef onmessageValue = JSUtil::getProperty(context , successCallback, "onmessage");
261             if(!JSValueIsUndefined(context, onmessageValue)) {
262                 LoggerD("There is a onmessage()");
263                 callback->setCallback("onmessage", JSUtil::JSValueToObject(context, onmessageValue));
264             }
265             
266             // onclose
267             JSValueRef oncloseValue = JSUtil::getProperty(context , successCallback, "onclose");
268             if(!JSValueIsUndefined(context, oncloseValue)) {
269                 LoggerD("There is a onclose()");
270                 callback->setCallback("onclose", JSUtil::JSValueToObject(context, oncloseValue));
271             }
272         }
273
274         priv->setListener(callback);
275         TIME_TRACER_ITEM_END(__FUNCTION__, 1);;
276         
277         return JSValueMakeUndefined(context);
278     } catch (const BasePlatformException &err) {
279         return JSWebAPIErrorFactory::postException(context, exception, err);
280     } catch (...) {
281         DeviceAPI::Common::UnknownException err("Unknown Error");
282         return JSWebAPIErrorFactory::postException(context, exception, err);
283     }
284 }
285
286 JSValueRef JSBluetoothHealthChannel::unsetListener(JSContextRef context,
287         JSObjectRef object,
288         JSObjectRef thisObject,
289         size_t argumentCount,
290         const JSValueRef arguments[],
291         JSValueRef* exception)
292 {
293     LoggerD("Enter");
294
295     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);;
296     
297
298     try {
299         // Private Object
300         BluetoothHealthChannelPtr priv = static_cast<BluetoothHealthChannelPtr>(JSObjectGetPrivate(thisObject));
301         if (!priv) {
302             throw DeviceAPI::Common::UnknownException("Private object is NULL.");
303         }
304                 // Access Check
305                 TIME_TRACER_ITEM_BEGIN("unsetListener::ACE", 1);
306                 TIZEN_CHECK_ACCESS(context, exception, priv, BLUETOOTH_HEALTH_CHANNEL_API_UNSET_LISTENER);
307                 TIME_TRACER_ITEM_END("unsetListener::ACE", 1);
308
309
310         priv->unsetListener();
311         TIME_TRACER_ITEM_END(__FUNCTION__, 1);;
312         
313         return JSValueMakeUndefined(context);
314     } catch (const BasePlatformException &err) {
315         return JSWebAPIErrorFactory::postException(context, exception, err);
316     } catch (...) {
317         DeviceAPI::Common::UnknownException err("Unknown Error");
318         return JSWebAPIErrorFactory::postException(context, exception, err);
319     }
320 }
321
322
323
324 } // Bluetooth
325 } // DeviceAPI