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
20 * @author Kisub Song (kisubs.song@samsung.com)
22 * @brief Implementation of the JSLocalMessagePort class
25 #include "JSLocalMessagePort.h"
26 #include <CommonsJavaScript/Validator.h>
27 #include <CommonsJavaScript/Converter.h>
28 #include <CommonsJavaScript/JSCallbackManager.h>
29 #include <CommonsJavaScript/JSUtils.h>
30 #include <JSWebAPIException.h>
31 #include <ArgumentValidator.h>
32 #include <TimeTracer.h>
33 #include "EventLocalMessagePortAddMessagePortListener.h"
34 #include "EventLocalMessagePortRemoveMessagePortListener.h"
35 #include "MessagePortListenerManager.h"
36 #include "MessagePortJSUtil.h"
39 #define TIZEN_LOCAL_MESSAGE_PORT "LocalMessagePort"
41 #define TIZEN_LOCAL_MESSAGE_PORT_MESSAGE_PORT_NAME "messagePortName"
42 #define TIZEN_LOCAL_MESSAGE_PORT_IS_TRUSTED "isTrusted"
44 #define TIZEN_LOCAL_MESSAGE_PORT_ADD_MESSAGE_PORT_LISTENER "addMessagePortListener"
45 #define TIZEN_LOCAL_MESSAGE_PORT_REMOVE_MESSAGE_PORT_LISTENER "removeMessagePortListener"
48 namespace MessagePort {
51 using namespace DeviceAPI::Common;
52 using namespace WrtDeviceApis::Commons;
53 using namespace WrtDeviceApis::CommonsJavaScript;
55 JSClassRef JSLocalMessagePort::m_jsClassRef = NULL;
57 JSClassDefinition JSLocalMessagePort::m_classInfo = {
59 kJSClassAttributeNone,
60 TIZEN_LOCAL_MESSAGE_PORT,
69 NULL, //DeleteProperty,
70 NULL, //GetPropertyNames,
71 NULL, //CallAsFunction,
72 NULL, //CallAsConstructor,
74 NULL, //ConvertToType,
77 JSStaticValue JSLocalMessagePort::m_property[] = {
78 { TIZEN_LOCAL_MESSAGE_PORT_MESSAGE_PORT_NAME, getMessagePortName, NULL, kJSPropertyAttributeReadOnly },
79 { TIZEN_LOCAL_MESSAGE_PORT_IS_TRUSTED, getIsTrusted, NULL, kJSPropertyAttributeReadOnly },
83 JSStaticFunction JSLocalMessagePort::m_function[] = {
84 { TIZEN_LOCAL_MESSAGE_PORT_ADD_MESSAGE_PORT_LISTENER, addMessagePortListener, kJSPropertyAttributeNone },
85 { TIZEN_LOCAL_MESSAGE_PORT_REMOVE_MESSAGE_PORT_LISTENER, removeMessagePortListener, kJSPropertyAttributeNone },
89 const JSClassDefinition* JSLocalMessagePort::getClassInfo()
94 const JSClassRef JSLocalMessagePort::getClassRef()
98 m_jsClassRef = JSClassCreate(&m_classInfo);
103 void JSLocalMessagePort::Initialize(JSContextRef context,
108 void JSLocalMessagePort::Finalize(JSObjectRef object)
110 LocalMessagePortController *priv =
111 static_cast<LocalMessagePortController*>(JSObjectGetPrivate(object));
116 bool JSLocalMessagePort::isObjectOfClass(JSContextRef context, JSValueRef value)
118 return JSValueIsObjectOfClass(context, value, getClassRef());
121 LocalMessagePortPtr JSLocalMessagePort::getLocalMessagePort(JSContextRef context, JSValueRef value)
123 if (!isObjectOfClass(context, value))
124 throw TypeMismatchException("value is not a LocalMessagePort object");
126 JSObjectRef object = JSValueToObject(context, value, NULL);
128 throw TypeMismatchException("value is not a object");
130 LocalMessagePortController *priv = static_cast<LocalMessagePortController*>(JSObjectGetPrivate(object));
132 throw TypeMismatchException("cannot get priv object from LocalMessagePort object");
134 return priv->getObject();
137 LocalMessagePortPtr JSLocalMessagePort::getPrivData(JSObjectRef object)
139 LocalMessagePortController *priv =
140 static_cast<LocalMessagePortController*>(JSObjectGetPrivate(object));
143 return priv->getObject();
145 Throw(NullPointerException);
148 JSValueRef JSLocalMessagePort::getMessagePortName(JSContextRef context,
150 JSStringRef propertyName,
151 JSValueRef* exception)
155 LocalMessagePortPtr localMessagePort = getPrivData(object);
156 return JSUtil::toJSValueRef(context, localMessagePort->getMessagePortName());
158 catch(BasePlatformException &e)
160 LoggerW("trying to get incorrect value");
163 return JSValueMakeUndefined(context);
166 JSValueRef JSLocalMessagePort::getIsTrusted(JSContextRef context,
168 JSStringRef propertyName,
169 JSValueRef* exception)
173 LocalMessagePortPtr localMessagePort = getPrivData(object);
174 return JSUtil::toJSValueRef(context, localMessagePort->getIsTrusted());
176 catch(BasePlatformException &e)
178 LoggerW("trying to get incorrect value");
181 return JSValueMakeUndefined(context);
184 JSValueRef JSLocalMessagePort::addMessagePortListener(JSContextRef context,
186 JSObjectRef thisObject,
187 size_t argumentCount,
188 const JSValueRef arguments[],
189 JSValueRef* exception)
192 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
193 LocalMessagePortPtr localMessagePort;
194 JSContextRef gContext;
195 LocalMessagePortController *controller;
199 controller = static_cast<LocalMessagePortController*>(JSObjectGetPrivate(thisObject));
201 throw TypeMismatchException("Wrong object");
203 localMessagePort = controller->getObject();
204 gContext = controller->getContext();
206 catch(BasePlatformException &e)
208 LoggerE("No private object");
209 return JSWebAPIException::throwException(context, exception, e);
212 JSValueRef listener = NULL;
214 ArgumentValidator validator(context, argumentCount, arguments);
218 listener = validator.toFunction(0, false);
220 catch(BasePlatformException &e)
222 return JSWebAPIException::throwException(context, exception, e);
225 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
227 callbackManager->setOnSuccess(listener);
229 EventLocalMessagePortListenerEmitterPtr emitter(new EventLocalMessagePortListenerEmitter());
231 emitter->setEventPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
232 emitter->setListener(controller);
234 EventLocalMessagePortAddMessagePortListenerPtr dplEvent(new EventLocalMessagePortAddMessagePortListener());
236 dplEvent->setEmitter(emitter);
237 dplEvent->setForSynchronousCall();
241 localMessagePort->addMessagePortListener(dplEvent);
245 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
246 return JSWebAPIException::throwException(context, exception,
247 UnknownException("Plugin's internal error"));
250 if (!dplEvent->getResult() || !dplEvent->getIdIsSet())
252 switch (dplEvent->getExceptionCode())
254 case ExceptionCodes::InvalidArgumentException:
255 return JSWebAPIException::throwException(context, exception,
256 UnknownException("Plugin's internal error."));
258 case ExceptionCodes::PlatformException:
259 return JSWebAPIException::throwException(context, exception,
260 UnknownException("The method cannot proceed due to a severe system error."));
263 return JSWebAPIException::throwException(context, exception,
264 UnknownException("Internal error"));
269 long watchId = dplEvent->getId();
271 MessagePortsChangeListenerCancellerPtr canceller = MessagePortsChangeListenerCancellerPtr(new MessagePortsChangeListenerCanceller(gContext, thisObject, watchId));
272 DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
273 MessagePortListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
278 result = JSUtil::toJSValueRef(context, watchId);
280 catch(BasePlatformException &e)
282 LoggerE("Error on conversion : " << e.getMessage());
283 return JSWebAPIException::throwException(context, exception,
284 UnknownException("Internal error"));
287 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
291 JSValueRef JSLocalMessagePort::removeMessagePortListener(JSContextRef context,
293 JSObjectRef thisObject,
294 size_t argumentCount,
295 const JSValueRef arguments[],
296 JSValueRef* exception)
299 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
300 LocalMessagePortPtr localMessagePort;
301 JSContextRef gContext;
302 LocalMessagePortController *controller;
306 controller = static_cast<LocalMessagePortController*>(JSObjectGetPrivate(thisObject));
308 throw TypeMismatchException("Wrong object");
310 localMessagePort = controller->getObject();
311 gContext = controller->getContext();
313 catch(BasePlatformException &e)
315 LoggerE("No private object");
316 return JSWebAPIException::throwException(context, exception, e);
321 ArgumentValidator validator(context, argumentCount, arguments);
325 watchId = validator.toLong(0, false);
327 catch(BasePlatformException &e)
329 return JSWebAPIException::throwException(context, exception, e);
332 EventLocalMessagePortRemoveMessagePortListenerPtr dplEvent(new EventLocalMessagePortRemoveMessagePortListener());
334 dplEvent->setId(watchId);
335 dplEvent->setForSynchronousCall();
339 localMessagePort->removeMessagePortListener(dplEvent);
343 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
344 return JSWebAPIException::throwException(context, exception,
345 UnknownException("Internal error"));
348 MessagePortsChangeListenerCancellerPtr canceller =
349 MessagePortsChangeListenerCancellerPtr(new MessagePortsChangeListenerCanceller(gContext, thisObject, watchId));
350 DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
351 MessagePortListenerManagerSingleton::Instance().unregisterListener(listenerItem);
353 if (!dplEvent->getResult())
356 switch (dplEvent->getExceptionCode())
358 case ExceptionCodes::InvalidArgumentException:
359 return JSWebAPIException::throwException(context, exception,
360 InvalidValuesException(oss.str().c_str()));
362 case ExceptionCodes::NotFoundException:
363 oss << "No watchId (" << watchId << ") has been registered.";
364 return JSWebAPIException::throwException(context, exception,
365 NotFoundException(oss.str().c_str()));
367 case ExceptionCodes::PlatformException:
368 return JSWebAPIException::throwException(context, exception,
369 UnknownException("The method cannot proceed due to a severe system error."));
372 return JSWebAPIException::throwException(context, exception,
373 UnknownException("Internal error."));
378 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
379 return JSValueMakeUndefined(context);