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