wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / NFC / JSNFCTag.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. 
15  */
16
17 #include <CommonsJavaScript/Validator.h>
18 #include <Commons/Exception.h>
19 #include <CommonsJavaScript/PrivateObject.h>
20 #include <CommonsJavaScript/JSUtils.h>
21 #include <CommonsJavaScript/JSCallbackManager.h>
22 #include <CommonsJavaScript/Utils.h>
23 #include <JSTizenExceptionFactory.h>
24 #include <JSTizenException.h>
25 #include <SecurityExceptions.h>
26 #include <ArgumentValidator.h>
27 #include <GlobalContextManager.h>
28 #include <JSWebAPIException.h>
29 #include <PlatformException.h>
30
31 #include "JSNFCTag.h"
32 #include "JSNdefMessage.h"
33 #include "JSNFCManager.h"
34 #include "NFCConverter.h"
35 #include "ResponseDispatcher.h"
36 #include "NFCFactory.h"
37 #include "EventTagAction.h"
38 #include "NFCAsyncCallbackManager.h"
39 #include "plugin_config.h"
40 #include <Logger.h>
41
42 using namespace DeviceAPI::Common;
43 using namespace WrtDeviceApis::Commons;
44 using namespace WrtDeviceApis::CommonsJavaScript;
45 using namespace DPL;
46
47 #define TIZEN_NFCTAG_ATTRIBUTENAME "NFCTag"
48
49 #define TIZEN_NFCTAG_TYPE "type"
50 #define TIZEN_NFCTAG_ISSUPPORTEDNDEF "isSupportedNDEF"
51 #define TIZEN_NFCTAG_NDEFSIZE "ndefSize"
52 #define TIZEN_NFCTAG_PROPERTIES "properties"
53 #define TIZEN_NFCTAG_ISCONNECTED "isConnected"
54
55 namespace DeviceAPI {
56 namespace NFC {
57
58  JSClassDefinition JSNFCTag::m_classInfo =
59 {
60     0,
61     kJSClassAttributeNone,
62     TIZEN_NFCTAG_ATTRIBUTENAME,
63     0,
64     m_property,
65     m_function,
66     initialize,
67     finalize,
68     NULL, //hasProperty,
69     NULL,
70     NULL, //setProperty,
71     NULL, //DeleteProperty,
72     NULL, //GetPropertyNames,
73     NULL, //CallAsFunction,
74     NULL, //CallAsConstructor,
75     hasInstance, //HasInstance,
76     NULL  //ConvertToType
77 };
78
79 JSStaticValue JSNFCTag::m_property[] =
80 {
81     //NFCTagProperties
82     { TIZEN_NFCTAG_TYPE, getProperty, 
83             NULL, kJSPropertyAttributeReadOnly},
84     { TIZEN_NFCTAG_ISSUPPORTEDNDEF, getProperty, 
85             NULL, kJSPropertyAttributeReadOnly},
86     { TIZEN_NFCTAG_NDEFSIZE, getProperty, 
87             NULL, kJSPropertyAttributeReadOnly},
88     { TIZEN_NFCTAG_PROPERTIES, getProperty, 
89             NULL, kJSPropertyAttributeReadOnly},
90     { TIZEN_NFCTAG_ISCONNECTED, getProperty, 
91             NULL, kJSPropertyAttributeReadOnly},
92     { 0, 0, 0, 0 }
93 };
94
95 JSStaticFunction JSNFCTag::m_function[] = {
96     {"readNDEF", JSNFCTag::readNDEF, kJSPropertyAttributeNone},
97     {"writeNDEF", JSNFCTag::writeNDEF, kJSPropertyAttributeNone},
98     {"transceive", JSNFCTag::transceive, kJSPropertyAttributeNone},
99     { 0, 0, 0}
100 };
101
102 JSClassRef JSNFCTag::m_jsClassRef = JSClassCreate(JSNFCTag::getClassInfo());
103
104 JSObjectRef JSNFCTag::createJSObject(JSContextRef context, void *tagHandle) {
105         LoggerD("entered");
106
107         INFCTagPtr nfcTag = NFCFactory::getInstance().createNFCTagObject(tagHandle);
108         
109         NFCTagPrivObject *priv = new NFCTagPrivObject(context, nfcTag);
110
111         if (!priv) {
112                 ThrowMsg(NullPointerException, "Can not new a NFCTag object");
113         }
114
115         return JSObjectMake(context, getClassRef(), priv);
116 }
117
118 void JSNFCTag::initialize(JSContextRef context, JSObjectRef object)
119 {
120 }
121
122 void JSNFCTag::finalize(JSObjectRef object)
123 {
124         LoggerD( "entered" );
125         NFCTagPrivObject *priv = static_cast<NFCTagPrivObject*>( JSObjectGetPrivate( object ) ) ;
126         JSObjectSetPrivate(object, NULL);
127         LoggerD("Deleting NFCTag object");
128         delete priv;
129 }
130
131
132 const JSClassRef JSNFCTag::getClassRef()
133 {
134         if (!m_jsClassRef) {
135                 m_jsClassRef = JSClassCreate(&m_classInfo);
136         }
137         return m_jsClassRef;
138 }
139
140 const JSClassDefinition* JSNFCTag::getClassInfo()
141 {
142         return &m_classInfo;
143 }
144
145 JSValueRef JSNFCTag::getProperty(JSContextRef context, JSObjectRef object,
146         JSStringRef propertyName, JSValueRef* exception)
147 {
148         LoggerD("Enter");
149
150         Try     {
151                 NFCTagPrivObject* privateObject = static_cast<NFCTagPrivObject*>(JSObjectGetPrivate(object));
152                 if (!privateObject) {
153                         LoggerE("Private object is not set.");
154                         ThrowMsg(NullPointerException, "Private object not initialized");
155                 }
156
157                 INFCTagPtr nfcTag(privateObject->getObject());
158                 NFCConverter convert(context);
159
160                 LoggerD("propertyName : " << convert.toString(propertyName));
161                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTAG_TYPE)) {
162                         return convert.toJSValueRef(convert.toNfcTagTypeString(nfcTag->getTagType()));
163                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTAG_ISSUPPORTEDNDEF)) {
164                         return convert.toJSValueRef(nfcTag->isNDEFSupport());
165                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTAG_NDEFSIZE)) {
166                         return convert.toJSValueRefLong(nfcTag->getNdefSize());
167                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTAG_PROPERTIES)) {
168                         LoggerD("get Properties");
169                         return convert.toJSValueRef(nfcTag->getProperties());
170                 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTAG_ISCONNECTED)) {
171                         return convert.toJSValueRef(nfcTag->isConnected());
172                 }
173         } Catch (NullPointerException) {
174                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
175         } Catch (ConversionException) {
176                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
177         } Catch (WrtDeviceApis::Commons::UnknownException) {
178                 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
179         } Catch (PlatformException) {
180                 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
181         } Catch (WrtDeviceApis::Commons::Exception) {
182                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
183         }
184         return JSValueMakeUndefined(context);
185 }
186
187 bool JSNFCTag::hasInstance(JSContextRef context,
188         JSObjectRef constructor,
189         JSValueRef possibleInstance,
190         JSValueRef* exception)
191 {
192     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
193 }
194
195 JSValueRef JSNFCTag::readNDEF(JSContextRef context,
196         JSObjectRef object,
197         JSObjectRef thisObject,
198         size_t argumentCount,
199         const JSValueRef arguments[],
200         JSValueRef* exception)
201 {
202         LoggerD("Entered ");
203
204         AceSecurityStatus status = NFC_CHECK_ACCESS(NFC_FUNCTION_API_TAG_FUNCS);
205         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
206
207         JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
208
209         NFCTagPrivObject* privateObject = static_cast<NFCTagPrivObject*>(JSObjectGetPrivate(thisObject));
210         if (NULL == privateObject) {
211                 LoggerE("private object is null");
212                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
213         }
214
215         INFCTagPtr nfcTag(privateObject->getObject());
216     JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, NULL, NULL, true, true);
217
218         Try {
219                 ArgumentValidator validator(context, argumentCount, arguments);
220
221                 // successCallback
222                 if (validator.toFunction(0))
223                         callbackManager->setOnSuccess(arguments[0]);
224                 // errorCallback
225                 if (validator.toFunction(1, true))
226                         callbackManager->setOnError(arguments[1]);
227
228                 EventTagActionReadPtr event(new EventTagActionRead());
229                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
230                 event->setForAsynchronousCall(&NFCResponseDispatcher::getInstance());
231
232                 nfcTag->readNdef(event);
233                 NFCAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, global_context);
234                 return JSValueMakeUndefined(context);
235     } Catch (BasePlatformException) {
236         LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
237         return JSWebAPIException::throwException(context, exception, _rethrown_exception);
238         } Catch (ConversionException) {
239                 LoggerE("readNDEF : ConversionException");
240                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
241         } Catch (UnsupportedException) {
242                 LoggerE("UnsupportedException: " << _rethrown_exception.GetMessage());
243                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, "Not Support NDEF");
244         } Catch (InvalidArgumentException) {
245                 LoggerE("readNDEF InvalidArgumentException");
246                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values"));
247                 return JSValueMakeUndefined(context);
248         } Catch (PlatformException) {
249                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
250                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available"));
251                 return JSValueMakeUndefined(context);
252         } Catch (WrtDeviceApis::Commons::UnknownException) {
253                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
254         } Catch (WrtDeviceApis::Commons::Exception) {
255                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
256         }
257
258         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
259         return JSValueMakeUndefined(context);
260 }
261
262 JSValueRef JSNFCTag::writeNDEF(JSContextRef context,
263         JSObjectRef object,
264         JSObjectRef thisObject,
265         size_t argumentCount,
266         const JSValueRef arguments[],
267         JSValueRef* exception)
268 {
269         LoggerD("Entered ");
270
271         AceSecurityStatus status = NFC_CHECK_ACCESS(NFC_FUNCTION_API_TAG_FUNCS);
272         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
273
274         JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
275
276         NFCTagPrivObject* privateObject = static_cast<NFCTagPrivObject*>(JSObjectGetPrivate(thisObject));
277         if (NULL == privateObject) {
278                 LoggerE("private object is null");
279                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
280         }
281
282         INFCTagPtr nfcTag(privateObject->getObject());
283         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, NULL, NULL, true, true);
284         Try {
285                 ArgumentValidator validator(context, argumentCount, arguments);
286
287                 // ndefMessage
288                 JSObjectRef ndefMessageObj = validator.toObject(0, JSNdefMessage::getClassRef(), false);
289                 // successCallback
290                 if (validator.toFunction(1, true))
291                         callbackManager->setOnSuccess(arguments[1]);
292                 // errorCallback
293                 if (validator.toFunction(2, true))
294                         callbackManager->setOnError(arguments[2]);
295
296                 EventTagActionWritePtr event(new EventTagActionWrite());
297                 NFCConverter convert(context);
298                 void *messageHandle = convert.copiedMessage(ndefMessageObj);
299                 event->writeNdef(messageHandle);
300                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager));
301                 event->setForAsynchronousCall(&NFCResponseDispatcher::getInstance());
302                 nfcTag->writeNdef(event);
303                 NFCAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, global_context);
304                 return JSValueMakeUndefined(context);
305     } Catch (BasePlatformException) {
306         LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
307         return JSWebAPIException::throwException(context, exception, _rethrown_exception);
308         } Catch (ConversionException) {
309                 LoggerE("writeNDEF : ConversionException");
310                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
311         } Catch (UnsupportedException) {
312                 LoggerE("UnsupportedException: " << _rethrown_exception.GetMessage());
313                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_SUPPORTED_ERROR, "Not Support NDEF");
314         } Catch (InvalidArgumentException) {
315                 LoggerE("writeNDEF InvalidArgumentException");
316                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values"));
317                 return JSValueMakeUndefined(context);
318         } Catch (PlatformException) {
319                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
320                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available"));
321                 return JSValueMakeUndefined(context);
322         } Catch (WrtDeviceApis::Commons::UnknownException) {
323                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
324         } Catch (WrtDeviceApis::Commons::Exception) {
325                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
326         }
327
328         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
329         return JSValueMakeUndefined(context);
330 }
331
332 JSValueRef JSNFCTag::transceive(JSContextRef context,
333         JSObjectRef object,
334         JSObjectRef thisObject,
335         size_t argumentCount,
336         const JSValueRef arguments[],
337         JSValueRef* exception)
338 {
339         LoggerD("Entered ");
340
341         AceSecurityStatus status = NFC_CHECK_ACCESS(NFC_FUNCTION_API_TAG_FUNCS);
342         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
343
344         JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
345
346         NFCTagPrivObject* privateObject = static_cast<NFCTagPrivObject*>(JSObjectGetPrivate(thisObject));
347         if (NULL == privateObject) {
348                 LoggerE("private object is null");
349                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
350         }
351
352         INFCTagPtr nfcTag(privateObject->getObject());
353         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, NULL, NULL, true, true);
354         Try {
355                 ArgumentValidator validator(context, argumentCount, arguments);
356
357                 // ndefMessage
358                 JSObjectRef dataObj = validator.toArrayObject(0);
359                 
360                 // successCallback
361                 if (validator.toFunction(1))
362                         callbackManager->setOnSuccess(arguments[1]);
363                 // errorCallback
364                 if (validator.toFunction(2, true))
365                         callbackManager->setOnError(arguments[2]);
366
367                 EventTagActionTransceivePtr event(new EventTagActionTransceive());
368                 Converter convert(context);
369                 std::vector<unsigned char> data;
370                 if (dataObj)
371                         data= convert.toVectorOfUChars(arguments[0]);
372                 event->transceive(data);
373                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
374                 event->setForAsynchronousCall(&NFCResponseDispatcher::getInstance());
375                 nfcTag->transceive(event);
376                 NFCAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, global_context);
377                 return JSValueMakeUndefined(context);
378     } Catch (BasePlatformException) {
379         LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
380         return JSWebAPIException::throwException(context, exception, _rethrown_exception);
381         } Catch (ConversionException) {
382                 LoggerE("transceive : ConversionException");
383                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
384         } Catch (InvalidArgumentException) {
385                 LoggerE("transceive InvalidArgumentException");
386                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values"));
387                 return JSValueMakeUndefined(context);
388         } Catch (PlatformException) {
389                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
390                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available"));
391                 return JSValueMakeUndefined(context);
392         } Catch (WrtDeviceApis::Commons::UnknownException) {
393                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
394         } Catch (WrtDeviceApis::Commons::Exception) {
395                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
396         }
397
398         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
399         return JSValueMakeUndefined(context);
400 }
401
402
403 }
404 }