wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / SecureElement / JSSEChannel.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 <JSTizenExceptionFactory.h>
25 #include <JSTizenException.h>
26 #include <ArgumentValidator.h>
27 #include <JSWebAPIException.h>
28 #include <SecurityExceptions.h>
29 #include "SEFactory.h"
30 #include "SEResponseDispatcher.h"
31 #include "JSSEChannel.h"
32 #include "SEAsyncCallbackManager.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 using namespace DPL;
41
42 #define TIZEN_SECHANNEL_ATTRIBUTENAME "Channel"
43 #define TIZEN_SECHANNEL_ISBASICCHANNEL "isBasicChannel"
44
45
46 namespace DeviceAPI {
47 namespace SecureElement {
48
49  JSClassDefinition JSSEChannel::m_classInfo =
50 {
51     0,
52     kJSClassAttributeNone,
53     TIZEN_SECHANNEL_ATTRIBUTENAME,
54     0,
55     m_property,
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 JSSEChannel::m_function[] = {
71     {"close", JSSEChannel::close, kJSPropertyAttributeNone},
72     {"transmit", JSSEChannel::transmit, kJSPropertyAttributeNone},
73     { 0, 0, 0}
74 };
75
76 JSStaticValue JSSEChannel::m_property[] =
77 {
78         {TIZEN_SECHANNEL_ISBASICCHANNEL,  getProperty, NULL, kJSPropertyAttributeReadOnly},
79         { 0, 0, 0, 0 }
80 };
81 JSClassRef JSSEChannel::m_jsClassRef = JSClassCreate(JSSEChannel::getClassInfo());
82
83 JSValueRef JSSEChannel::getProperty(JSContextRef context, JSObjectRef object,
84         JSStringRef propertyName, JSValueRef* exception)
85 {
86         LoggerD("Enter");
87
88         Try     {
89                 SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(object));
90                 if (NULL == privateObject) {
91                         ThrowMsg(NullPointerException, "Private object not set.");
92                 }
93                 ISEChannelPtr channel = privateObject->getObject();
94                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_SECHANNEL_ISBASICCHANNEL)) {
95                         Converter convert(context);
96                         return convert.toJSValueRef(channel->isBasicChannel());
97                 }
98         } Catch (ConversionException) {
99                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
100         } Catch (NullPointerException) {
101                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
102         } Catch (WrtDeviceApis::Commons::UnknownException) {
103                 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
104         } Catch (PlatformException) {
105                 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
106         } Catch (WrtDeviceApis::Commons::Exception) {
107                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
108         }
109
110     return JSValueMakeUndefined(context);
111 }
112
113 JSObjectRef JSSEChannel::createJSObject(JSContextRef context, void *channel) {
114         LoggerD("entered");
115
116         ISEChannelPtr seChannel = SEFactory::getInstance().createSEChannelObject(channel);
117         
118         SEChannelPrivObject *priv = new SEChannelPrivObject(context, seChannel);
119
120         if (!priv) {
121                 ThrowMsg(NullPointerException, "Can not new a SecureElement object");
122         }
123
124         return JSObjectMake(context, getClassRef(), priv);
125 }
126
127 void JSSEChannel::initialize(JSContextRef context, JSObjectRef object)
128 {
129         LoggerD( "entered" );
130 }
131
132 void JSSEChannel::finalize(JSObjectRef object)
133 {
134         LoggerD( "entered" );
135         SEChannelPrivObject *priv = static_cast<SEChannelPrivObject*>( JSObjectGetPrivate( object ) ) ;
136         JSObjectSetPrivate(object, NULL);
137         LoggerD("Deleting SecureElement object");
138         delete priv;
139 }
140
141
142 const JSClassRef JSSEChannel::getClassRef()
143 {
144         if (!m_jsClassRef) {
145                 m_jsClassRef = JSClassCreate(&m_classInfo);
146         }
147         return m_jsClassRef;
148 }
149
150 const JSClassDefinition* JSSEChannel::getClassInfo()
151 {
152         return &m_classInfo;
153 }
154
155 bool JSSEChannel::hasInstance(JSContextRef context,
156         JSObjectRef constructor,
157         JSValueRef possibleInstance,
158         JSValueRef* exception)
159 {
160     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
161 }
162
163 JSValueRef JSSEChannel::close(JSContextRef context,
164         JSObjectRef object,
165         JSObjectRef thisObject,
166         size_t argumentCount,
167         const JSValueRef arguments[],
168         JSValueRef* exception)
169 {
170         LoggerD("Entered ");
171
172     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
173     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
174
175         SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(thisObject));
176         if (NULL == privateObject) {
177                 LoggerE("private object is null");
178                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
179         }
180
181         ISEChannelPtr seChannel(privateObject->getObject());
182         Try {
183                 seChannel->close();
184                 return JSValueMakeUndefined(context);
185         } Catch (WrtDeviceApis::Commons::UnknownException) {
186                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
187         } Catch (WrtDeviceApis::Commons::Exception) {
188                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
189         }
190         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
191 }
192
193 JSValueRef JSSEChannel::transmit(JSContextRef context,
194         JSObjectRef object,
195         JSObjectRef thisObject,
196         size_t argumentCount,
197         const JSValueRef arguments[],
198         JSValueRef* exception)
199 {
200         LoggerD("Entered ");
201
202     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
203     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
204
205         if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
206                 /* 1st argument is mandatory. And 1st argument must be Array */
207                 LoggerE("data TypeMismatchException!");
208                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
209         }
210
211         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
212         try {
213                 ArgumentValidator validator(context, argumentCount, arguments);
214
215                 JSObjectRef successCallbackObj = validator.toFunction(1);
216                 if (successCallbackObj) {
217                         onSuccessForCbm = arguments[1];
218                 }
219
220                 JSObjectRef errorCallbackObj = validator.toFunction(2, true);
221                 if (errorCallbackObj) {
222                         onErrorForCbm = arguments[2];
223                 }
224         } catch (const BasePlatformException &err) {
225         LoggerE(err.getName() << ": " << err.getMessage());
226         return JSWebAPIException::throwException(context, exception, err);
227     }
228
229
230         SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(thisObject));
231         if (NULL == privateObject) {
232                 LoggerE("private object is null");
233                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
234         }
235
236         ISEChannelPtr seChannel(privateObject->getObject());
237         Converter convert(context);
238         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
239
240         Try {
241                 EventSEChannelTransmitPtr event(new EventSEChannelTransmit(convert.toVectorOfUChars(arguments[0])));
242                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
243                 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
244
245                 seChannel->transmit(event);
246
247                 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
248
249                 return JSValueMakeUndefined(context);
250         } Catch (ConversionException) {
251                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
252                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
253         } Catch (WrtDeviceApis::Commons::UnknownException) {
254                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
255         } Catch (WrtDeviceApis::Commons::Exception) {
256                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
257         }
258
259         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
260         return JSValueMakeUndefined(context);
261 }
262
263 }
264 }