Update change log and spec for wrt-plugins-tizen_0.4.39
[platform/framework/web/wrt-plugins-tizen.git] / src / NFC / JSNFCTarget.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 <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>
29
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.h"
40 #include <Logger.h>
41
42
43 using namespace DeviceAPI::Common;
44 using namespace WrtDeviceApis::Commons;
45 using namespace WrtDeviceApis::CommonsJavaScript;
46
47
48 #define TIZEN_NFCTARGET_ATTRIBUTENAME "NFCTarget"
49
50 #define TIZEN_NFCTARGET_ISCONNECTED "isConnected"
51
52 namespace DeviceAPI {
53 namespace NFC {
54
55  JSClassDefinition JSNFCTarget::m_classInfo =
56 {
57     0,
58     kJSClassAttributeNone,
59     TIZEN_NFCTARGET_ATTRIBUTENAME,
60     0,
61     m_property,
62     m_function,
63     initialize,
64     finalize,
65     NULL, //hasProperty,
66     NULL,
67     NULL, //setProperty,
68     NULL, //DeleteProperty,
69     NULL, //GetPropertyNames,
70     NULL, //CallAsFunction,
71     NULL, //CallAsConstructor,
72     hasInstance, //HasInstance,
73     NULL  //ConvertToType
74 };
75
76 JSStaticValue JSNFCTarget::m_property[] =
77 {
78     //NFCTargetProperties
79     { TIZEN_NFCTARGET_ISCONNECTED, getProperty,
80             NULL, kJSPropertyAttributeReadOnly},
81     { 0, 0, 0, 0 }
82 };
83
84 JSStaticFunction JSNFCTarget::m_function[] = {
85     {"setReceiveNDEFListener", JSNFCTarget::setReceiveNDEFListener, kJSPropertyAttributeNone},
86     {"unsetReceiveNDEFListener", JSNFCTarget::unsetReceiveNDEFListener, kJSPropertyAttributeNone},
87     {"sendNDEF", JSNFCTarget::sendNDEF, kJSPropertyAttributeNone},
88     { 0, 0, 0}
89 };
90
91 JSClassRef JSNFCTarget::m_jsClassRef = JSClassCreate(JSNFCTarget::getClassInfo());
92
93 JSObjectRef JSNFCTarget::createJSObject(JSContextRef context, void *tagHandle) {
94         LoggerD("entered");
95
96         INFCTargetPtr nfcTarget = NFCFactory::getInstance().createNFCTargetObject(tagHandle);
97
98         NFCTargetPrivObject *priv = new NFCTargetPrivObject(context, nfcTarget);
99
100         if (!priv) {
101                 ThrowMsg(NullPointerException, "Can not new a NFCTarget object");
102         }
103
104         return JSObjectMake(context, getClassRef(), priv);
105 }
106
107 void JSNFCTarget::initialize(JSContextRef context, JSObjectRef object)
108 {
109 }
110
111 void JSNFCTarget::finalize(JSObjectRef object)
112 {
113         LoggerD( "entered" );
114         NFCTargetPrivObject *priv = static_cast<NFCTargetPrivObject*>( JSObjectGetPrivate( object ) ) ;
115         JSObjectSetPrivate(object, NULL);
116         LoggerD("Deleting timezone object");
117         delete priv;
118 }
119
120
121 const JSClassRef JSNFCTarget::getClassRef()
122 {
123         if (!m_jsClassRef) {
124                 m_jsClassRef = JSClassCreate(&m_classInfo);
125         }
126         return m_jsClassRef;
127 }
128
129 const JSClassDefinition* JSNFCTarget::getClassInfo()
130 {
131         return &m_classInfo;
132 }
133
134 JSValueRef JSNFCTarget::getProperty(JSContextRef context, JSObjectRef object,
135         JSStringRef propertyName, JSValueRef* exception)
136 {
137         LoggerD("Enter");
138
139         Try     {
140                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_NFCTARGET_ISCONNECTED)) {
141                         NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(object));
142                         if (!privateObject) {
143                                 LoggerE("Private object is not set.");
144                                 ThrowMsg(NullPointerException, "Private object not initialized");
145                         }
146
147                         INFCTargetPtr nfcTarget(privateObject->getObject());
148                         NFCConverter convert(context);
149                         return convert.toJSValueRef(nfcTarget->isConnected());
150                 }
151         } Catch (ConversionException) {
152                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
153         } Catch (NullPointerException) {
154                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
155         } Catch (WrtDeviceApis::Commons::UnknownException) {
156                 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
157         } Catch (PlatformException) {
158                 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
159         } Catch (WrtDeviceApis::Commons::Exception) {
160                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
161         }
162         return JSValueMakeUndefined(context);
163 }
164
165 bool JSNFCTarget::hasInstance(JSContextRef context,
166         JSObjectRef constructor,
167         JSValueRef possibleInstance,
168         JSValueRef* exception)
169 {
170     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
171 }
172
173 JSValueRef JSNFCTarget::setReceiveNDEFListener(JSContextRef context,
174         JSObjectRef object,
175         JSObjectRef thisObject,
176         size_t argumentCount,
177         const JSValueRef arguments[],
178         JSValueRef* exception)
179 {
180         LoggerD("Entered ");
181
182         AceSecurityStatus status = NFC_CHECK_ACCESS(NFC_FUNCTION_API_P2P_FUNCS);
183         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
184
185         JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
186
187         NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(thisObject));
188         if (NULL == privateObject) {
189                 LoggerE("private object is null");
190                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
191         }
192         
193         INFCTargetPtr nfcTarget(privateObject->getObject());
194
195         Try {
196                 ArgumentValidator validator(context, argumentCount, arguments);
197                 JSValueRef onSuccessForCbm = NULL;
198                 // NDEFMessageReadCallback
199                 if (validator.toFunction(0))
200                         onSuccessForCbm = arguments[0];
201
202                 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, onSuccessForCbm, NULL, true, true);
203
204                 EventTargetActionReceiveEmitterPtr emitter(new EventTargetActionReceiveEmitter);
205                 emitter->setListener(&NFCResponseDispatcher::getInstance());
206                 emitter->setEventPrivateData(DPL::StaticPointerCast<EventTargetActionReceive::PrivateDataType>(callbackManager));
207                 nfcTarget->setReceiveNDEFListener(emitter);
208
209                 NFCListenerCancellerPtr canceller = NFCListenerCancellerPtr(new NFCListenerCanceller(global_context, thisObject, static_cast<long>(ID_NFCPEER_RECEIVENDEF_LISTENER)));
210                 IListenerItemPtr listenerItem = DPL::StaticPointerCast<IListenerItem>(canceller);
211                 NFCListenerManagerSingleton::Instance().registerListener(listenerItem, global_context);
212
213                 return JSValueMakeUndefined(context);
214     } Catch (BasePlatformException) {
215         LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
216         return JSWebAPIErrorFactory::postException(context, exception, _rethrown_exception);
217         } Catch (ConversionException) {
218                 LoggerE("setReceiveNDEFListener : ConversionException");
219                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
220         } Catch (PlatformException) {
221                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
222                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR, "Service Not Available");
223         } Catch (WrtDeviceApis::Commons::UnknownException) {
224                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
225         } Catch (WrtDeviceApis::Commons::Exception) {
226                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
227         }
228
229         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
230 }
231
232 JSValueRef JSNFCTarget::unsetReceiveNDEFListener(JSContextRef context,
233         JSObjectRef object,
234         JSObjectRef thisObject,
235         size_t argumentCount,
236         const JSValueRef arguments[],
237         JSValueRef* exception)
238 {
239         LoggerD("Entered ");
240         Try {
241                 AceSecurityStatus status = NFC_CHECK_ACCESS(NFC_FUNCTION_API_P2P_FUNCS);
242                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
243
244                 JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
245
246                 NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(thisObject));
247                 if (NULL == privateObject) {
248                         LoggerE("private object is null");
249                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
250                 }
251
252                 INFCTargetPtr nfcTarget(privateObject->getObject());
253                 nfcTarget->unsetReceiveNDEFListener();
254
255                 NFCListenerCancellerPtr canceller = NFCListenerCancellerPtr(new NFCListenerCanceller(global_context, thisObject,  static_cast<long>(ID_NFCPEER_RECEIVENDEF_LISTENER)));
256                 IListenerItemPtr listenerItem = DPL::StaticPointerCast<IListenerItem>(canceller);
257                 NFCListenerManagerSingleton::Instance().unregisterListener(listenerItem);
258
259                 return JSValueMakeUndefined(context);
260         } Catch (WrtDeviceApis::Commons::UnknownException) {
261                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
262         } Catch(NullPointerException) {
263                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
264                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
265         } Catch (PlatformException) {
266                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
267                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR, "Service Not Available");
268         } Catch (WrtDeviceApis::Commons::Exception) {
269                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
270         }
271
272         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
273 }
274
275 JSValueRef JSNFCTarget::sendNDEF(JSContextRef context,
276         JSObjectRef object,
277         JSObjectRef thisObject,
278         size_t argumentCount,
279         const JSValueRef arguments[],
280         JSValueRef* exception)
281 {
282         LoggerD("Entered ");
283
284         AceSecurityStatus status = NFC_CHECK_ACCESS(NFC_FUNCTION_API_P2P_FUNCS);
285         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
286
287         JSContextRef global_context = GlobalContextManager::getInstance()->getGlobalContext(context);
288         
289         NFCConverter convert(context);
290
291         NFCTargetPrivObject* privateObject = static_cast<NFCTargetPrivObject*>(JSObjectGetPrivate(thisObject));
292         if (NULL == privateObject) {
293                 LoggerE("private object is null");
294                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
295         }
296
297         INFCTargetPtr nfcTarget(privateObject->getObject());
298         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(global_context, NULL, NULL, true, true);
299         Try {
300                 ArgumentValidator validator(context, argumentCount, arguments);
301
302                 // ndefMessage
303                 JSObjectRef ndefMessageObj = validator.toObject(0, JSNdefMessage::getClassRef());
304                 // successCallback
305                 if (validator.toFunction(1, true))
306                         callbackManager->setOnSuccess(arguments[1]);
307                 // errorCallback
308                 if (validator.toFunction(2, true))
309                         callbackManager->setOnError(arguments[2]);
310
311                 void *messageHandle = convert.copiedMessage(ndefMessageObj);
312                 EventTargetActionSendPtr event(new EventTargetActionSend(messageHandle));
313                 event->setPrivateData( DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
314                 event->setForAsynchronousCall(&NFCResponseDispatcher::getInstance());
315                 nfcTarget->sendNDEF(event);
316                 NFCAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, global_context);
317                 return JSValueMakeUndefined(context);
318     } Catch (BasePlatformException) {
319         LoggerE(_rethrown_exception.getName() << ": " << _rethrown_exception.getMessage());
320         return JSWebAPIErrorFactory::postException(context, exception, _rethrown_exception);
321         } Catch (ConversionException) {
322                 LoggerE("sendNDEF : ConversionException");
323                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
324         } Catch (InvalidArgumentException) {
325                 LoggerE("sendNDEF InvalidArgumentException");
326                 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid Values"));
327                 return JSValueMakeUndefined(context);
328         } Catch (PlatformException) {
329                 LoggerE("PlatformException: " << _rethrown_exception.GetMessage());
330                 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR, "Service Not Available"));
331                 return JSValueMakeUndefined(context);
332         } Catch (WrtDeviceApis::Commons::UnknownException) {
333                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
334         } Catch (WrtDeviceApis::Commons::Exception) {
335                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
336         }
337
338         callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR,"Unknown Error"));
339         return JSValueMakeUndefined(context);
340 }
341
342 }
343 }