541894c98ce564e204d6e5cf38567e1c1ccc6b45
[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
19 #include <dpl/log/log.h>
20 #include <CommonsJavaScript/Validator.h>
21 #include <Commons/Exception.h>
22 #include <CommonsJavaScript/PrivateObject.h>
23 #include <CommonsJavaScript/JSUtils.h>
24 #include <CommonsJavaScript/JSCallbackManager.h>
25 #include <CommonsJavaScript/Utils.h>
26 #include <JSTizenExceptionFactory.h>
27 #include <JSTizenException.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
35 using namespace DeviceAPI::Common;
36 using namespace WrtDeviceApis::Commons;
37 using namespace WrtDeviceApis::CommonsJavaScript;
38 using namespace DPL;
39
40 #define TIZEN_SECHANNEL_ATTRIBUTENAME "Channel"
41 #define TIZEN_SECHANNEL_ISBASICCHANNEL "isBasicChannel"
42
43
44 namespace DeviceAPI {
45 namespace SecureElement {
46
47  JSClassDefinition JSSEChannel::m_classInfo =
48 {
49     0,
50     kJSClassAttributeNone,
51     TIZEN_SECHANNEL_ATTRIBUTENAME,
52     0,
53     m_property,
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 JSSEChannel::m_function[] = {
69     {"close", JSSEChannel::close, kJSPropertyAttributeNone},
70     {"transmit", JSSEChannel::transmit, kJSPropertyAttributeNone},
71     { 0, 0, 0}
72 };
73
74 JSStaticValue JSSEChannel::m_property[] =
75 {
76         {TIZEN_SECHANNEL_ISBASICCHANNEL,  getProperty, NULL, kJSPropertyAttributeReadOnly},
77         { 0, 0, 0, 0 }
78 };
79 JSClassRef JSSEChannel::m_jsClassRef = JSClassCreate(JSSEChannel::getClassInfo());
80
81 JSValueRef JSSEChannel::getProperty(JSContextRef context, JSObjectRef object,
82         JSStringRef propertyName, JSValueRef* exception)
83 {
84         LogDebug("Enter");
85
86         Try     {
87                 SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(object));
88                 if (NULL == privateObject) {
89                         ThrowMsg(NullPointerException, "Private object not set.");
90                 }
91                 ISEChannelPtr channel = privateObject->getObject();
92                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_SECHANNEL_ISBASICCHANNEL)) {
93                         Converter convert(context);
94                         return convert.toJSValueRef(channel->isBasicChannel());
95                 }
96         } Catch (ConversionException) {
97                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
98         } Catch (NullPointerException) {
99                 LogError("NullPointerException: " << _rethrown_exception.GetMessage());
100         } Catch (UnknownException) {
101                 LogError("UnknownExceptionException: " << _rethrown_exception.GetMessage());
102         } Catch (PlatformException) {
103                 LogError("PlatformExceptionException: " << _rethrown_exception.GetMessage());
104         } Catch (WrtDeviceApis::Commons::Exception) {
105                 LogError("Exception: " << _rethrown_exception.GetMessage());
106         }
107
108     return JSValueMakeUndefined(context);
109 }
110
111 JSObjectRef JSSEChannel::createJSObject(JSContextRef context, void *channel) {
112         LogDebug("entered");
113
114         ISEChannelPtr seChannel = SEFactory::getInstance().createSEChannelObject(channel);
115         
116         SEChannelPrivObject *priv = new SEChannelPrivObject(context, seChannel);
117
118         if (!priv) {
119                 ThrowMsg(NullPointerException, "Can not new a SecureElement object");
120         }
121
122         return JSObjectMake(context, getClassRef(), priv);
123 }
124
125 void JSSEChannel::initialize(JSContextRef context, JSObjectRef object)
126 {
127         LogDebug( "entered" );
128 }
129
130 void JSSEChannel::finalize(JSObjectRef object)
131 {
132         LogDebug( "entered" );
133         SEChannelPrivObject *priv = static_cast<SEChannelPrivObject*>( JSObjectGetPrivate( object ) ) ;
134         JSObjectSetPrivate(object, NULL);
135         LogDebug("Deleting SecureElement object");
136         delete priv;
137 }
138
139
140 const JSClassRef JSSEChannel::getClassRef()
141 {
142         if (!m_jsClassRef) {
143                 m_jsClassRef = JSClassCreate(&m_classInfo);
144         }
145         return m_jsClassRef;
146 }
147
148 const JSClassDefinition* JSSEChannel::getClassInfo()
149 {
150         return &m_classInfo;
151 }
152
153 bool JSSEChannel::hasInstance(JSContextRef context,
154         JSObjectRef constructor,
155         JSValueRef possibleInstance,
156         JSValueRef* exception)
157 {
158     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
159 }
160
161 JSValueRef JSSEChannel::close(JSContextRef context,
162         JSObjectRef object,
163         JSObjectRef thisObject,
164         size_t argumentCount,
165         const JSValueRef arguments[],
166         JSValueRef* exception)
167 {
168         LogDebug("Entered ");
169
170         SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(thisObject));
171         if (NULL == privateObject) {
172                 LogError("private object is null");
173                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
174         }
175
176         ISEChannelPtr seChannel(privateObject->getObject());
177         Try {
178                 seChannel->close();
179                 return JSValueMakeUndefined(context);
180         } Catch (UnknownException) {
181                 LogError("Exception: " << _rethrown_exception.GetMessage());
182         } Catch (PlatformException) {
183                 LogError("Exception: " << _rethrown_exception.GetMessage());
184                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available");
185         } Catch (WrtDeviceApis::Commons::Exception) {
186                 LogError("Exception: " << _rethrown_exception.GetMessage());
187         }
188         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
189 }
190
191 JSValueRef JSSEChannel::transmit(JSContextRef context,
192         JSObjectRef object,
193         JSObjectRef thisObject,
194         size_t argumentCount,
195         const JSValueRef arguments[],
196         JSValueRef* exception)
197 {
198         LogDebug("Entered ");
199
200         Validator validator(context, exception);
201
202         if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
203                 /* 1st argument is mandatory. And 1st argument must be Array */
204                 LogError("data TypeMismatchException!");
205                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
206         }
207
208         if (JSValueIsNull(context, arguments[1]) || JSValueIsUndefined(context, arguments[1]) || !validator.isCallback(arguments[1])) {
209                 /* 2st argument is mandatory. And 2st argument must be Callback. */
210                 LogError("ByteArraySuccessCallback TypeMismatchException!");
211                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
212         }
213         if ((argumentCount > 2) && !JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
214                 if (!validator.isCallback(arguments[2])) {
215                         /* 3nd argument must be Callback. */
216                         LogError("ErrorCallback TypeMismatchException!");
217                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
218                 }
219         }
220
221         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
222         if (validator.isCallback(arguments[1])) {
223                 onSuccessForCbm = arguments[1];
224         }
225
226         if ((argumentCount > 2) && validator.isCallback(arguments[2])) {
227                 onErrorForCbm = arguments[2];
228         }
229
230         SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(thisObject));
231         if (NULL == privateObject) {
232                 LogError("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                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
252                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
253         } Catch (InvalidArgumentException) {
254                 LogError("InvalidArgumentException: " << _rethrown_exception.GetMessage());
255                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values"));
256                 return JSValueMakeUndefined(context);
257         } Catch (PlatformException) {
258                 LogError("PlatformException: " << _rethrown_exception.GetMessage());
259                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available"));
260                 return JSValueMakeUndefined(context);
261         } Catch (UnknownException) {
262                 LogError("UnknownException: " << _rethrown_exception.GetMessage());
263         } Catch (WrtDeviceApis::Commons::Exception) {
264                 LogError("Exception: " << _rethrown_exception.GetMessage());
265         }
266
267         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
268         return JSValueMakeUndefined(context);
269 }
270
271 }
272 }