2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <SecurityExceptions.h>
21 #include <ArgumentValidator.h>
22 #include <GlobalContextManager.h>
24 #include "plugin_config.h"
25 #include "JSBluetoothAdapter.h"
26 #include "BluetoothAdapter.h"
28 #include <TimeTracer.h>
31 using namespace WrtDeviceApis::Commons;
32 using namespace DeviceAPI::Common;
37 JSClassDefinition JSBluetoothAdapter::m_classInfo = {
39 kJSClassAttributeNone,
42 m_property, //StaticValues
43 m_function, //StaticFunctions
44 initialize, //Initialize
49 NULL, //DeleteProperty,
50 NULL, //GetPropertyNames,
51 NULL, //CallAsFunction,
52 NULL, //CallAsConstructor,
57 JSStaticValue JSBluetoothAdapter::m_property[] = {
58 { BLUETOOTH_ADAPTER_NAME, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
59 { BLUETOOTH_ADAPTER_POWERED, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
60 { BLUETOOTH_ADAPTER_VISIBLE, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
61 { BLUETOOTH_ADAPTER_ADDRESS, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
65 JSStaticFunction JSBluetoothAdapter::m_function[] = {
66 { BLUETOOTH_ADAPTER_API_SET_NAME, setName, kJSPropertyAttributeNone },
67 { BLUETOOTH_ADAPTER_API_SET_POWERED, setPowered, kJSPropertyAttributeNone },
68 { BLUETOOTH_ADAPTER_API_SET_VISIBLE, setVisible, kJSPropertyAttributeNone },
69 { BLUETOOTH_ADAPTER_API_DISCOVER_DEVICES, discoverDevices, kJSPropertyAttributeNone },
70 { BLUETOOTH_ADAPTER_API_STOP_DISCOVERY, stopDiscovery, kJSPropertyAttributeNone },
71 { BLUETOOTH_ADAPTER_API_GET_KNOWN_DEVICES, getKnownDevices, kJSPropertyAttributeNone },
72 { BLUETOOTH_ADAPTER_API_GET_DEVICE, getDevice, kJSPropertyAttributeNone },
73 { BLUETOOTH_ADAPTER_API_CREATE_BONDING, createBonding, kJSPropertyAttributeNone },
74 { BLUETOOTH_ADAPTER_API_DESTROY_BONDING, destroyBonding, kJSPropertyAttributeNone },
75 { BLUETOOTH_ADAPTER_API_REGISTER_RFCOMMSERVICE_BY_UUID, registerRFCOMMServiceByUUID, kJSPropertyAttributeNone },
79 JSClassRef JSBluetoothAdapter::m_jsClassRef = JSClassCreate(JSBluetoothAdapter::getClassInfo());
81 const JSClassRef JSBluetoothAdapter::getClassRef()
84 m_jsClassRef = JSClassCreate(&m_classInfo);
89 const JSClassDefinition* JSBluetoothAdapter::getClassInfo()
94 JSObjectRef JSBluetoothAdapter::createJSObject(JSContextRef context)
96 return JSObjectMake(context, getClassRef(), NULL);
99 void JSBluetoothAdapter::initialize(JSContextRef context, JSObjectRef object)
105 void JSBluetoothAdapter::finalize(JSObjectRef object)
110 JSValueRef JSBluetoothAdapter::getProperty(JSContextRef context,
112 JSStringRef propertyName,
113 JSValueRef* exception)
116 if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_NAME)) {
117 std::string name = BluetoothAdapter::getInstance()->getName();
118 return JSUtil::toJSValueRef(context, name);
120 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_POWERED)) {
121 return JSUtil::toJSValueRef(context, BluetoothAdapter::getInstance()->getPowered());
123 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_VISIBLE)) {
124 return JSUtil::toJSValueRef(context, BluetoothAdapter::getInstance()->getVisible());
126 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_DEVICE_ADDRESS)) {
127 std::string address = BluetoothAdapter::getInstance()->getAddress();
128 return JSUtil::toJSValueRef(context, address);
130 } catch (const BasePlatformException &err) {
131 LoggerW("Getting property is failed" << err.getMessage().c_str());
137 JSValueRef JSBluetoothAdapter::setName(JSContextRef context,
139 JSObjectRef thisObject,
140 size_t argumentCount,
141 const JSValueRef arguments[],
142 JSValueRef* exception)
144 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
147 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_NAME);
148 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
151 ArgumentValidator validator(context, argumentCount, arguments);
152 std::string name = validator.toString(0); // name
153 JSObjectRef successCallback = validator.toFunction(1, true); // successCallback
154 JSObjectRef errorCallback = validator.toFunction(2, true); // errorCallback
157 MultiCallbackUserDataPtr callback(
158 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
160 LoggerW("Can't create MultiCallbackUserData");
163 callback->setCallback("success", successCallback);
164 callback->setCallback("error", errorCallback);
167 BluetoothAdapter::getInstance()->setName(name, callback);
168 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
170 return JSValueMakeUndefined(context);
171 } catch (const BasePlatformException &err) {
172 return JSWebAPIErrorFactory::postException(context, exception, err);
174 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setName().");
175 return JSWebAPIErrorFactory::postException(context, exception, err);
179 JSValueRef JSBluetoothAdapter::setPowered(JSContextRef context,
181 JSObjectRef thisObject,
182 size_t argumentCount,
183 const JSValueRef arguments[],
184 JSValueRef* exception)
186 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
189 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_POWERED);
190 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
193 // Validate arguments
194 ArgumentValidator validator(context, argumentCount, arguments);
195 bool state = validator.toBool(0); // state
196 JSObjectRef successCallback = validator.toFunction(1, true); // successCallback
197 JSObjectRef errorCallback = validator.toFunction(2, true); // errorCallback
200 MultiCallbackUserDataPtr callback(
201 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
203 LoggerW("Can't create MultiCallbackUserData");
206 callback->setCallback("success", successCallback);
207 callback->setCallback("error", errorCallback);
210 BluetoothAdapter::getInstance()->setPowered(state, callback);
211 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
213 return JSValueMakeUndefined(context);
214 } catch (const BasePlatformException &err) {
215 return JSWebAPIErrorFactory::postException(context, exception, err);
217 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setPowered().");
218 return JSWebAPIErrorFactory::postException(context, exception, err);
222 JSValueRef JSBluetoothAdapter::setVisible(JSContextRef context,
224 JSObjectRef thisObject,
225 size_t argumentCount,
226 const JSValueRef arguments[],
227 JSValueRef* exception)
229 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
232 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_VISIBLE);
233 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
236 // Validate arguments
237 ArgumentValidator validator(context, argumentCount, arguments);
238 bool mode = validator.toBool(0); // mode
239 JSObjectRef successCallback = validator.toFunction(1, true); // successCallback
240 JSObjectRef errorCallback = validator.toFunction(2, true); // errorCallback
241 unsigned long timeout = validator.toULong(3, true); // timeout
246 MultiCallbackUserDataPtr callback(
247 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
249 LoggerW("Can't create MultiCallbackUserData");
252 callback->setCallback("success", successCallback);
253 callback->setCallback("error", errorCallback);
256 BluetoothAdapter::getInstance()->setVisible(mode, timeout, callback);
257 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
259 return JSValueMakeUndefined(context);
260 } catch (const BasePlatformException &err) {
261 return JSWebAPIErrorFactory::postException(context, exception, err);
263 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setVisible().");
264 return JSWebAPIErrorFactory::postException(context, exception, err);
268 JSValueRef JSBluetoothAdapter::discoverDevices(JSContextRef context,
270 JSObjectRef thisObject,
271 size_t argumentCount,
272 const JSValueRef arguments[],
273 JSValueRef* exception)
275 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
278 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_DISCOVER_DEVICES);
279 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
282 // Validate arguments
283 ArgumentValidator validator(context, argumentCount, arguments);
286 JSObjectRef successCallback = validator.toCallbackObject(0, false, "onstarted", "ondevicefound", "ondevicedisappeared", "onfinished", NULL);
289 JSObjectRef errorCallback = validator.toFunction(1, true);
291 MultiCallbackUserDataPtr callback(
292 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
294 LoggerW("Can't create MultiMultiCallbackUserData");
298 JSValueRef onstartedValue = JSUtil::getProperty(context , successCallback, "onstarted");
299 if(!JSValueIsUndefined(context, onstartedValue)) {
300 LoggerD("There is a onstarted()");
301 callback->setCallback("onstarted", JSUtil::JSValueToObject(context, onstartedValue));
305 JSValueRef ondevicefoundValue = JSUtil::getProperty(context , successCallback, "ondevicefound");
306 if(!JSValueIsUndefined(context, ondevicefoundValue)) {
307 LoggerD("There is a ondevicefound()");
308 callback->setCallback("ondevicefound", JSUtil::JSValueToObject(context, ondevicefoundValue));
311 // ondevicedisappeared
312 JSValueRef ondevicedisappearedValue = JSUtil::getProperty(context , successCallback, "ondevicedisappeared");
313 if(!JSValueIsUndefined(context, ondevicedisappearedValue)) {
314 LoggerD("There is a ondevicedisappeared()");
315 callback->setCallback("ondevicedisappeared", JSUtil::JSValueToObject(context, ondevicedisappearedValue));
319 JSValueRef onfinishedValue = JSUtil::getProperty(context , successCallback, "onfinished");
320 if(!JSValueIsUndefined(context, onfinishedValue)) {
321 LoggerD("There is a onfinished()");
322 callback->setCallback("onfinished", JSUtil::JSValueToObject(context, onfinishedValue));
325 callback->setCallback("error", errorCallback);
329 BluetoothAdapter::getInstance()->discoverDevices(callback);
330 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
332 return JSValueMakeUndefined(context);
333 } catch (const BasePlatformException &err) {
334 return JSWebAPIErrorFactory::postException(context, exception, err);
336 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.discoverDevices().");
337 return JSWebAPIErrorFactory::postException(context, exception, err);
341 JSValueRef JSBluetoothAdapter::stopDiscovery(JSContextRef context,
343 JSObjectRef thisObject,
344 size_t argumentCount,
345 const JSValueRef arguments[],
346 JSValueRef* exception)
348 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
351 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_STOP_DISCOVERY);
352 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
355 // Validate arguments
356 ArgumentValidator validator(context, argumentCount, arguments);
357 JSObjectRef successCallback = validator.toFunction(0, true); // successCallback
358 JSObjectRef errorCallback = validator.toFunction(1, true); // errorCallback
361 MultiCallbackUserDataPtr callback(
362 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
364 LoggerW("Can't create MultiCallbackUserData");
367 callback->setCallback("success", successCallback);
368 callback->setCallback("error", errorCallback);
371 BluetoothAdapter::getInstance()->stopDiscovery(callback);
372 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
374 return JSValueMakeUndefined(context);
375 } catch (const BasePlatformException &err) {
376 return JSWebAPIErrorFactory::postException(context, exception, err);
378 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.stopDiscovery().");
379 return JSWebAPIErrorFactory::postException(context, exception, err);
383 JSValueRef JSBluetoothAdapter::getKnownDevices(JSContextRef context,
385 JSObjectRef thisObject,
386 size_t argumentCount,
387 const JSValueRef arguments[],
388 JSValueRef* exception)
390 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
393 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_GET_KNOWN_DEVICES);
394 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
397 // Validate arguments
398 ArgumentValidator validator(context, argumentCount, arguments);
399 JSObjectRef successCallback = validator.toFunction(0); // successCallback
400 JSObjectRef errorCallback = validator.toFunction(1, true); // errorCallback
403 MultiCallbackUserDataPtr callback(
404 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
406 LoggerW("Can't create MultiCallbackUserData");
409 callback->setCallback("success", successCallback);
410 callback->setCallback("error", errorCallback);
413 BluetoothAdapter::getInstance()->getKnownDevices(callback);
414 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
416 return JSValueMakeUndefined(context);
417 } catch (const BasePlatformException &err) {
418 return JSWebAPIErrorFactory::postException(context, exception, err);
420 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.getKnownDevices().");
421 return JSWebAPIErrorFactory::postException(context, exception, err);
425 JSValueRef JSBluetoothAdapter::getDevice(JSContextRef context,
427 JSObjectRef thisObject,
428 size_t argumentCount,
429 const JSValueRef arguments[],
430 JSValueRef* exception)
432 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
435 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_GET_DEVICE);
436 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
439 // Validate arguments
440 ArgumentValidator validator(context, argumentCount, arguments);
441 std::string address = validator.toString(0); // address
442 JSObjectRef successCallback = validator.toFunction(1); // successCallback
443 JSObjectRef errorCallback = validator.toFunction(2, true); // errorCallback
446 MultiCallbackUserDataPtr callback(
447 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
449 LoggerW("Can't create MultiCallbackUserData");
452 callback->setCallback("success", successCallback);
453 callback->setCallback("error", errorCallback);
456 BluetoothAdapter::getInstance()->getDevice(address, callback);
457 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
459 return JSValueMakeUndefined(context);
460 } catch (const BasePlatformException &err) {
461 return JSWebAPIErrorFactory::postException(context, exception, err);
463 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.getDevice().");
464 return JSWebAPIErrorFactory::postException(context, exception, err);
468 JSValueRef JSBluetoothAdapter::createBonding(JSContextRef context,
470 JSObjectRef thisObject,
471 size_t argumentCount,
472 const JSValueRef arguments[],
473 JSValueRef* exception)
475 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
478 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_CREATE_BONDING);
479 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
482 // Validate arguments
483 ArgumentValidator validator(context, argumentCount, arguments);
484 std::string address = validator.toString(0); // address
485 JSObjectRef successCallback = validator.toFunction(1); // successCallback
486 JSObjectRef errorCallback = validator.toFunction(2, true); // errorCallback
489 MultiCallbackUserDataPtr callback(
490 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
492 LoggerW("Can't create MultiCallbackUserData");
495 callback->setCallback("success", successCallback);
496 callback->setCallback("error", errorCallback);
499 BluetoothAdapter::getInstance()->createBonding(address, callback);
500 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
502 return JSValueMakeUndefined(context);
503 } catch (const BasePlatformException &err) {
504 return JSWebAPIErrorFactory::postException(context, exception, err);
506 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.createBonding().");
507 return JSWebAPIErrorFactory::postException(context, exception, err);
511 JSValueRef JSBluetoothAdapter::destroyBonding(JSContextRef context,
513 JSObjectRef thisObject,
514 size_t argumentCount,
515 const JSValueRef arguments[],
516 JSValueRef* exception)
518 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
521 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_DESTROY_BONDING);
522 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
525 // Validate arguments
526 ArgumentValidator validator(context, argumentCount, arguments);
527 std::string address = validator.toString(0); // address
528 JSObjectRef successCallback = validator.toFunction(1, true); // successCallback
529 JSObjectRef errorCallback = validator.toFunction(2, true); // errorCallback
532 MultiCallbackUserDataPtr callback(
533 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
535 LoggerW("Can't create MultiCallbackUserData");
538 callback->setCallback("success", successCallback);
539 callback->setCallback("error", errorCallback);
542 BluetoothAdapter::getInstance()->destroyBonding(address, callback);
543 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
545 return JSValueMakeUndefined(context);
546 } catch (const BasePlatformException &err) {
547 return JSWebAPIErrorFactory::postException(context, exception, err);
549 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.destroyBonding().");
550 return JSWebAPIErrorFactory::postException(context, exception, err);
554 JSValueRef JSBluetoothAdapter::registerRFCOMMServiceByUUID(JSContextRef context,
556 JSObjectRef thisObject,
557 size_t argumentCount,
558 const JSValueRef arguments[],
559 JSValueRef* exception)
561 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
564 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_REGISTER_RFCOMMSERVICE_BY_UUID);
565 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
568 // Validate arguments
569 ArgumentValidator validator(context, argumentCount, arguments);
570 std::string uuid = validator.toString(0); // uuid
571 std::string name = validator.toString(1); // name
572 JSObjectRef successCallback = validator.toFunction(2); // successCallback
573 JSObjectRef errorCallback = validator.toFunction(3, true); // errorCallback
576 MultiCallbackUserDataPtr callback(
577 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
579 LoggerW("Can't create MultiCallbackUserData");
582 callback->setCallback("success", successCallback);
583 callback->setCallback("error", errorCallback);
586 BluetoothAdapter::getInstance()->registerRFCOMMServiceByUUID(uuid, name, callback);
587 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
589 return JSValueMakeUndefined(context);
590 } catch (const BasePlatformException &err) {
591 return JSWebAPIErrorFactory::postException(context, exception, err);
593 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.registerRFCOMMServiceByUUID().");
594 return JSWebAPIErrorFactory::postException(context, exception, err);