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 #include <CommonsJavaScript/Validator.h>
20 #include <CommonsJavaScript/JSUtils.h>
21 #include <CommonsJavaScript/JSCallbackManager.h>
22 #include <CommonsJavaScript/Utils.h>
23 #include <FilterConverter.h>
24 #include "EventFindCallHistory.h"
25 #include "EventRemoveBatch.h"
26 #include "EventRemoveAll.h"
27 #include "EventCallHistoryListener.h"
28 #include "CallHistoryFactory.h"
29 #include "ICallHistory.h"
30 #include <SecurityExceptions.h>
32 #include <JSWebAPIErrorFactory.h>
33 #include <ArgumentValidator.h>
34 #include <TimeTracer.h>
37 #include "JSCallHistoryEntry.h"
38 #include "JSCallHistory.h"
39 #include "CallHistoryStaticController.h"
40 #include "CallHistoryMultiCallback.h"
41 #include "ResponseDispatcher.h"
42 #include "Converter.h"
43 #include "plugin_config_impl.h"
44 #include "CallHistoryAsyncCallbackManager.h"
45 #include "CallHistoryListenerManager.h"
46 #include "CallHistoryFilterConverter.h"
51 using namespace WrtDeviceApis::Commons;
52 using namespace WrtDeviceApis::CommonsJavaScript;
53 using namespace DeviceAPI::Tizen;
54 using namespace DeviceAPI::Common;
57 namespace CallHistory {
60 JSClassRef JSCallHistory::m_jsClassRef = NULL;
62 JSClassDefinition JSCallHistory::m_classInfo =
65 kJSClassAttributeNone,
83 JSStaticValue JSCallHistory::m_property[] = {
87 JSStaticFunction JSCallHistory::m_function[] =
89 { "find", JSCallHistory::find, kJSPropertyAttributeNone },
90 { "remove", JSCallHistory::remove, kJSPropertyAttributeNone },
91 { "removeBatch", JSCallHistory::removeBatch, kJSPropertyAttributeNone },
92 { "removeAll", JSCallHistory::removeAll, kJSPropertyAttributeNone },
93 { "addChangeListener", JSCallHistory::addChangeListener, kJSPropertyAttributeNone },
94 { "removeChangeListener", JSCallHistory::removeChangeListener, kJSPropertyAttributeNone },
98 const JSClassRef DLL_EXPORT JSCallHistory::getClassRef() {
100 m_jsClassRef = JSClassCreate(&m_classInfo);
105 const JSClassDefinition* JSCallHistory::getClassInfo(){
109 void JSCallHistory::initialize(JSContextRef context, JSObjectRef object) {
110 JSCallHistoryPriv* priv = static_cast<JSCallHistoryPriv*>(JSObjectGetPrivate(object));
113 ICallHistoryPtr CallHistory(CallHistoryFactory::getInstance().getCallHistoryObject());
114 priv = new JSCallHistoryPriv(context, CallHistory);
115 if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
121 void JSCallHistory::finalize(JSObjectRef object) {
122 JSCallHistoryPriv* priv = static_cast<JSCallHistoryPriv*>(JSObjectGetPrivate(object));
124 JSObjectSetPrivate(object, NULL);
129 JSObjectRef JSCallHistory::createJSObject(JSContextRef context, JSObjectRef object)
131 ICallHistoryPtr CallHistory(CallHistoryFactory::getInstance().getCallHistoryObject());
132 JSCallHistoryPriv* priv = new JSCallHistoryPriv(context, CallHistory);
134 return JSObjectMake(context, getClassRef(), priv);
137 bool JSCallHistory::hasInstance(JSContextRef context, JSObjectRef constructor,
138 JSValueRef possibleInstance, JSValueRef* exception) {
139 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
142 JSValueRef JSCallHistory::find(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
143 const JSValueRef arguments[], JSValueRef* exception) {
144 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
146 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
149 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
152 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_FIND);
154 if (argumentCount < 1) {
155 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
158 JSContextRef gContext = priv->getContext();
159 WrtDeviceApis::CommonsJavaScript::Converter converter(context);
160 Validator check(context, exception);
162 JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
166 ArgumentValidator validator(context, argumentCount, arguments);
168 JSObjectRef successCB = validator.toFunction(0);
170 JSObjectRef errCB = validator.toFunction(1, true);
172 unsigned long limit = validator.toULong(4, true);
173 unsigned long offset = validator.toULong(5, true);
175 if(successCB != NULL)
176 cbm->setOnSuccess(successCB);
179 cbm->setOnError(errCB);
181 if (argumentCount >= 3) {
182 if (!JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
183 if (!JSValueIsObject(context, arguments[2])) {
184 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : filter");
189 cbm->setObject(thisObject);
191 CallHistoryFilterConverterFactory::ConverterType filterConverter =
192 CallHistoryFilterConverterFactory::getConverter(context);
194 EventFindCallHistoryPtr event(new EventFindCallHistory());
195 ICallHistoryPtr callHistory(priv->getObject());
197 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
198 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
200 if (argumentCount >= 3) {
201 if(JSValueIsUndefined(context, arguments[2])) {
202 throw DeviceAPI::Common::TypeMismatchException("Filter is undefined");
205 if(!JSValueIsNull(context, arguments[2])){
206 FilterPtr filter = filterConverter->toFilter(arguments[2]);
209 throw DeviceAPI::Common::TypeMismatchException("Invalid Filter");
211 event ->setFilter(filter);
216 if (argumentCount >= 4) {
217 if(JSValueIsUndefined(context, arguments[3])) {
218 throw DeviceAPI::Common::TypeMismatchException("Sortmode is undefined");
221 if (!JSValueIsNull(context, arguments[3])) {
222 DeviceAPI::Tizen::SortModePtr sortMode = filterConverter->toSortMode(arguments[3]);
224 if(sortMode == NULL){
225 throw DeviceAPI::Common::TypeMismatchException("Invalid Sortmode");
227 event->setSortMode(filterConverter->toSortMode(arguments[3]));
232 event->setLimit(limit);
233 event->setOffset(offset);
235 callHistory->find(event);
236 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
237 } catch(const BasePlatformException& err){
238 return JSWebAPIErrorFactory::postException(context, exception, err);
239 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
240 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
241 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
242 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()));
243 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
244 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
245 } catch(const WrtDeviceApis::Commons::Exception& ex) {
246 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
249 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
250 return JSValueMakeUndefined(context);
253 JSValueRef JSCallHistory::remove(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
254 const JSValueRef arguments[], JSValueRef* exception) {
256 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
259 ArgumentValidator validator(context, argumentCount, arguments);
261 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
264 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
267 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVE);
269 JSObjectRef entryObj = validator.toObject(0);
271 if (argumentCount < 1) {
272 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
275 Converter converter(context);
277 if (!JSValueIsObjectOfClass(context, arguments[0], JSCallHistoryEntry::getClassRef())) {
278 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : CallHistoryEntry");
281 ICallHistoryPtr callHistory(priv->getObject());
282 if(entryObj != NULL){
283 CallHistoryEntryPropertiesPtr entry = converter.toCallHistoryEntryProperties(entryObj);
284 callHistory->remove(entry->getEntryId());
286 } catch(const BasePlatformException& err){
287 return JSWebAPIErrorFactory::postException(context, exception, err);
288 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
289 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
290 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
291 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage());
292 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
293 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
294 } catch(const WrtDeviceApis::Commons::Exception& ex) {
295 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
298 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
299 return JSValueMakeUndefined(context);
302 JSValueRef JSCallHistory::removeBatch(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
303 const JSValueRef arguments[], JSValueRef* exception) {
305 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
307 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
310 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
313 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVE_BATCH);
315 if (argumentCount < 1) {
316 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
319 JSContextRef gContext = priv->getContext();
320 Converter converter(context);
322 JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
325 ArgumentValidator validator(context, argumentCount, arguments);
327 JSObjectRef entryObj = validator.toObject(0);
328 JSObjectRef successCB = validator.toFunction(1, true);
329 JSObjectRef errCB = validator.toFunction(2, true);
331 if(successCB != NULL)
332 cbm->setOnSuccess(successCB);
335 cbm->setOnError(errCB);
337 cbm->setObject(thisObject);
339 EventRemoveBatchPtr event(new EventRemoveBatch());
340 ICallHistoryPtr callHistory(priv->getObject());
342 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
343 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
345 CallHistoryEntryList entryList;
347 entryList = converter.toVectorOfCallHistoryEntryProperties(entryObj);
349 std::vector<unsigned long> entryIds;
351 if (entryList.size() > 0) {
352 for (unsigned int i = 0; i < entryList.size(); i++) {
353 entryIds.push_back(entryList[i]->getEntryId());
355 event->setEntryIds(entryIds);
356 callHistory->removeBatch(event);
357 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
359 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid values error : Entry array is empty"));
361 } catch(const BasePlatformException& err){
362 return JSWebAPIErrorFactory::postException(context, exception, err);
363 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
364 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
365 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
366 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()));
367 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
368 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
369 } catch(const WrtDeviceApis::Commons::Exception& ex) {
370 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
373 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
374 return JSValueMakeUndefined(context);
377 JSValueRef JSCallHistory::removeAll(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
378 const JSValueRef arguments[], JSValueRef* exception) {
380 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
382 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
385 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
388 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVE_ALL);
390 JSContextRef gContext = priv->getContext();
391 Converter converter(context);
393 JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
396 ArgumentValidator validator(context, argumentCount, arguments);
398 JSObjectRef successCB = validator.toFunction(0, true);
399 JSObjectRef errCB = validator.toFunction(1, true);
401 if(successCB != NULL)
402 cbm->setOnSuccess(successCB);
404 cbm->setOnError(errCB);
406 cbm->setObject(thisObject);
407 EventRemoveAllPtr event(new EventRemoveAll());
408 ICallHistoryPtr callHistory(priv->getObject());
410 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
411 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
412 callHistory->removeAll(event);
413 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
414 } catch(const BasePlatformException& err){
415 return JSWebAPIErrorFactory::postException(context, exception, err);
416 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
417 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
418 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
419 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()));
420 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
421 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
422 } catch(const WrtDeviceApis::Commons::Exception& ex) {
423 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
426 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
427 return JSValueMakeUndefined(context);
430 JSValueRef JSCallHistory::addChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
431 const JSValueRef arguments[], JSValueRef* exception) {
434 ArgumentValidator validator(context, argumentCount, arguments);
436 JSObjectRef observerObj = validator.toCallbackObject(0, false,"onadded","onchanged","onremoved",NULL);
438 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
441 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
444 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_ADDLISTENER);
446 if (argumentCount < 1) {
447 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
450 JSContextRef gContext = priv->getContext();
451 Converter converter(context);
454 if (argumentCount >= 1) {
455 EventCallHistoryListenerPrivateDataPtr privData(converter.toEventCallHistoryListenerPrivateData(observerObj, gContext));
457 EventCallHistoryListenerEmitterPtr emitter(new EventCallHistoryListenerEmitter);
458 emitter->setListener(&CallHistoryStaticController::getInstance());
459 emitter->setEventPrivateData(DPL::StaticPointerCast<EventCallHistoryListener::PrivateDataType>(privData));
461 ICallHistoryPtr callHistory(priv->getObject());
462 id = callHistory->addListener(emitter);
464 CallHistoryListenerCancellerPtr canceller = CallHistoryListenerCancellerPtr(new CallHistoryListenerCanceller(gContext, thisObject, id));
465 DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
466 CallHistoryListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
468 return JSUtil::toJSValueRef(context, id);
470 } catch(const BasePlatformException& err){
471 return JSWebAPIErrorFactory::postException(context, exception, err);
472 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
473 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
474 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
475 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage());
476 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
477 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
478 } catch(const WrtDeviceApis::Commons::Exception& ex) {
479 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
483 JSValueRef JSCallHistory::removeChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
484 const JSValueRef arguments[], JSValueRef* exception) {
489 ArgumentValidator validator(context, argumentCount, arguments);
491 handle = validator.toLong(0);
493 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
496 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
499 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVELISTENER);
501 JSContextRef gContext = priv->getContext();
504 ICallHistoryPtr callHistory(priv->getObject());
505 callHistory->removeListener(handle);
507 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid values error : handle");
510 CallHistoryListenerCancellerPtr canceller = CallHistoryListenerCancellerPtr(new CallHistoryListenerCanceller(gContext, thisObject, handle));
511 DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
512 CallHistoryListenerManagerSingleton::Instance().unregisterListener(listenerItem);
513 } catch(const BasePlatformException& err){
514 return JSWebAPIErrorFactory::postException(context, exception, err);
515 } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
516 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
517 } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
518 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage());
519 } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
520 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
521 } catch(const WrtDeviceApis::Commons::Exception& ex) {
522 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
525 return JSValueMakeUndefined(context);