wrt-plugins-tizen_0.4.23
[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 #include <CommonsJavaScript/Validator.h>
19 #include <CommonsJavaScript/Converter.h>
20 #include <Commons/Exception.h>
21 #include <CommonsJavaScript/PrivateObject.h>
22 #include <CommonsJavaScript/JSUtils.h>
23 #include <CommonsJavaScript/JSCallbackManager.h>
24 #include <CommonsJavaScript/Utils.h>
25 #include <JSTizenExceptionFactory.h>
26 #include <JSTizenException.h>
27 #include <SecurityExceptions.h>
28 #include <ArgumentValidator.h>
29 #include <JSWebAPIException.h>
30 #include "SEFactory.h"
31 #include "SEResponseDispatcher.h"
32 #include "JSSEService.h"
33 #include "SEAsyncCallbackManager.h"
34 #include "SEListenerManager.h"
35 #include "SEConverter.h"
36 #include "plugin_config.h"
37 #include <Logger.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                                 LoggerE("Object can't store private data.");
89                                 delete priv;
90                         }
91                 } Catch (UnsupportedException) {
92                         LoggerE("UnsupportedException: " << _rethrown_exception.GetMessage());
93                 } Catch (WrtDeviceApis::Commons::UnknownException) {
94                         LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
95                 } Catch (PlatformException) {
96                         LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
97                 } Catch (WrtDeviceApis::Commons::Exception) {
98                         LoggerE("Exception: " << _rethrown_exception.GetMessage());
99                 }
100         }
101 }
102
103 void JSSEService::finalize(JSObjectRef object)
104 {
105         LoggerD( "entered" );
106         SEServicePrivObject *priv = static_cast<SEServicePrivObject*>( JSObjectGetPrivate( object ) ) ;
107         JSObjectSetPrivate(object, NULL);
108         LoggerD("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         LoggerD("Entered ");
142
143     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
144     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
145
146         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
147         try {
148                 ArgumentValidator validator(context, argumentCount, arguments);
149
150                 JSObjectRef successCallbackObj = validator.toFunction(0);
151                 if (successCallbackObj) {
152                         onSuccessForCbm = arguments[0];
153                 }
154
155                 JSObjectRef errorCallbackObj = validator.toFunction(1, true);
156                 if (errorCallbackObj) {
157                         onErrorForCbm = arguments[1];
158                 }
159         } catch (const BasePlatformException &err) {
160         LoggerE(err.getName() << ": " << err.getMessage());
161         return JSWebAPIException::throwException(context, exception, err);
162     }
163
164         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
165         if (NULL == privateObject) {
166                 LoggerE("private object is null");
167                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
168         }
169
170         ISEServicePtr seService(privateObject->getObject());
171         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
172         Try {
173                 EventListSEsPtr event(new EventListSEs());
174                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
175                 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
176
177                 seService->getReaders(event);
178
179                 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
180                 return JSValueMakeUndefined(context);
181         } Catch (ConversionException) {
182                 LoggerE("ConversionException");
183                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
184         } Catch (WrtDeviceApis::Commons::UnknownException) {
185                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
186         } Catch (WrtDeviceApis::Commons::Exception) {
187                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
188         }
189
190         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
191         return JSValueMakeUndefined(context);
192 }
193
194 JSValueRef JSSEService::registerSEListener(JSContextRef context,
195         JSObjectRef object,
196         JSObjectRef thisObject,
197         size_t argumentCount,
198         const JSValueRef arguments[],
199         JSValueRef* exception)
200 {
201         LoggerD("Entered ");
202
203     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
204     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
205
206         Validator validator(context, exception);
207         try {
208                 ArgumentValidator argValidator(context, argumentCount, arguments);
209                 if (!argValidator.toObject(0))
210                         throw TypeMismatchException("Parameter is not Object");
211         }catch(const BasePlatformException& err){
212         return JSWebAPIException::throwException(context, exception, err);
213     }
214
215         SEConverter convert(context);
216         SEListener seListener;
217         if (!validator.isCallback(arguments[0])) {
218                 seListener = convert.toSEListener(arguments[0]);
219         } else {
220                 /* 1st argument must be SEListener. */
221                 LoggerE("SEListener must has onSEReady and onSENotReady");
222                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
223         }
224
225
226         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
227         if (NULL == privateObject) {
228                 LoggerE("private object is null");
229                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
230         }
231
232         ISEServicePtr seService(privateObject->getObject());
233         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), seListener.onSEReady, seListener.onSENotReady, true, true);
234         JSValueProtect(privateObject->getContext(), thisObject);    
235         Try {
236                 EventSEStateChangedEmitterPtr emitter(new EventSEStateChangedEmitter);
237                 emitter->setListener(&SEResponseDispatcher::getInstance());
238                 emitter->setEventPrivateData(StaticPointerCast<EventSEStateChanged::PrivateDataType>(callbackManager));
239                 seService->registerSEListener(emitter);
240
241                 SEListenerCancellerPtr canceller = SEListenerCancellerPtr(new SEListenerCanceller(privateObject->getContext(), thisObject, static_cast<long>(emitter->getId())));
242                 IListenerItemPtr listenerItem = StaticPointerCast<IListenerItem>(canceller);
243                 SEListenerManagerSingleton::Instance().registerListener(listenerItem, privateObject->getContext());
244
245                 return convert.toJSValueRefLong(static_cast<long>(emitter->getId()));
246         } Catch (ConversionException) {
247                 LoggerE("ConversionException");
248                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
249         } Catch (WrtDeviceApis::Commons::UnknownException) {
250                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
251         } Catch (WrtDeviceApis::Commons::Exception) {
252                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
253         }
254
255         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR,"Unknown Error");
256 }
257
258 JSValueRef JSSEService::unregisterSEListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject,
259                 size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) {
260         LoggerD("Enter");
261
262     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
263     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
264
265         unsigned long value;
266         try {
267                 ArgumentValidator validator(context, argumentCount, arguments);
268            value = validator.toULong(0);
269         }catch(const BasePlatformException& err){
270         return JSWebAPIException::throwException(context, exception, err);
271     }
272
273         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
274         if (NULL == privateObject) {
275                 LoggerE("private object is null");
276                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
277         }
278
279         Try     {
280                 ISEServicePtr seService(privateObject->getObject());
281
282                 Converter convert(context);
283                 seService->unregisterSEListener(value);
284
285                 SEListenerCancellerPtr canceller = SEListenerCancellerPtr(new SEListenerCanceller(privateObject->getContext(), thisObject, value));
286                 IListenerItemPtr listenerItem = StaticPointerCast<IListenerItem>(canceller);
287                 SEListenerManagerSingleton::Instance().unregisterListener(listenerItem);
288
289                 return JSValueMakeUndefined(context);
290         } Catch (ConversionException) {
291                 LoggerE("ConversionException");
292                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
293         } Catch (NullPointerException) {
294                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
295         } Catch (WrtDeviceApis::Commons::NotFoundException) {
296                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Not Found ID");
297         } Catch (WrtDeviceApis::Commons::Exception) {
298                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
299         }
300         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
301 }
302
303 JSValueRef JSSEService::shutdown(JSContextRef context,
304         JSObjectRef object,
305         JSObjectRef thisObject,
306         size_t argumentCount,
307         const JSValueRef arguments[],
308         JSValueRef* exception)
309 {
310         LoggerD("Entered ");
311
312     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
313     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
314
315         SEServicePrivObject* privateObject = static_cast<SEServicePrivObject*>(JSObjectGetPrivate(thisObject));
316         if (NULL == privateObject) {
317                 LoggerE("private object is null");
318                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
319         }
320
321         ISEServicePtr seService(privateObject->getObject());
322         Try {
323                 seService->shutdown();
324                 return JSValueMakeUndefined(context);
325         } Catch (WrtDeviceApis::Commons::UnknownException) {
326                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
327         } Catch (WrtDeviceApis::Commons::Exception) {
328                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
329         }
330         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
331 }
332
333 }
334 }