Update change log and spec for wrt-plugins-tizen_0.4.13
[framework/web/wrt-plugins-tizen.git] / src / SecureElement / JSSEService.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
19 #include <dpl/log/log.h>
20
21 #include <CommonsJavaScript/Validator.h>
22 #include <CommonsJavaScript/Converter.h>
23 #include <Commons/Exception.h>
24 #include <CommonsJavaScript/PrivateObject.h>
25 #include <CommonsJavaScript/JSUtils.h>
26 #include <CommonsJavaScript/JSCallbackManager.h>
27 #include <CommonsJavaScript/Utils.h>
28 #include <JSTizenExceptionFactory.h>
29 #include <JSTizenException.h>
30 #include <SecurityExceptions.h>
31 #include "SEFactory.h"
32 #include "SEResponseDispatcher.h"
33 #include "JSSEService.h"
34 #include "SEAsyncCallbackManager.h"
35 #include "SEListenerManager.h"
36 #include "SEConverter.h"
37 #include "plugin_config.h"
38
39 using namespace DeviceAPI::Common;
40 using namespace WrtDeviceApis::Commons;
41 using namespace WrtDeviceApis::CommonsJavaScript;
42 using namespace DPL;
43
44 #define TIZEN_SESERVICE_ATTRIBUTENAME "SEService"
45
46 namespace DeviceAPI {
47 namespace SecureElement {
48
49  JSClassDefinition JSSEService::m_classInfo =
50 {
51     0,
52     kJSClassAttributeNone,
53     TIZEN_SESERVICE_ATTRIBUTENAME,
54     0,
55     NULL,
56     m_function,
57     initialize,
58     finalize,
59     NULL, //hasProperty,
60     NULL,
61     NULL, //setProperty,
62     NULL, //DeleteProperty,
63     NULL, //GetPropertyNames,
64     NULL, //CallAsFunction,
65     NULL, //CallAsConstructor,
66     hasInstance, //HasInstance,
67     NULL  //ConvertToType
68 };
69
70 JSStaticFunction JSSEService::m_function[] = {
71     {"getReaders", JSSEService::getReaders, kJSPropertyAttributeNone},
72     {"registerSEListener", JSSEService::registerSEListener, kJSPropertyAttributeNone},
73     {"unregisterSEListener", JSSEService::unregisterSEListener, kJSPropertyAttributeNone},
74     {"shutdown", JSSEService::shutdown, kJSPropertyAttributeNone},
75     { 0, 0, 0}
76 };
77
78 JSClassRef JSSEService::m_jsClassRef = JSClassCreate(JSSEService::getClassInfo());
79
80 void JSSEService::initialize(JSContextRef context, JSObjectRef object)
81 {
82         SEServicePrivObject* priv = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(object));
83         if (!priv) {
84                 Try {
85                         ISEServicePtr seService( SEFactory::getInstance().createSEServiceObject() );
86                         priv = new SEServicePrivObject(context, seService);
87                         if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
88                                 LogError("Object can't store private data.");
89                                 delete priv;
90                         }
91                 } Catch (UnsupportedException) {
92                         LogError("UnsupportedException: " << _rethrown_exception.GetMessage());
93                 } Catch (UnknownException) {
94                         LogError("UnknownExceptionException: " << _rethrown_exception.GetMessage());
95                 } Catch (PlatformException) {
96                         LogError("PlatformExceptionException: " << _rethrown_exception.GetMessage());
97                 } Catch (WrtDeviceApis::Commons::Exception) {
98                         LogError("Exception: " << _rethrown_exception.GetMessage());
99                 }
100         }
101 }
102
103 void JSSEService::finalize(JSObjectRef object)
104 {
105         LogDebug( "entered" );
106         SEServicePrivObject *priv = static_cast<SEServicePrivObject*>( JSObjectGetPrivate( object ) ) ;
107         JSObjectSetPrivate(object, NULL);
108         LogDebug("Deleting SEService object");
109         delete priv;
110 }
111
112
113 const JSClassRef JSSEService::getClassRef()
114 {
115         if (!m_jsClassRef) {
116                 m_jsClassRef = JSClassCreate(&m_classInfo);
117         }
118         return m_jsClassRef;
119 }
120
121 const JSClassDefinition* JSSEService::getClassInfo()
122 {
123         return &m_classInfo;
124 }
125
126 bool JSSEService::hasInstance(JSContextRef context,
127         JSObjectRef constructor,
128         JSValueRef possibleInstance,
129         JSValueRef* exception)
130 {
131     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
132 }
133
134 JSValueRef JSSEService::getReaders(JSContextRef context,
135         JSObjectRef object,
136         JSObjectRef thisObject,
137         size_t argumentCount,
138         const JSValueRef arguments[],
139         JSValueRef* exception)
140 {
141         LogDebug("Entered ");
142
143         Validator validator(context, exception);
144
145     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
146     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
147
148         if ((argumentCount < 1) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !validator.isCallback(arguments[0])) {
149                 /* 1st argument is mandatory. And 1st argument must be Callback. */
150                 LogError("TypeMismatchException!");
151                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
152         }
153         if ((argumentCount > 1) && !JSValueIsNull(context, arguments[1]) && !JSValueIsUndefined(context, arguments[1])) {
154                 if (!validator.isCallback(arguments[1])) {
155                         /* 2nd argument must be Callback. */
156                         LogError("ErrorCallback TypeMismatchException!");
157                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
158                 }
159         }
160
161         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
162         if (validator.isCallback(arguments[0])) {
163                 onSuccessForCbm = arguments[0];
164         }
165         if (argumentCount > 1) {
166                 if (validator.isCallback(arguments[1])) {
167                         onErrorForCbm = arguments[1];
168                 }
169         }
170
171         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
172         if (NULL == privateObject) {
173                 LogError("private object is null");
174                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
175         }
176
177         ISEServicePtr seService(privateObject->getObject());
178         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
179         Try {
180                 EventListSEsPtr event(new EventListSEs());
181                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
182                 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
183
184                 seService->getReaders(event);
185
186                 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
187                 return JSValueMakeUndefined(context);
188         } Catch (ConversionException) {
189                 LogError("ConversionException");
190                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
191         } Catch (UnknownException) {
192                 LogError("UnknownException: " << _rethrown_exception.GetMessage());
193         } Catch (WrtDeviceApis::Commons::Exception) {
194                 LogError("Exception: " << _rethrown_exception.GetMessage());
195         }
196
197         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
198         return JSValueMakeUndefined(context);
199 }
200
201 JSValueRef JSSEService::registerSEListener(JSContextRef context,
202         JSObjectRef object,
203         JSObjectRef thisObject,
204         size_t argumentCount,
205         const JSValueRef arguments[],
206         JSValueRef* exception)
207 {
208         LogDebug("Entered ");
209
210     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
211     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
212
213         Validator validator(context, exception);
214
215         if ((argumentCount < 1) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0])) {
216                 /* 1st argument is mandatory */
217                 LogError("TypeMismatchException!");
218                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
219         }
220
221         SEConverter convert(context);
222         SEListener seListener;
223         if (JSValueIsObject(context, arguments[0]) &&
224             !validator.isCallback(arguments[0])) {
225                 seListener = convert.toSEListener(arguments[0]);
226         } else {
227                 /* 1st argument must be SEListener. */
228                 LogError("SEListener must has onSEReady and onSENotReady");
229                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
230         }
231
232
233         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
234         if (NULL == privateObject) {
235                 LogError("private object is null");
236                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
237         }
238
239         ISEServicePtr seService(privateObject->getObject());
240         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), seListener.onSEReady, seListener.onSENotReady, true, true);
241         JSValueProtect(privateObject->getContext(), thisObject);    
242         Try {
243                 EventSEStateChangedEmitterPtr emitter(new EventSEStateChangedEmitter);
244                 emitter->setListener(&SEResponseDispatcher::getInstance());
245                 emitter->setEventPrivateData(StaticPointerCast<EventSEStateChanged::PrivateDataType>(callbackManager));
246                 seService->registerSEListener(emitter);
247
248                 SEListenerCancellerPtr canceller = SEListenerCancellerPtr(new SEListenerCanceller(privateObject->getContext(), thisObject, static_cast<long>(emitter->getId())));
249                 IListenerItemPtr listenerItem = StaticPointerCast<IListenerItem>(canceller);
250                 SEListenerManagerSingleton::Instance().registerListener(listenerItem, privateObject->getContext());
251
252                 return convert.toJSValueRefLong(static_cast<long>(emitter->getId()));
253         } Catch (ConversionException) {
254                 LogError("ConversionException");
255                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
256         } Catch (UnknownException) {
257                 LogError("UnknownException: " << _rethrown_exception.GetMessage());
258         } Catch (WrtDeviceApis::Commons::Exception) {
259                 LogError("Exception: " << _rethrown_exception.GetMessage());
260         }
261
262         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR,"Unknown Error");
263 }
264
265 JSValueRef JSSEService::unregisterSEListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject,
266                 size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
267         LogDebug("Enter");
268
269     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
270     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
271
272         if ((argumentCount < 1) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0])) {
273                 /* 1st argument is mandatory. And 1st argument must be Callback. */
274                 LogError("TypeMismatchException!");
275                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
276         }
277
278         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
279         if (NULL == privateObject) {
280                 LogError("private object is null");
281                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
282         }
283
284         Try     {
285                 ISEServicePtr seService(privateObject->getObject());
286
287                 Converter convert(context);
288                 seService->unregisterSEListener(convert.toLong(arguments[0]));
289
290                 SEListenerCancellerPtr canceller = SEListenerCancellerPtr(new SEListenerCanceller(privateObject->getContext(), thisObject,  convert.toLong(arguments[0])));
291                 IListenerItemPtr listenerItem = StaticPointerCast<IListenerItem>(canceller);
292                 SEListenerManagerSingleton::Instance().unregisterListener(listenerItem);
293
294                 return JSValueMakeUndefined(context);
295         } Catch (ConversionException) {
296                 LogError("ConversionException");
297                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
298         } Catch (NullPointerException) {
299                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
300         } Catch (NotFoundException) {
301                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Not Found ID");
302         } Catch (WrtDeviceApis::Commons::Exception) {
303                 LogError("Exception: " << _rethrown_exception.GetMessage());
304         }
305         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
306 }
307
308 JSValueRef JSSEService::shutdown(JSContextRef context,
309         JSObjectRef object,
310         JSObjectRef thisObject,
311         size_t argumentCount,
312         const JSValueRef arguments[],
313         JSValueRef* exception)
314 {
315         LogDebug("Entered ");
316
317     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
318     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
319
320         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
321         if (NULL == privateObject) {
322                 LogError("private object is null");
323                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
324         }
325
326         ISEServicePtr seService(privateObject->getObject());
327         Try {
328                 seService->shutdown();
329                 return JSValueMakeUndefined(context);
330         } Catch (UnknownException) {
331                 LogError("Exception: " << _rethrown_exception.GetMessage());
332         } Catch (WrtDeviceApis::Commons::Exception) {
333                 LogError("Exception: " << _rethrown_exception.GetMessage());
334         }
335         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
336 }
337
338 }
339 }