Update change log and spec for wrt-plugins-tizen_0.4.49
[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 <JSWebAPIErrorFactory.h>
25 #include <ArgumentValidator.h>
26 #include <SecurityExceptions.h>
27 #include "SEFactory.h"
28 #include "SEResponseDispatcher.h"
29 #include "JSSEChannel.h"
30 #include "SEAsyncCallbackManager.h"
31 #include "SEConverter.h"
32 #include "plugin_config.h"
33 #include <Logger.h>
34
35 using namespace DeviceAPI::Common;
36 using namespace WrtDeviceApis::Commons;
37 using namespace WrtDeviceApis::CommonsJavaScript;
38
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         LoggerD("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                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
98         } Catch (NullPointerException) {
99                 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
100         } Catch (WrtDeviceApis::Commons::UnknownException) {
101                 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
102         } Catch (PlatformException) {
103                 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
104         } Catch (WrtDeviceApis::Commons::Exception) {
105                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
106         }
107
108     return JSValueMakeUndefined(context);
109 }
110
111 JSObjectRef JSSEChannel::createJSObject(JSContextRef context, void *channel) {
112         LoggerD("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         LoggerD( "entered" );
128 }
129
130 void JSSEChannel::finalize(JSObjectRef object)
131 {
132         LoggerD( "entered" );
133         SEChannelPrivObject *priv = static_cast<SEChannelPrivObject*>( JSObjectGetPrivate( object ) ) ;
134         JSObjectSetPrivate(object, NULL);
135         LoggerD("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         LoggerD("Entered ");
169
170     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
171     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
172
173         SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(thisObject));
174         if (NULL == privateObject) {
175                 LoggerE("private object is null");
176                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
177         }
178
179         ISEChannelPtr seChannel(privateObject->getObject());
180         Try {
181                 seChannel->close();
182                 return JSValueMakeUndefined(context);
183         } Catch (WrtDeviceApis::Commons::UnknownException) {
184                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
185         } Catch (WrtDeviceApis::Commons::Exception) {
186                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
187         }
188         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::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         LoggerD("Entered ");
199
200     AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
201     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
202
203         if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
204                 /* 1st argument is mandatory. And 1st argument must be Array */
205                 LoggerE("data TypeMismatchException!");
206                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
207         }
208
209         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
210         try {
211                 ArgumentValidator validator(context, argumentCount, arguments);
212
213                 JSObjectRef successCallbackObj = validator.toFunction(1);
214                 if (successCallbackObj) {
215                         onSuccessForCbm = arguments[1];
216                 }
217
218                 JSObjectRef errorCallbackObj = validator.toFunction(2, true);
219                 if (errorCallbackObj) {
220                         onErrorForCbm = arguments[2];
221                 }
222         } catch (const BasePlatformException &err) {
223         LoggerE(err.getName() << ": " << err.getMessage());
224         return JSWebAPIErrorFactory::postException(context, exception, err);
225     }
226
227
228         SEChannelPrivObject* privateObject = static_cast<SEChannelPrivObject*>(JSObjectGetPrivate(thisObject));
229         if (NULL == privateObject) {
230                 LoggerE("private object is null");
231                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
232         }
233
234         ISEChannelPtr seChannel(privateObject->getObject());
235         Converter convert(context);
236         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
237
238         Try {
239                 EventSEChannelTransmitPtr event(new EventSEChannelTransmit(convert.toVectorOfUChars(arguments[0])));
240                 event->setPrivateData( DPL::StaticPointerCast<IEventPrivateData>(callbackManager) );
241                 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
242                 callbackManager->setObject(thisObject);
243                 seChannel->transmit(event);
244
245                 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
246
247                 return JSValueMakeUndefined(context);
248         } Catch (ConversionException) {
249                 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
250                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
251         } Catch (WrtDeviceApis::Commons::UnknownException) {
252                 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
253         } Catch (WrtDeviceApis::Commons::Exception) {
254                 LoggerE("Exception: " << _rethrown_exception.GetMessage());
255         }
256
257         callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR,"Unknown Error"));
258         return JSValueMakeUndefined(context);
259 }
260
261 }
262 }