2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file JSLocalMessagePort.cpp
21 * @brief Implementation of the JSLocalMessagePort class
24 #include "JSLocalMessagePort.h"
25 #include <CommonsJavaScript/Validator.h>
26 #include <CommonsJavaScript/Converter.h>
27 #include <CommonsJavaScript/JSCallbackManager.h>
28 #include <CommonsJavaScript/JSUtils.h>
29 #include <ArgumentValidator.h>
30 #include <JSWebAPIErrorFactory.h>
31 #include <TimeTracer.h>
32 #include "EventLocalMessagePortAddMessagePortListener.h"
33 #include "EventLocalMessagePortRemoveMessagePortListener.h"
34 #include "MessagePortListenerManager.h"
35 #include "MessagePortJSUtil.h"
38 #define TIZEN_LOCAL_MESSAGE_PORT "LocalMessagePort"
40 #define TIZEN_LOCAL_MESSAGE_PORT_MESSAGE_PORT_NAME "messagePortName"
41 #define TIZEN_LOCAL_MESSAGE_PORT_IS_TRUSTED "isTrusted"
43 #define TIZEN_LOCAL_MESSAGE_PORT_ADD_MESSAGE_PORT_LISTENER "addMessagePortListener"
44 #define TIZEN_LOCAL_MESSAGE_PORT_REMOVE_MESSAGE_PORT_LISTENER "removeMessagePortListener"
47 namespace MessagePort {
50 using namespace DeviceAPI::Common;
51 using namespace WrtDeviceApis::Commons;
52 using namespace WrtDeviceApis::CommonsJavaScript;
54 JSClassRef JSLocalMessagePort::m_jsClassRef = NULL;
56 JSClassDefinition JSLocalMessagePort::m_classInfo = {
58 kJSClassAttributeNone,
59 TIZEN_LOCAL_MESSAGE_PORT,
68 NULL, //DeleteProperty,
69 NULL, //GetPropertyNames,
70 NULL, //CallAsFunction,
71 NULL, //CallAsConstructor,
73 NULL, //ConvertToType,
76 JSStaticValue JSLocalMessagePort::m_property[] = {
77 { TIZEN_LOCAL_MESSAGE_PORT_MESSAGE_PORT_NAME, getMessagePortName, NULL, kJSPropertyAttributeReadOnly },
78 { TIZEN_LOCAL_MESSAGE_PORT_IS_TRUSTED, getIsTrusted, NULL, kJSPropertyAttributeReadOnly },
82 JSStaticFunction JSLocalMessagePort::m_function[] = {
83 { TIZEN_LOCAL_MESSAGE_PORT_ADD_MESSAGE_PORT_LISTENER, addMessagePortListener, kJSPropertyAttributeNone },
84 { TIZEN_LOCAL_MESSAGE_PORT_REMOVE_MESSAGE_PORT_LISTENER, removeMessagePortListener, kJSPropertyAttributeNone },
88 const JSClassDefinition* JSLocalMessagePort::getClassInfo()
93 const JSClassRef JSLocalMessagePort::getClassRef()
96 m_jsClassRef = JSClassCreate(&m_classInfo);
101 void JSLocalMessagePort::Initialize(JSContextRef context,
106 void JSLocalMessagePort::Finalize(JSObjectRef object)
108 LocalMessagePortController *priv =
109 static_cast<LocalMessagePortController*>(JSObjectGetPrivate(object));
114 bool JSLocalMessagePort::isObjectOfClass(JSContextRef context, JSValueRef value)
116 return JSValueIsObjectOfClass(context, value, getClassRef());
119 LocalMessagePortPtr JSLocalMessagePort::getLocalMessagePort(JSContextRef context, JSValueRef value)
121 if (!isObjectOfClass(context, value)) {
122 LOGE("value is not a LocalMessagePort object");
123 throw TypeMismatchException("value is not a LocalMessagePort object");
125 JSObjectRef object = JSValueToObject(context, value, NULL);
127 LOGE("value is not a object");
128 throw TypeMismatchException("value is not a object");
130 LocalMessagePortController *priv =
131 static_cast<LocalMessagePortController*>(JSObjectGetPrivate(object));
133 LOGE("cannot get priv object from LocalMessagePort object");
134 throw TypeMismatchException(
135 "cannot get priv object from LocalMessagePort object");
137 return priv->getObject();
140 LocalMessagePortPtr JSLocalMessagePort::getPrivData(JSObjectRef object)
142 LocalMessagePortController *priv =
143 static_cast<LocalMessagePortController*>(JSObjectGetPrivate(object));
146 return priv->getObject();
148 Throw(NullPointerException);
151 JSValueRef JSLocalMessagePort::getMessagePortName(JSContextRef context,
153 JSStringRef propertyName,
154 JSValueRef* exception)
158 LocalMessagePortPtr localMessagePort = getPrivData(object);
159 return JSUtil::toJSValueRef(context, localMessagePort->getMessagePortName());
161 catch(BasePlatformException &e)
163 LOGW("trying to get incorrect value");
166 return JSValueMakeUndefined(context);
169 JSValueRef JSLocalMessagePort::getIsTrusted(JSContextRef context,
171 JSStringRef propertyName,
172 JSValueRef* exception)
176 LocalMessagePortPtr localMessagePort = getPrivData(object);
177 return JSUtil::toJSValueRef(context, localMessagePort->getIsTrusted());
179 catch(BasePlatformException &e)
181 LOGW("trying to get incorrect value");
184 return JSValueMakeUndefined(context);
187 JSValueRef JSLocalMessagePort::addMessagePortListener(JSContextRef context,
189 JSObjectRef thisObject,
190 size_t argumentCount,
191 const JSValueRef arguments[],
192 JSValueRef* exception)
195 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
196 LocalMessagePortPtr localMessagePort;
197 JSContextRef gContext;
198 LocalMessagePortController *controller;
202 controller = static_cast<LocalMessagePortController*>(JSObjectGetPrivate(thisObject));
204 LOGE("Wrong object");
205 throw TypeMismatchException("Wrong object");
207 localMessagePort = controller->getObject();
208 gContext = controller->getContext();
210 catch(BasePlatformException &e)
212 LOGE("No private object");
213 return JSWebAPIErrorFactory::postException(context, exception, e);
216 JSValueRef listener = NULL;
218 ArgumentValidator validator(context, argumentCount, arguments);
222 listener = validator.toFunction(0, false);
224 catch(BasePlatformException &e)
226 return JSWebAPIErrorFactory::postException(context, exception, e);
229 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
231 callbackManager->setOnSuccess(listener);
233 EventLocalMessagePortListenerEmitterPtr emitter(new EventLocalMessagePortListenerEmitter());
235 emitter->setEventPrivateData(std::static_pointer_cast<IEventPrivateData>(callbackManager));
236 emitter->setListener(controller);
238 EventLocalMessagePortAddMessagePortListenerPtr dplEvent(new EventLocalMessagePortAddMessagePortListener());
240 dplEvent->setEmitter(emitter);
241 dplEvent->setForSynchronousCall();
245 localMessagePort->addMessagePortListener(dplEvent);
249 LOGE("Error on platform : %s", _rethrown_exception.GetMessage().c_str());
250 return JSWebAPIErrorFactory::postException(context, exception,
251 UnknownException("Plugin's internal error"));
254 if (!dplEvent->getResult() || !dplEvent->getIdIsSet())
256 switch (dplEvent->getExceptionCode())
258 case ExceptionCodes::InvalidArgumentException:
259 return JSWebAPIErrorFactory::postException(context, exception,
260 UnknownException("Plugin's internal error."));
261 case ExceptionCodes::PlatformException:
262 return JSWebAPIErrorFactory::postException(context, exception,
263 UnknownException("The method cannot proceed due to a severe system error."));
265 return JSWebAPIErrorFactory::postException(context, exception,
266 UnknownException("Internal error"));
270 long watchId = dplEvent->getId();
272 MessagePortsChangeListenerCancellerPtr canceller = MessagePortsChangeListenerCancellerPtr(new MessagePortsChangeListenerCanceller(gContext, thisObject, watchId));
273 DeviceAPI::Common::IListenerItemPtr listenerItem = std::static_pointer_cast<DeviceAPI::Common::IListenerItem>(canceller);
274 MessagePortListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
279 result = JSUtil::toJSValueRef(context, watchId);
281 catch(BasePlatformException &e)
283 LOGE("Error on conversion : %s", e.getMessage().c_str());
284 return JSWebAPIErrorFactory::postException(context, exception,
285 UnknownException("Internal error"));
288 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
292 JSValueRef JSLocalMessagePort::removeMessagePortListener(JSContextRef context,
294 JSObjectRef thisObject,
295 size_t argumentCount,
296 const JSValueRef arguments[],
297 JSValueRef* exception)
300 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
301 LocalMessagePortPtr localMessagePort;
302 JSContextRef gContext;
303 LocalMessagePortController *controller;
307 controller = static_cast<LocalMessagePortController*>(JSObjectGetPrivate(thisObject));
309 LOGE("Wrong object");
310 throw TypeMismatchException("Wrong object");
312 localMessagePort = controller->getObject();
313 gContext = controller->getContext();
315 catch(BasePlatformException &e)
317 LOGE("No private object");
318 return JSWebAPIErrorFactory::postException(context, exception, e);
323 ArgumentValidator validator(context, argumentCount, arguments);
327 watchId = validator.toLong(0, false);
329 catch(BasePlatformException &e)
331 return JSWebAPIErrorFactory::postException(context, exception, e);
334 EventLocalMessagePortRemoveMessagePortListenerPtr dplEvent(new EventLocalMessagePortRemoveMessagePortListener());
336 dplEvent->setId(watchId);
337 dplEvent->setForSynchronousCall();
341 localMessagePort->removeMessagePortListener(dplEvent);
345 LOGE("Error on platform : %s", _rethrown_exception.GetMessage().c_str());
346 return JSWebAPIErrorFactory::postException(context, exception,
347 UnknownException("Internal error"));
350 MessagePortsChangeListenerCancellerPtr canceller =
351 MessagePortsChangeListenerCancellerPtr(new MessagePortsChangeListenerCanceller(gContext, thisObject, watchId));
352 DeviceAPI::Common::IListenerItemPtr listenerItem = std::static_pointer_cast<DeviceAPI::Common::IListenerItem>(canceller);
353 MessagePortListenerManagerSingleton::Instance().unregisterListener(listenerItem);
355 if (!dplEvent->getResult())
358 switch (dplEvent->getExceptionCode())
360 case ExceptionCodes::InvalidArgumentException:
361 return JSWebAPIErrorFactory::postException(context, exception,
362 InvalidValuesException(oss.str().c_str()));
363 case ExceptionCodes::NotFoundException:
364 oss << "No watchId (" << watchId << ") has been registered.";
365 return JSWebAPIErrorFactory::postException(context, exception,
366 NotFoundException(oss.str().c_str()));
367 case ExceptionCodes::PlatformException:
368 return JSWebAPIErrorFactory::postException(context, exception,
369 UnknownException("The method cannot proceed due to a severe system error."));
371 return JSWebAPIErrorFactory::postException(context, exception,
372 UnknownException("Internal error."));
376 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
377 return JSValueMakeUndefined(context);