a6653a8da17bcad9da9e2a6ea10aab58b40a7ee2
[platform/framework/web/wrt-plugins-tizen.git] / src / MessagePort / JSRemoteMessagePort.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  * @file        JSRemoteMessagePort.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief       Implementation of the JSRemoteMessagePort class
23  */
24
25 #include "JSRemoteMessagePort.h"
26
27 #include <dpl/log/log.h>
28 #include <CommonsJavaScript/Validator.h>
29 #include <CommonsJavaScript/Converter.h>
30 #include <CommonsJavaScript/JSCallbackManager.h>
31 #include <CommonsJavaScript/JSUtils.h>
32 #include <CommonsJavaScript/JSPendingOperation.h>
33 #include <JSWebAPIException.h>
34 #include "EventRemoteMessagePortSendMessage.h"
35 #include "JSLocalMessagePort.h"
36 #include "MessagePortJSUtil.h"
37
38 #define TIZEN_REMOTE_MESSAGE_PORT                   "RemoteMessagePort"
39
40 #define TIZEN_REMOTE_MESSAGE_PORT_MESSAGE_PORT_NAME "messagePortName"
41 #define TIZEN_REMOTE_MESSAGE_PORT_APP_ID            "appId"
42 #define TIZEN_REMOTE_MESSAGE_PORT_IS_TRUSTED        "isTrusted"
43
44 #define TIZEN_REMOTE_MESSAGE_PORT_SEND_MESSAGE      "sendMessage"
45
46 namespace DeviceAPI {
47 namespace MessagePort {
48
49 using namespace std;
50 using namespace DeviceAPI::Common;
51 using namespace WrtDeviceApis::Commons;
52 using namespace WrtDeviceApis::CommonsJavaScript;
53
54 JSClassRef JSRemoteMessagePort::m_jsClassRef = NULL;
55
56 JSClassDefinition JSRemoteMessagePort::m_classInfo = {
57         0,
58         kJSClassAttributeNone,
59         TIZEN_REMOTE_MESSAGE_PORT,
60         0,
61         m_property,
62         m_function,
63         Initialize,
64         Finalize,
65         NULL, //HasProperty,
66         NULL, //GetProperty,
67         NULL, //SetProperty,
68         NULL, //DeleteProperty,
69         NULL, //GetPropertyNames,
70         NULL, //CallAsFunction,
71         NULL, //CallAsConstructor,
72         NULL, //HasInstance,
73         NULL, //ConvertToType,
74 };
75
76 JSStaticValue JSRemoteMessagePort::m_property[] = {
77         { TIZEN_REMOTE_MESSAGE_PORT_MESSAGE_PORT_NAME, getMessagePortName, NULL, kJSPropertyAttributeReadOnly },
78         { TIZEN_REMOTE_MESSAGE_PORT_APP_ID, getAppId, NULL, kJSPropertyAttributeReadOnly },
79         { TIZEN_REMOTE_MESSAGE_PORT_IS_TRUSTED, getIsTrusted, NULL, kJSPropertyAttributeReadOnly },
80         { 0, 0, 0, 0 }
81 };
82
83 JSStaticFunction JSRemoteMessagePort::m_function[] = {
84         { TIZEN_REMOTE_MESSAGE_PORT_SEND_MESSAGE, sendMessage, kJSPropertyAttributeNone },
85         { 0, 0, 0 }
86 };
87
88 const JSClassDefinition* JSRemoteMessagePort::getClassInfo()
89 {
90         return &m_classInfo;
91 }
92
93 const JSClassRef JSRemoteMessagePort::getClassRef()
94 {
95         LogInfo("entered");
96         if (!m_jsClassRef) {
97                 m_jsClassRef = JSClassCreate(&m_classInfo);
98         }
99         return m_jsClassRef;
100 }
101
102 void JSRemoteMessagePort::Initialize(JSContextRef context,
103                 JSObjectRef object)
104 {
105 }
106
107 void JSRemoteMessagePort::Finalize(JSObjectRef object)
108 {
109         JSRemoteMessagePortPriv *priv =
110                 static_cast<JSRemoteMessagePortPriv*>(JSObjectGetPrivate(object));
111
112         delete priv;
113 }
114
115 bool JSRemoteMessagePort::isObjectOfClass(JSContextRef context, JSValueRef value)
116 {
117         return JSValueIsObjectOfClass(context, value, getClassRef());
118 }
119
120 RemoteMessagePortPtr JSRemoteMessagePort::getRemoteMessagePort(JSContextRef context, JSValueRef value)
121 {
122         if (!isObjectOfClass(context, value))
123                 throw TypeMismatchException("value is not a RemoteMessagePort object");
124
125         JSObjectRef object = JSValueToObject(context, value, NULL);
126         if (!object)
127                 throw TypeMismatchException("value is not a object");
128
129         JSRemoteMessagePortPriv *priv = static_cast<JSRemoteMessagePortPriv*>(JSObjectGetPrivate(object));
130         if (!priv)
131                 throw TypeMismatchException("cannot get priv object from RemoteMessagePort object");
132
133         return priv->getObject();
134 }
135
136 RemoteMessagePortPtr JSRemoteMessagePort::getPrivData(JSObjectRef object)
137 {
138         JSRemoteMessagePortPriv *priv =
139                 static_cast<JSRemoteMessagePortPriv*>(JSObjectGetPrivate(object));
140
141         if (priv)
142                 return priv->getObject();
143
144         throw TypeMismatchException("cannot get priv object from RemoteMessagePort object");
145 }
146
147 JSValueRef JSRemoteMessagePort::getMessagePortName(JSContextRef context,
148                 JSObjectRef object,
149                 JSStringRef propertyName,
150                 JSValueRef* exception)
151 {
152         try
153         {
154                 RemoteMessagePortPtr localMessagePort = getPrivData(object);
155                 return JSUtil::toJSValueRef(context, localMessagePort->getMessagePortName());
156         }
157         catch(BasePlatformException &e)
158         {
159                 LogWarning("trying to get incorrect value");
160         }
161
162         return JSValueMakeUndefined(context);
163 }
164
165 JSValueRef JSRemoteMessagePort::getAppId(JSContextRef context,
166                 JSObjectRef object,
167                 JSStringRef propertyName,
168                 JSValueRef* exception)
169 {
170         try
171         {
172                 RemoteMessagePortPtr localMessagePort = getPrivData(object);
173                 return JSUtil::toJSValueRef(context, localMessagePort->getAppId());
174         }
175         catch(BasePlatformException &e)
176         {
177                 LogWarning("trying to get incorrect value");
178         }
179
180         return JSValueMakeUndefined(context);
181 }
182
183 JSValueRef JSRemoteMessagePort::getIsTrusted(JSContextRef context,
184                 JSObjectRef object,
185                 JSStringRef propertyName,
186                 JSValueRef* exception)
187 {
188         try
189         {
190                 RemoteMessagePortPtr localMessagePort = getPrivData(object);
191                 return JSUtil::toJSValueRef(context, localMessagePort->getIsTrusted());
192         }
193         catch(BasePlatformException &e)
194         {
195                 LogWarning("trying to get incorrect value");
196         }
197
198         return JSValueMakeUndefined(context);
199 }
200
201 JSValueRef JSRemoteMessagePort::sendMessage(JSContextRef context,
202                 JSObjectRef object,
203                 JSObjectRef thisObject,
204                 size_t argumentCount,
205                 const JSValueRef arguments[],
206                 JSValueRef* exception)
207 {
208         LogDebug("entered");
209         RemoteMessagePortPtr remoteMessagePort(NULL);
210
211         try
212         {
213                 JSRemoteMessagePortPriv *priv =
214                         static_cast<JSRemoteMessagePortPriv*>(JSObjectGetPrivate(thisObject));
215
216                 if (!priv)
217                         throw TypeMismatchException("Wrong object");
218
219                 remoteMessagePort = priv->getObject();
220         }
221         catch(BasePlatformException &e)
222         {
223                 LogError("No private object");
224                 return JSWebAPIException::throwException(context, exception, e);
225         }
226
227         MessagePortDataItemMapPtr data(NULL);
228         LocalMessagePortPtr localMessagePort(NULL);
229
230         try
231         {
232                 if(argumentCount < 1)
233                         throw TypeMismatchException("1st argument must be array of MessagePortDataItem");
234
235                 data = MessagePortJSUtil::JSValueToMessagePortDataItemMap(context, arguments[0]);
236         }
237         catch(BasePlatformException &e)
238         {
239                 return JSWebAPIException::throwException(context, exception, e);
240         }
241
242         try
243         {
244                 if(argumentCount >= 2 &&
245                                 !JSValueIsUndefined(context, arguments[1]) &&
246                                 !JSValueIsNull(context, arguments[1]))
247                         localMessagePort = MessagePortJSUtil::JSValueToLocalMessagePort(context, arguments[1]);
248         }
249         catch(BasePlatformException &e)
250         {
251                 return JSWebAPIException::throwException(context, exception, e);
252         }
253
254         EventRemoteMessagePortSendMessagePtr dplEvent(new EventRemoteMessagePortSendMessage());
255
256         dplEvent->setData(data);
257         if(localMessagePort != NULL)
258                 dplEvent->setLocalMessagePort(localMessagePort);
259         dplEvent->setForSynchronousCall();
260
261         Try
262         {
263                 remoteMessagePort->sendMessage(dplEvent);
264         }
265         Catch(Exception)
266         {
267                 LogError("Error on platform : " << _rethrown_exception.GetMessage());
268                 return JSWebAPIException::throwException(context, exception,
269                                 UnknownException("Plugin's internal error."));
270         }
271
272         if (!dplEvent->getResult())
273         {
274                 switch (dplEvent->getExceptionCode())
275                 {
276                 case ExceptionCodes::ConversionException:
277                         return JSWebAPIException::throwException(context, exception,
278                                         TypeMismatchException("Wrong LocalMessagePort object."));
279                         break;
280                 case ExceptionCodes::InvalidArgumentException:
281                         return JSWebAPIException::throwException(context, exception,
282                                         InvalidValuesException("The data argument is wrong."));
283                         break;
284                 case ExceptionCodes::NotFoundException:
285                         return JSWebAPIException::throwException(context, exception,
286                                         UnknownException("The target application's port is not found."));
287                         break;
288                 case ExceptionCodes::PlatformException:
289                         return JSWebAPIException::throwException(context, exception,
290                                         UnknownException("The method cannot proceed due to a severe system error."));
291                         break;
292                 case ExceptionCodes::OutOfRangeException:
293                         return JSWebAPIException::throwException(context, exception,
294                                         UnknownException("The size of message has exceeded the maximum limit."));
295                         break;
296                 default:
297                         return JSWebAPIException::throwException(context, exception,
298                                         UnknownException("Internal error"));
299                         break;
300                 }
301         }
302
303         return JSValueMakeUndefined(context);
304 }
305
306 } // MessagePort
307 } // DeviceAPI