e5168dda02ee8b4fa1fa01fbd15e087b9f257670
[platform/framework/web/wrt-plugins-tizen.git] / src / Bluetooth / JSBluetoothAdapter.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 <SecurityExceptions.h>
19
20 #include <JSUtil.h>
21 #include <ArgumentValidator.h>
22 #include <GlobalContextManager.h>
23
24 #include "plugin_config.h"
25 #include "JSBluetoothAdapter.h"
26 #include "BluetoothAdapter.h"
27 #include "JSBluetoothHealthProfileHandler.h"
28
29 #include <system_info.h>
30 #include <TimeTracer.h>
31 #include <Logger.h>
32
33 using namespace WrtDeviceApis::Commons;
34 using namespace DeviceAPI::Common;
35
36 namespace DeviceAPI {
37 namespace Bluetooth {
38
39 JSClassDefinition JSBluetoothAdapter::m_classInfo = {
40     0,
41     kJSClassAttributeNone,
42     "BluetoothAdapter",
43     NULL, //ParentClass
44     m_property, //StaticValues
45     m_function, //StaticFunctions
46     initialize, //Initialize
47     finalize, //Finalize
48     NULL, //HasProperty,
49     NULL, //GetProperty,
50     NULL, //SetProperty,
51     NULL, //DeleteProperty,
52     NULL, //GetPropertyNames,
53     NULL, //CallAsFunction,
54     NULL, //CallAsConstructor,
55     NULL, //HasInstance,
56     NULL //ConvertToType
57 };
58
59 JSStaticValue JSBluetoothAdapter::m_property[] = {
60     { BLUETOOTH_ADAPTER_NAME, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
61     { BLUETOOTH_ADAPTER_POWERED, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
62     { BLUETOOTH_ADAPTER_VISIBLE, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
63     { BLUETOOTH_ADAPTER_ADDRESS, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
64     { 0, 0, 0, 0 }
65 };
66
67 JSStaticFunction JSBluetoothAdapter::m_function[] = {
68     { BLUETOOTH_ADAPTER_API_SET_NAME, setName, kJSPropertyAttributeNone },
69     { BLUETOOTH_ADAPTER_API_SET_POWERED, setPowered, kJSPropertyAttributeNone },
70     { BLUETOOTH_ADAPTER_API_SET_VISIBLE, setVisible, kJSPropertyAttributeNone },
71     { BLUETOOTH_ADAPTER_API_DISCOVER_DEVICES, discoverDevices, kJSPropertyAttributeNone },
72     { BLUETOOTH_ADAPTER_API_STOP_DISCOVERY, stopDiscovery, kJSPropertyAttributeNone },
73     { BLUETOOTH_ADAPTER_API_GET_KNOWN_DEVICES, getKnownDevices, kJSPropertyAttributeNone },
74     { BLUETOOTH_ADAPTER_API_GET_DEVICE, getDevice, kJSPropertyAttributeNone },
75     { BLUETOOTH_ADAPTER_API_CREATE_BONDING, createBonding, kJSPropertyAttributeNone },
76     { BLUETOOTH_ADAPTER_API_DESTROY_BONDING, destroyBonding, kJSPropertyAttributeNone },
77     { BLUETOOTH_ADAPTER_API_REGISTER_RFCOMMSERVICE_BY_UUID, registerRFCOMMServiceByUUID, kJSPropertyAttributeNone },
78     { BLUETOOTH_ADAPTER_API_GET_BLUETOOTH_PROFILE_HANDLER, getBluetoothProfileHandler, kJSPropertyAttributeNone },
79     { BLUETOOTH_ADAPTER_API_SET_CHANGE_LISTENER, setChangeListener, kJSPropertyAttributeNone },
80     { BLUETOOTH_ADAPTER_API_UNSET_CHANGE_LISTENER, unsetChangeListener, kJSPropertyAttributeNone },
81     { 0, 0, 0 }
82 };
83
84 JSClassRef JSBluetoothAdapter::m_jsClassRef = JSClassCreate(JSBluetoothAdapter::getClassInfo());
85
86 const JSClassRef JSBluetoothAdapter::getClassRef()
87 {
88     if (!m_jsClassRef) {
89         m_jsClassRef = JSClassCreate(&m_classInfo);
90     }
91     return m_jsClassRef;
92 }
93
94 const JSClassDefinition* JSBluetoothAdapter::getClassInfo()
95 {
96     return &m_classInfo;
97 }
98
99 JSObjectRef JSBluetoothAdapter::createJSObject(JSContextRef context)
100 {
101     return JSObjectMake(context, getClassRef(), NULL);
102 }
103
104 void JSBluetoothAdapter::initialize(JSContextRef context, JSObjectRef object)
105 {
106     // do nothing
107 }
108
109
110 void JSBluetoothAdapter::finalize(JSObjectRef object)
111 {
112     // do nothing
113 }
114
115 JSValueRef JSBluetoothAdapter::getProperty(JSContextRef context,
116         JSObjectRef object,
117         JSStringRef propertyName,
118         JSValueRef* exception)
119 {
120     try {
121         if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_NAME)) {
122             std::string name = BluetoothAdapter::getInstance()->getName();
123             return JSUtil::toJSValueRef(context, name);
124         }
125         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_POWERED)) {
126             return JSUtil::toJSValueRef(context, BluetoothAdapter::getInstance()->getPowered());
127         }
128         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_VISIBLE)) {
129             return JSUtil::toJSValueRef(context, BluetoothAdapter::getInstance()->getVisible());
130         }
131         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_DEVICE_ADDRESS)) {
132             std::string address = BluetoothAdapter::getInstance()->getAddress();
133             return JSUtil::toJSValueRef(context, address);
134         }
135     } catch (const BasePlatformException &err) {
136         LoggerW("Getting property is failed" << err.getMessage().c_str());
137     }
138
139     return NULL;
140 }
141
142 JSValueRef JSBluetoothAdapter::setName(JSContextRef context,
143         JSObjectRef object,
144         JSObjectRef thisObject,
145         size_t argumentCount,
146         const JSValueRef arguments[],
147         JSValueRef* exception)
148 {
149     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
150     
151     // Access Check
152     TIME_TRACER_ITEM_BEGIN("setName::ACE", 1);
153     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_NAME);
154     TIME_TRACER_ITEM_END("setName::ACE", 1);
155     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
156
157     try {
158         ArgumentValidator validator(context, argumentCount, arguments);        
159         std::string name = validator.toString(0);  // name
160         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
161         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
162
163         // perform
164         MultiCallbackUserDataPtr callback(
165                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
166         if(!callback){
167             LoggerW("Can't create MultiCallbackUserData");
168         }
169         else {
170             callback->setCallback("success", successCallback);
171             callback->setCallback("error", errorCallback);
172         }      
173         
174         BluetoothAdapter::getInstance()->setName(name, callback);        
175         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
176         
177         return JSValueMakeUndefined(context);
178     } catch (const BasePlatformException &err) {
179         return JSWebAPIErrorFactory::postException(context, exception, err);
180     } catch (...) {
181         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setName().");
182         return JSWebAPIErrorFactory::postException(context, exception, err);
183     }
184 }
185
186 JSValueRef JSBluetoothAdapter::setPowered(JSContextRef context,
187         JSObjectRef object,
188         JSObjectRef thisObject,
189         size_t argumentCount,
190         const JSValueRef arguments[],
191         JSValueRef* exception)
192 {
193     LoggerD("Enter");
194     
195     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
196     
197     // Access Check
198     TIME_TRACER_ITEM_BEGIN("setPowered::ACE", 1);
199     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_POWERED);
200     TIME_TRACER_ITEM_END("setPowered::ACE", 1);
201     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
202
203     try {
204         // Check whether BT is supported or not
205         bool supported = false;
206         if(system_info_get_platform_bool("tizen.org/feature/network.bluetooth", &supported) != SYSTEM_INFO_ERROR_NONE) {
207             LoggerW("Can't check BT is supported or not");
208         }
209
210         if(supported == false) {
211             LoggerW("BT is not supported");        
212             throw DeviceAPI::Common::NotSupportedException("Bluetooth is not supported");
213         }
214         else {
215             LoggerD("BT is supported");
216         }
217         
218         // Validate arguments
219         ArgumentValidator validator(context, argumentCount, arguments);
220         bool state = validator.toBool(0);  // state
221         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
222         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
223
224         // perform
225         MultiCallbackUserDataPtr callback(
226                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
227         if(!callback){
228             LoggerW("Can't create MultiCallbackUserData");
229         }
230         else {
231             callback->setCallback("success", successCallback);
232             callback->setCallback("error", errorCallback);        
233         }
234         
235         BluetoothAdapter::getInstance()->setPowered(state, callback);
236         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
237         
238         return JSValueMakeUndefined(context);
239     } catch (const BasePlatformException &err) {
240         return JSWebAPIErrorFactory::postException(context, exception, err);
241     } catch (...) {
242         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setPowered().");
243         return JSWebAPIErrorFactory::postException(context, exception, err);
244     }
245 }
246
247 JSValueRef JSBluetoothAdapter::setVisible(JSContextRef context,
248         JSObjectRef object,
249         JSObjectRef thisObject,
250         size_t argumentCount,
251         const JSValueRef arguments[],
252         JSValueRef* exception)
253 {
254     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
255
256     // Access Check
257     TIME_TRACER_ITEM_BEGIN("setVisible::ACE", 1);    
258     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_VISIBLE);
259     TIME_TRACER_ITEM_END("setVisible::ACE", 1);    
260     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
261
262     try {    
263         // Validate arguments
264         ArgumentValidator validator(context, argumentCount, arguments);
265         bool mode = validator.toBool(0);  // mode
266         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
267         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
268         unsigned long timeout = validator.toULong(3, true, 180);  // timeout
269         if(timeout > 65535)
270             timeout = 180;
271
272         // perform
273         MultiCallbackUserDataPtr callback(
274                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
275         if(!callback){
276             LoggerW("Can't create MultiCallbackUserData");
277         }
278         else {
279             callback->setCallback("success", successCallback);
280             callback->setCallback("error", errorCallback);            
281         }
282         
283         BluetoothAdapter::getInstance()->setVisible(mode, timeout, callback);
284         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
285         
286         return JSValueMakeUndefined(context);
287     } catch (const BasePlatformException &err) {
288         return JSWebAPIErrorFactory::postException(context, exception, err);
289     } catch (...) {
290         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setVisible().");
291         return JSWebAPIErrorFactory::postException(context, exception, err);
292     }
293 }
294
295 JSValueRef JSBluetoothAdapter::discoverDevices(JSContextRef context,
296         JSObjectRef object,
297         JSObjectRef thisObject,
298         size_t argumentCount,
299         const JSValueRef arguments[],
300         JSValueRef* exception)
301 {
302     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
303
304     // Access Check
305     TIME_TRACER_ITEM_BEGIN("discoverDevices::ACE", 1);
306     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_DISCOVER_DEVICES);
307     TIME_TRACER_ITEM_END("discoverDevices::ACE", 1);
308     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
309
310     try {    
311         TIME_TRACER_ITEM_BEGIN("discoverDevices::parameter", 1);
312         
313         // Validate arguments
314         ArgumentValidator validator(context, argumentCount, arguments);
315
316         // successCallback
317         JSObjectRef successCallback = validator.toCallbackObject(0, false, "onstarted", "ondevicefound", "ondevicedisappeared", "onfinished", NULL);
318
319         // errorCallback
320         JSObjectRef errorCallback = validator.toFunction(1, true);
321
322         MultiCallbackUserDataPtr callback(
323                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
324         if(!callback){
325             LoggerW("Can't create MultiMultiCallbackUserData");
326         }
327         else {
328             // onstarted
329             JSValueRef onstartedValue = JSUtil::getProperty(context , successCallback, "onstarted");
330             if(!JSValueIsUndefined(context, onstartedValue)) {
331                 LoggerD("There is a onstarted()");
332                 callback->setCallback("onstarted", JSUtil::JSValueToObject(context, onstartedValue));
333             }
334             
335             // ondevicefound
336             JSValueRef ondevicefoundValue = JSUtil::getProperty(context , successCallback, "ondevicefound");
337             if(!JSValueIsUndefined(context, ondevicefoundValue)) {
338                 LoggerD("There is a ondevicefound()");
339                 callback->setCallback("ondevicefound", JSUtil::JSValueToObject(context, ondevicefoundValue));
340             }
341             
342             // ondevicedisappeared
343             JSValueRef ondevicedisappearedValue = JSUtil::getProperty(context , successCallback, "ondevicedisappeared");
344             if(!JSValueIsUndefined(context, ondevicedisappearedValue)) {
345                 LoggerD("There is a ondevicedisappeared()");
346                 callback->setCallback("ondevicedisappeared", JSUtil::JSValueToObject(context, ondevicedisappearedValue));
347             }
348             
349             // onfinished
350             JSValueRef onfinishedValue = JSUtil::getProperty(context , successCallback, "onfinished");
351             if(!JSValueIsUndefined(context, onfinishedValue)) {
352                 LoggerD("There is a onfinished()");
353                 callback->setCallback("onfinished", JSUtil::JSValueToObject(context, onfinishedValue));
354             }      
355             
356             callback->setCallback("error", errorCallback);        
357         }
358         TIME_TRACER_ITEM_END("discoverDevices::parameter", 1);
359         
360         // perform       
361         BluetoothAdapter::getInstance()->discoverDevices(callback);
362         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
363         
364         return JSValueMakeUndefined(context);
365     } catch (const BasePlatformException &err) {
366         return JSWebAPIErrorFactory::postException(context, exception, err);
367     } catch (...) {
368         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.discoverDevices().");
369         return JSWebAPIErrorFactory::postException(context, exception, err);
370     }
371 }
372
373 JSValueRef JSBluetoothAdapter::stopDiscovery(JSContextRef context,
374         JSObjectRef object,
375         JSObjectRef thisObject,
376         size_t argumentCount,
377         const JSValueRef arguments[],
378         JSValueRef* exception)
379 {
380     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
381
382     // Access Check
383     TIME_TRACER_ITEM_BEGIN("stopDiscovery::ACE", 1);
384     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_STOP_DISCOVERY);
385     TIME_TRACER_ITEM_END("stopDiscovery::ACE", 1);
386     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
387
388     try {
389         // Validate arguments
390         ArgumentValidator validator(context, argumentCount, arguments);
391         JSObjectRef successCallback = validator.toFunction(0, true);  // successCallback  
392         JSObjectRef errorCallback = validator.toFunction(1, true);  // errorCallback
393
394         // perform
395         MultiCallbackUserDataPtr callback(
396                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
397         if(!callback){
398             LoggerW("Can't create MultiCallbackUserData");
399         }
400         else {
401             callback->setCallback("success", successCallback);
402             callback->setCallback("error", errorCallback);        
403         }
404         
405         BluetoothAdapter::getInstance()->stopDiscovery(callback);
406         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
407
408         return JSValueMakeUndefined(context);
409     } catch (const BasePlatformException &err) {
410         return JSWebAPIErrorFactory::postException(context, exception, err);
411     } catch (...) {
412         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.stopDiscovery().");
413         return JSWebAPIErrorFactory::postException(context, exception, err);
414     }
415 }
416
417 JSValueRef JSBluetoothAdapter::getKnownDevices(JSContextRef context,
418         JSObjectRef object,
419         JSObjectRef thisObject,
420         size_t argumentCount,
421         const JSValueRef arguments[],
422         JSValueRef* exception)
423 {
424     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
425
426     // Access Check
427     TIME_TRACER_ITEM_BEGIN("getKnownDevices::ACE", 1);
428     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_GET_KNOWN_DEVICES);
429     TIME_TRACER_ITEM_END("getKnownDevices::ACE", 1);
430     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
431
432     try {
433         // Validate arguments
434         ArgumentValidator validator(context, argumentCount, arguments);
435         JSObjectRef successCallback = validator.toFunction(0);  // successCallback  
436         JSObjectRef errorCallback = validator.toFunction(1, true);  // errorCallback
437
438         // perform
439         MultiCallbackUserDataPtr callback(
440                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
441         if(!callback){
442             LoggerW("Can't create MultiCallbackUserData");
443         }
444         else {
445             callback->setCallback("success", successCallback);
446             callback->setCallback("error", errorCallback);        
447         }
448         
449         BluetoothAdapter::getInstance()->getKnownDevices(callback);
450         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
451         
452         return JSValueMakeUndefined(context);
453     } catch (const BasePlatformException &err) {
454         return JSWebAPIErrorFactory::postException(context, exception, err);
455     } catch (...) {
456         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.getKnownDevices().");
457         return JSWebAPIErrorFactory::postException(context, exception, err);
458     }
459 }
460
461 JSValueRef JSBluetoothAdapter::getDevice(JSContextRef context,
462         JSObjectRef object,
463         JSObjectRef thisObject,
464         size_t argumentCount,
465         const JSValueRef arguments[],
466         JSValueRef* exception)
467 {
468     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
469
470     // Access Check
471     TIME_TRACER_ITEM_BEGIN("getDevice::ACE", 1);
472     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_GET_DEVICE);
473     TIME_TRACER_ITEM_END("getDevice::ACE", 1);
474     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
475
476     try {
477         // Validate arguments
478         ArgumentValidator validator(context, argumentCount, arguments);
479         std::string address = validator.toString(0);  // address
480         JSObjectRef successCallback = validator.toFunction(1);  // successCallback  
481         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
482
483         // perform
484         MultiCallbackUserDataPtr callback(
485                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
486         if(!callback){
487             LoggerW("Can't create MultiCallbackUserData");
488         }
489         else {
490             callback->setCallback("success", successCallback);
491             callback->setCallback("error", errorCallback);        
492         }
493         
494         BluetoothAdapter::getInstance()->getDevice(address, callback);
495         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
496         
497         return JSValueMakeUndefined(context);
498     } catch (const BasePlatformException &err) {
499         return JSWebAPIErrorFactory::postException(context, exception, err);
500     } catch (...) {
501         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.getDevice().");
502         return JSWebAPIErrorFactory::postException(context, exception, err);
503     }
504 }
505
506 JSValueRef JSBluetoothAdapter::createBonding(JSContextRef context,
507         JSObjectRef object,
508         JSObjectRef thisObject,
509         size_t argumentCount,
510         const JSValueRef arguments[],
511         JSValueRef* exception)
512 {
513     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
514
515     // Access Check
516     TIME_TRACER_ITEM_BEGIN("createBonding::ACE", 1);
517     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_CREATE_BONDING);
518     TIME_TRACER_ITEM_END("createBonding::ACE", 1);
519     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
520
521     try {
522         // Validate arguments
523         ArgumentValidator validator(context, argumentCount, arguments);
524         std::string address = validator.toString(0);  // address
525         JSObjectRef successCallback = validator.toFunction(1);  // successCallback  
526         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
527
528         // perform
529         MultiCallbackUserDataPtr callback(
530                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
531         if(!callback){
532             LoggerW("Can't create MultiCallbackUserData");
533         }
534         else {
535             callback->setCallback("success", successCallback);
536             callback->setCallback("error", errorCallback);        
537         }
538         
539         BluetoothAdapter::getInstance()->createBonding(address, callback);
540         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
541         
542         return JSValueMakeUndefined(context);
543     } catch (const BasePlatformException &err) {
544         return JSWebAPIErrorFactory::postException(context, exception, err);
545     } catch (...) {
546         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.createBonding().");
547         return JSWebAPIErrorFactory::postException(context, exception, err);
548     }
549 }
550
551 JSValueRef JSBluetoothAdapter::destroyBonding(JSContextRef context,
552         JSObjectRef object,
553         JSObjectRef thisObject,
554         size_t argumentCount,
555         const JSValueRef arguments[],
556         JSValueRef* exception)
557 {
558     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
559
560     // Access Check
561     TIME_TRACER_ITEM_BEGIN("destroyBonding::ACE", 1);
562     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_DESTROY_BONDING);
563     TIME_TRACER_ITEM_END("destroyBonding::ACE", 1);
564     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
565
566     try {
567         // Validate arguments
568         ArgumentValidator validator(context, argumentCount, arguments);
569         std::string address = validator.toString(0);  // address
570         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
571         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
572
573         // perform
574         MultiCallbackUserDataPtr callback(
575                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
576         if(!callback){
577             LoggerW("Can't create MultiCallbackUserData");
578         }
579         else {
580             callback->setCallback("success", successCallback);
581             callback->setCallback("error", errorCallback);        
582         }
583         
584         BluetoothAdapter::getInstance()->destroyBonding(address, callback);
585         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
586         
587         return JSValueMakeUndefined(context);
588     } catch (const BasePlatformException &err) {
589         return JSWebAPIErrorFactory::postException(context, exception, err);
590     } catch (...) {
591         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.destroyBonding().");
592         return JSWebAPIErrorFactory::postException(context, exception, err);
593     }
594 }
595
596 JSValueRef JSBluetoothAdapter::registerRFCOMMServiceByUUID(JSContextRef context,
597         JSObjectRef object,
598         JSObjectRef thisObject,
599         size_t argumentCount,
600         const JSValueRef arguments[],
601         JSValueRef* exception)
602 {
603     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
604
605     // Access Check
606     TIME_TRACER_ITEM_BEGIN("registerRFCOMMServiceByUUID::ACE", 1);
607     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_REGISTER_RFCOMMSERVICE_BY_UUID);
608     TIME_TRACER_ITEM_END("registerRFCOMMServiceByUUID::ACE", 1);
609     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
610
611     try {
612         // Validate arguments
613         ArgumentValidator validator(context, argumentCount, arguments);
614         std::string uuid = validator.toString(0);  // uuid
615         std::string name = validator.toString(1);  // name
616         JSObjectRef successCallback = validator.toFunction(2);  // successCallback  
617         JSObjectRef errorCallback = validator.toFunction(3, true);  // errorCallback
618
619         // perform
620         MultiCallbackUserDataPtr callback(
621                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
622         if(!callback){
623             LoggerW("Can't create MultiCallbackUserData");
624         }
625         else {
626             callback->setCallback("success", successCallback);
627             callback->setCallback("error", errorCallback);        
628         }
629         
630         BluetoothAdapter::getInstance()->registerRFCOMMServiceByUUID(uuid, name, callback);
631         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
632         
633         return JSValueMakeUndefined(context);
634     } catch (const BasePlatformException &err) {
635         return JSWebAPIErrorFactory::postException(context, exception, err);
636     } catch (...) {
637         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.registerRFCOMMServiceByUUID().");
638         return JSWebAPIErrorFactory::postException(context, exception, err);
639     }
640 }
641
642 JSValueRef JSBluetoothAdapter::getBluetoothProfileHandler(JSContextRef context,
643         JSObjectRef object,
644         JSObjectRef thisObject,
645         size_t argumentCount,
646         const JSValueRef arguments[],
647         JSValueRef* exception)
648 {
649     LoggerD("Enter");
650     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
651     
652     try {
653         // Validate arguments
654         ArgumentValidator validator(context, argumentCount, arguments);
655         std::string type = validator.toString(0);  // profileType
656
657         // perform
658         JSObjectRef profileHandler;
659         bool isCorrectParameter = false;
660         if(type.compare("HEALTH") == 0) {
661             isCorrectParameter = true;
662             profileHandler = JSBluetoothHealthProfileHandler::createJSObject(context);
663         }
664         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
665
666         if(!isCorrectParameter) {
667             throw TypeMismatchException("Type Mismatch");
668         }
669         
670         return profileHandler;
671     } catch (const BasePlatformException &err) {
672         return JSWebAPIErrorFactory::postException(context, exception, err);
673     } catch (...) {
674         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.registerRFCOMMServiceByUUID().");
675         return JSWebAPIErrorFactory::postException(context, exception, err);
676     }    
677 }
678
679 JSValueRef JSBluetoothAdapter::setChangeListener(JSContextRef context,
680         JSObjectRef object,
681         JSObjectRef thisObject,
682         size_t argumentCount,
683         const JSValueRef arguments[],
684         JSValueRef* exception)
685 {
686     LoggerD("Enter");
687     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
688
689     try {
690         // Validate arguments
691         ArgumentValidator validator(context, argumentCount, arguments);        
692         JSObjectRef changeCallbackObj = validator.toCallbackObject(0, false, "onstatechanged", "onnamechanged", "onvisibilitychanged", NULL);
693
694         MultiCallbackUserDataPtr callback(
695                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
696         if(!callback){
697             LoggerW("Can't create MultiMultiCallbackUserData");
698         }
699         else {
700             // onstatechanged
701             JSValueRef onstatechangedValue = JSUtil::getProperty(context , changeCallbackObj, "onstatechanged");
702             if(!JSValueIsUndefined(context, onstatechangedValue)) {
703                 LoggerD("There is a onstatechanged()");
704                 callback->setCallback("onstatechanged", JSUtil::JSValueToObject(context, onstatechangedValue));
705             }
706             
707             // onnamechanged
708             JSValueRef onnamechangedValue = JSUtil::getProperty(context , changeCallbackObj, "onnamechanged");
709             if(!JSValueIsUndefined(context, onnamechangedValue)) {
710                 LoggerD("There is a onnamechanged()");
711                 callback->setCallback("onnamechanged", JSUtil::JSValueToObject(context, onnamechangedValue));
712             }
713             
714             // onvisibilitychanged
715             JSValueRef onvisibilitychangedValue = JSUtil::getProperty(context , changeCallbackObj, "onvisibilitychanged");
716             if(!JSValueIsUndefined(context, onvisibilitychangedValue)) {
717                 LoggerD("There is a onvisibilitychanged()");
718                 callback->setCallback("onvisibilitychanged", JSUtil::JSValueToObject(context, onvisibilitychangedValue));
719             }
720         }
721
722         // perform
723         BluetoothAdapter::getInstance()->setChangeListener(callback);
724         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
725         
726         return JSValueMakeUndefined(context);
727     } catch (const BasePlatformException &err) {
728         return JSWebAPIErrorFactory::postException(context, exception, err);
729     } catch (...) {
730         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.registerRFCOMMServiceByUUID().");
731         return JSWebAPIErrorFactory::postException(context, exception, err);
732     }    
733 }
734
735 JSValueRef JSBluetoothAdapter::unsetChangeListener(JSContextRef context,
736         JSObjectRef object,
737         JSObjectRef thisObject,
738         size_t argumentCount,
739         const JSValueRef arguments[],
740         JSValueRef* exception)
741 {
742     LoggerD("Enter");
743     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 1);
744
745     try {
746         // perform
747         BluetoothAdapter::getInstance()->unsetChangeListener();
748         TIME_TRACER_ITEM_END(__FUNCTION__, 1);
749         
750         return JSValueMakeUndefined(context);
751     } catch (const BasePlatformException &err) {
752         return JSWebAPIErrorFactory::postException(context, exception, err);
753     } catch (...) {
754         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.registerRFCOMMServiceByUUID().");
755         return JSWebAPIErrorFactory::postException(context, exception, err);
756     }    
757 }
758
759
760 } // Bluetooth
761 } // DeviceAPI