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