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