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 <CommonsJavaScript/Validator.h>
19 #include <Commons/Exception.h>
20 #include <CommonsJavaScript/PrivateObject.h>
21 #include <CommonsJavaScript/JSUtils.h>
22 #include <CommonsJavaScript/JSCallbackManager.h>
23 #include <CommonsJavaScript/Utils.h>
24 #include <JSWebAPIErrorFactory.h>
25 #include <SecurityExceptions.h>
26 #include <ArgumentValidator.h>
27 #include <GlobalContextManager.h>
28 #include <PlatformException.h>
30 #include "JSNFCTarget.h"
31 #include "JSNFCManager.h"
32 #include "JSNdefMessage.h"
33 #include "NFCConverter.h"
34 #include "ResponseDispatcher.h"
35 #include "NFCAsyncCallbackManager.h"
36 #include "NFCListenerManager.h"
37 #include "NFCFactory.h"
38 #include "EventTargetAction.h"
39 #include "plugin_config_impl.h"
43 using namespace DeviceAPI::Common;
44 using namespace WrtDeviceApis::Commons;
45 using namespace WrtDeviceApis::CommonsJavaScript;
48 #define TIZEN_NFCTARGET_ATTRIBUTENAME "NFCTarget"
50 #define TIZEN_NFCTARGET_ISCONNECTED "isConnected"
55 JSClassDefinition JSNFCTarget::m_classInfo =
58 kJSClassAttributeNone,
59 TIZEN_NFCTARGET_ATTRIBUTENAME,
68 NULL, //DeleteProperty,
69 NULL, //GetPropertyNames,
70 NULL, //CallAsFunction,
71 NULL, //CallAsConstructor,
72 hasInstance, //HasInstance,
76 JSStaticValue JSNFCTarget::m_property[] =
79 { TIZEN_NFCTARGET_ISCONNECTED, getProperty,
80 NULL, kJSPropertyAttributeReadOnly},
84 JSStaticFunction JSNFCTarget::m_function[] = {
85 {"setReceiveNDEFListener", JSNFCTarget::setReceiveNDEFListener, kJSPropertyAttributeNone},
86 {"unsetReceiveNDEFListener", JSNFCTarget::unsetReceiveNDEFListener, kJSPropertyAttributeNone},
87 {"sendNDEF", JSNFCTarget::sendNDEF, kJSPropertyAttributeNone},
91 JSClassRef JSNFCTarget::m_jsClassRef = JSClassCreate(JSNFCTarget::getClassInfo());
93 JSObjectRef JSNFCTarget::createJSObject(JSContextRef context, void *tagHandle, EventNFCChangedPrivateDataPtr eventNFCChangedPriv) {
96 INFCTargetPtr nfcTarget = NFCFactory::getInstance().createNFCTargetObject(tagHandle);
98 NFCTargetPrivObject *priv = new NFCTargetPrivObject(context, nfcTarget);
101 ThrowMsg(NullPointerException, "Can not new a NFCTarget object");
104 priv->copyAceCheckAccessFunction(eventNFCChangedPriv.Get());
105 return JSObjectMake(context, getClassRef(), priv);
108 void JSNFCTarget::initialize(JSContextRef context, JSObjectRef object)
112 void JSNFCTarget::finalize(JSObjectRef object)
114 LoggerD( "entered" );
115 NFCTargetPrivObject *priv = static_cast<NFCTargetPrivObject*>( JSObjectGetPrivate( object ) ) ;
116 JSObjectSetPrivate(object, NULL);
117 LoggerD("Deleting timezone object");
122 const JSClassRef JSNFCTarget::getClassRef()
125 m_jsClassRef = JSClassCreate(&m_classInfo);
130 const JSClassDefinition* JSNFCTarget::getClassInfo()
135 JSValueRef JSNFCTarget::getProperty(JSContextRef context, JSObjectRef object,
136 JSStringRef propertyName, JSValueRef* exception)
141 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTARGET_ISCONNECTED)) {
142 NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(object));
143 if (!privateObject) {
144 LoggerE("Private object is not set.");
145 ThrowMsg(NullPointerException, "Private object not initialized");
148 INFCTargetPtr nfcTarget(privateObject->getObject());
149 NFCConverter convert(context);
150 return convert.toJSValueRef(nfcTarget->isConnected());
152 } Catch (ConversionException) {
153 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
154 } Catch (NullPointerException) {
155 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
156 } Catch (WrtDeviceApis::Commons::UnknownException) {
157 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
158 } Catch (PlatformException) {
159 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
160 } Catch (WrtDeviceApis::Commons::Exception) {
161 LoggerE("Exception: " << _rethrown_exception.GetMessage());
163 return JSValueMakeUndefined(context);
166 bool JSNFCTarget::hasInstance(JSContextRef context,
167 JSObjectRef constructor,
168 JSValueRef possibleInstance,
169 JSValueRef* exception)
171 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
174 JSValueRef JSNFCTarget::setReceiveNDEFListener(JSContextRef context,
176 JSObjectRef thisObject,
177 size_t argumentCount,
178 const JSValueRef arguments[],
179 JSValueRef* exception)
183 NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(thisObject));
184 if (NULL == privateObject) {
185 LoggerE("private object is null");
186 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
189 TIZEN_CHECK_ACCESS(context, exception, privateObject,
190 NFC_FUNCTION_API_P2P_FUNCS);
193 ArgumentValidator validator(context, argumentCount, arguments);
194 JSValueRef onSuccessForCbm = NULL;
195 // NDEFMessageReadCallback
196 if (validator.toFunction(0))
197 onSuccessForCbm = arguments[0];
199 JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
200 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, onSuccessForCbm, NULL, true, true);
202 EventTargetActionReceiveEmitterPtr emitter(new EventTargetActionReceiveEmitter);
203 emitter->setListener(&NFCResponseDispatcher::getInstance());
204 emitter->setEventPrivateData(DPL::StaticPointerCast<EventTargetActionReceive::PrivateDataType>(callbackManager));
205 INFCTargetPtr nfcTarget(privateObject->getObject());
206 nfcTarget->setReceiveNDEFListener(emitter);
208 NFCListenerCancellerPtr canceller = NFCListenerCancellerPtr(new NFCListenerCanceller(global_context, thisObject, static_cast<long>(ID_NFCPEER_RECEIVENDEF_LISTENER)));
209 IListenerItemPtr listenerItem = DPL::StaticPointerCast<IListenerItem>(canceller);
210 NFCListenerManagerSingleton::Instance().registerListener(listenerItem, global_context);
212 return JSValueMakeUndefined(context);
213 } Catch (BasePlatformException) {
214 LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
215 return JSWebAPIErrorFactory::postException(context, exception, _rethrown_exception);
216 } Catch (ConversionException) {
217 LoggerE("setReceiveNDEFListener : ConversionException");
218 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
219 } Catch (PlatformException) {
220 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
221 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR, "Service Not Available");
222 } Catch (WrtDeviceApis::Commons::UnknownException) {
223 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
224 } Catch (WrtDeviceApis::Commons::Exception) {
225 LoggerE("Exception: " << _rethrown_exception.GetMessage());
228 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
231 JSValueRef JSNFCTarget::unsetReceiveNDEFListener(JSContextRef context,
233 JSObjectRef thisObject,
234 size_t argumentCount,
235 const JSValueRef arguments[],
236 JSValueRef* exception)
240 NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(thisObject));
241 if (NULL == privateObject) {
242 LoggerE("private object is null");
243 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
246 TIZEN_CHECK_ACCESS(context, exception, privateObject,
247 NFC_FUNCTION_API_P2P_FUNCS);
249 INFCTargetPtr nfcTarget(privateObject->getObject());
250 nfcTarget->unsetReceiveNDEFListener();
252 JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
253 NFCListenerCancellerPtr canceller = NFCListenerCancellerPtr(new NFCListenerCanceller(global_context, thisObject, static_cast<long>(ID_NFCPEER_RECEIVENDEF_LISTENER)));
254 IListenerItemPtr listenerItem = DPL::StaticPointerCast<IListenerItem>(canceller);
255 NFCListenerManagerSingleton::Instance().unregisterListener(listenerItem);
257 return JSValueMakeUndefined(context);
258 } Catch (WrtDeviceApis::Commons::UnknownException) {
259 LoggerE("Exception: " << _rethrown_exception.GetMessage());
260 } Catch(NullPointerException) {
261 LoggerE("Exception: " << _rethrown_exception.GetMessage());
262 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
263 } Catch (PlatformException) {
264 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
265 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR, "Service Not Available");
266 } Catch (WrtDeviceApis::Commons::Exception) {
267 LoggerE("Exception: " << _rethrown_exception.GetMessage());
270 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
273 JSValueRef JSNFCTarget::sendNDEF(JSContextRef context,
275 JSObjectRef thisObject,
276 size_t argumentCount,
277 const JSValueRef arguments[],
278 JSValueRef* exception)
282 NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(thisObject));
283 if (NULL == privateObject) {
284 LoggerE("private object is null");
285 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
288 TIZEN_CHECK_ACCESS(context, exception, privateObject,
289 NFC_FUNCTION_API_P2P_FUNCS);
291 JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
293 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, NULL, NULL, true, true);
295 ArgumentValidator validator(context, argumentCount, arguments);
298 JSObjectRef ndefMessageObj = validator.toObject(0, JSNdefMessage::getClassRef());
300 if (validator.toFunction(1, true))
301 callbackManager->setOnSuccess(arguments[1]);
303 if (validator.toFunction(2, true))
304 callbackManager->setOnError(arguments[2]);
306 void *messageHandle = NULL;
308 NdefMessagePrivObject* ndefMessagePrivateObj = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(ndefMessageObj));
309 if (!ndefMessagePrivateObj) {
310 LogError("NDEF Message Private object is not set.");
311 ThrowMsg(ConversionException, "Private object is not set");
313 INdefMessagePtr ndefMessage(ndefMessagePrivateObj->getObject());
314 JSValueRef recordsValue = (ndefMessage->mLocalProperty).getProperty(global_context, TIZEN_NDEFMESSAGE_RECORDS);
315 NFCConverter convert(global_context);
316 std::vector<void *> records = convert.toVectorOfRecordHandles(recordsValue);
317 messageHandle = ndefMessage->makeNdefMessageHandle(records);
318 } catch (WrtDeviceApis::Commons::Exception& err) {
319 LoggerE(err.GetClassName() << ":"<<err.GetMessage());
320 ThrowMsg(InvalidArgumentException, "Invalid NDEF Message");
322 if (messageHandle == NULL)
323 ThrowMsg(InvalidArgumentException, "Invalid NDEF Message");
325 EventTargetActionSendPtr event(new EventTargetActionSend(messageHandle));
326 callbackManager->setObject(thisObject);
327 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
328 event->setForAsynchronousCall(&NFCResponseDispatcher::getInstance());
329 INFCTargetPtr nfcTarget(privateObject->getObject());
330 nfcTarget->sendNDEF(event);
331 NFCAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, global_context);
332 return JSValueMakeUndefined(context);
333 } Catch (BasePlatformException) {
334 LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
335 return JSWebAPIErrorFactory::postException(context, exception, _rethrown_exception);
336 } Catch (ConversionException) {
337 LoggerE("sendNDEF : ConversionException");
338 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
339 } Catch (InvalidArgumentException) {
340 LoggerE("sendNDEF InvalidArgumentException");
341 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, _rethrown_exception.GetMessage()));
342 return JSValueMakeUndefined(context);
343 } Catch (PlatformException) {
344 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
345 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR, "Service Not Available"));
346 return JSValueMakeUndefined(context);
347 } Catch (WrtDeviceApis::Commons::UnknownException) {
348 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
349 } Catch (WrtDeviceApis::Commons::Exception) {
350 LoggerE("Exception: " << _rethrown_exception.GetMessage());
353 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR,"Unknown Error"));
354 return JSValueMakeUndefined(context);