Update change log and spec for wrt-plugins-tizen_0.4.70
[framework/web/wrt-plugins-tizen.git] / src / Callhistory / JSCallHistory.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 #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>
31 #include <JSUtil.h>
32 #include <JSWebAPIErrorFactory.h>
33 #include <ArgumentValidator.h>
34 #include <TimeTracer.h>
35 #include <Logger.h>
36
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"
47
48
49 using namespace std;
50
51 using namespace WrtDeviceApis::Commons;
52 using namespace WrtDeviceApis::CommonsJavaScript;
53 using namespace DeviceAPI::Tizen;
54 using namespace DeviceAPI::Common;
55
56 namespace DeviceAPI {
57 namespace CallHistory {
58
59
60 JSClassRef JSCallHistory::m_jsClassRef = NULL;
61
62 JSClassDefinition JSCallHistory::m_classInfo =
63 {
64         0,
65         kJSClassAttributeNone,
66         "callhistory",
67         NULL,
68         m_property,
69         m_function,
70         initialize,
71         finalize,
72         NULL,
73         NULL,
74         NULL,
75         NULL,
76         NULL,
77         NULL,
78         NULL,
79         hasInstance,
80         NULL
81 };
82
83 JSStaticValue JSCallHistory::m_property[] = {
84         { 0, 0, 0, 0 }
85 };
86
87 JSStaticFunction JSCallHistory::m_function[] =
88 {
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 },
95         { 0, 0, 0 }
96 };
97
98 const JSClassRef DLL_EXPORT JSCallHistory::getClassRef() {
99         if (!m_jsClassRef) {
100                 m_jsClassRef = JSClassCreate(&m_classInfo);
101         }
102         return m_jsClassRef;
103 }
104
105 const JSClassDefinition* JSCallHistory::getClassInfo(){
106         return &m_classInfo;
107 }
108
109 void JSCallHistory::initialize(JSContextRef context, JSObjectRef object) {
110         JSCallHistoryPriv* priv = static_cast<JSCallHistoryPriv*>(JSObjectGetPrivate(object));
111
112         if (priv == NULL) {
113                 ICallHistoryPtr CallHistory(CallHistoryFactory::getInstance().getCallHistoryObject());
114                 priv = new JSCallHistoryPriv(context, CallHistory);
115                 if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
116                         delete priv;
117                 }
118         }
119 }
120
121 void JSCallHistory::finalize(JSObjectRef object) {
122         JSCallHistoryPriv* priv = static_cast<JSCallHistoryPriv*>(JSObjectGetPrivate(object));
123         if (priv != NULL) {
124                 JSObjectSetPrivate(object, NULL);
125                 delete priv;
126         }
127 }
128
129 JSObjectRef JSCallHistory::createJSObject(JSContextRef context, JSObjectRef object)
130 {
131         ICallHistoryPtr CallHistory(CallHistoryFactory::getInstance().getCallHistoryObject());
132         JSCallHistoryPriv* priv = new JSCallHistoryPriv(context, CallHistory);
133
134         return JSObjectMake(context, getClassRef(), priv);
135 }
136
137 bool JSCallHistory::hasInstance(JSContextRef context, JSObjectRef constructor,
138         JSValueRef possibleInstance, JSValueRef* exception) {
139         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
140 }
141
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);
145
146         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
147
148         if (!priv) {
149                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
150         }
151
152         TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_FIND);
153
154         if (argumentCount < 1) {
155                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
156         }
157
158         JSContextRef gContext = priv->getContext();
159         WrtDeviceApis::CommonsJavaScript::Converter converter(context);
160         Validator check(context, exception);
161
162         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
163
164
165     try{
166         ArgumentValidator validator(context, argumentCount, arguments);
167
168                 JSObjectRef successCB = validator.toFunction(0);
169
170                 JSObjectRef errCB = validator.toFunction(1, true);
171
172                 unsigned long limit = validator.toULong(4, true);
173                 unsigned long offset = validator.toULong(5, true);
174
175                 if(successCB != NULL)
176                         cbm->setOnSuccess(successCB);
177
178                 if(errCB != NULL)
179                         cbm->setOnError(errCB);
180
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");
185                                 }
186                         }
187                 }
188
189                 cbm->setObject(thisObject);
190
191                 CallHistoryFilterConverterFactory::ConverterType filterConverter =
192                                 CallHistoryFilterConverterFactory::getConverter(context);
193
194                 EventFindCallHistoryPtr event(new EventFindCallHistory());
195                 ICallHistoryPtr callHistory(priv->getObject());
196
197                 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
198                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
199
200                 if (argumentCount >= 3) {
201                         if(JSValueIsUndefined(context, arguments[2])) {
202                                         throw DeviceAPI::Common::TypeMismatchException("Filter is undefined");
203                         }
204
205                         if(!JSValueIsNull(context, arguments[2])){
206                                 FilterPtr filter = filterConverter->toFilter(arguments[2]);
207
208                                 if(filter == NULL){
209                                         throw DeviceAPI::Common::TypeMismatchException("Invalid Filter");
210                                 }else{
211                                         event ->setFilter(filter);
212                                 }
213                         }
214                 }
215
216                 if (argumentCount >= 4) {
217                         if(JSValueIsUndefined(context, arguments[3])) {
218                                         throw DeviceAPI::Common::TypeMismatchException("Sortmode is undefined");
219                         }
220
221                         if (!JSValueIsNull(context, arguments[3])) {
222                                 DeviceAPI::Tizen::SortModePtr sortMode = filterConverter->toSortMode(arguments[3]);
223
224                                 if(sortMode == NULL){
225                                         throw DeviceAPI::Common::TypeMismatchException("Invalid Sortmode");
226                                 }else{
227                                         event->setSortMode(filterConverter->toSortMode(arguments[3]));
228                                 }
229                         }
230                 }
231
232                 event->setLimit(limit);
233                 event->setOffset(offset);
234
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()));
247         }
248
249         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
250         return JSValueMakeUndefined(context);
251 }
252
253 JSValueRef JSCallHistory::remove(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
254         const JSValueRef arguments[], JSValueRef* exception) {
255
256         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
257
258     try{
259         ArgumentValidator validator(context, argumentCount, arguments);
260
261                 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
262
263                 if (!priv) {
264                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
265                 }
266
267                 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVE);
268
269         JSObjectRef entryObj = validator.toObject(0);
270
271                 if (argumentCount < 1) {
272                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
273                 }
274
275                 Converter converter(context);
276
277                 if (!JSValueIsObjectOfClass(context, arguments[0], JSCallHistoryEntry::getClassRef())) {
278                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : CallHistoryEntry");
279                 }
280
281                 ICallHistoryPtr callHistory(priv->getObject());
282                 if(entryObj  != NULL){
283                         CallHistoryEntryPropertiesPtr entry = converter.toCallHistoryEntryProperties(entryObj);
284                         callHistory->remove(entry->getEntryId());
285                 }
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());
296         }
297
298         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
299         return JSValueMakeUndefined(context);
300 }
301
302 JSValueRef JSCallHistory::removeBatch(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
303         const JSValueRef arguments[], JSValueRef* exception) {
304
305         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
306
307         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
308
309         if (!priv) {
310                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
311         }
312
313         TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVE_BATCH);
314
315         if (argumentCount < 1) {
316                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
317         }
318
319         JSContextRef gContext = priv->getContext();
320         Converter converter(context);
321
322         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
323         
324     try{
325         ArgumentValidator validator(context, argumentCount, arguments);
326
327         JSObjectRef entryObj = validator.toObject(0);
328         JSObjectRef successCB = validator.toFunction(1, true);
329         JSObjectRef errCB = validator.toFunction(2, true);
330
331                 if(successCB != NULL)
332                         cbm->setOnSuccess(successCB);
333
334                 if(errCB != NULL)
335                         cbm->setOnError(errCB);
336
337                 cbm->setObject(thisObject);
338
339                 EventRemoveBatchPtr event(new EventRemoveBatch());
340                 ICallHistoryPtr callHistory(priv->getObject());
341
342                 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
343                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
344
345                 CallHistoryEntryList entryList;
346                 if(entryObj != NULL)
347                         entryList = converter.toVectorOfCallHistoryEntryProperties(entryObj);
348
349                 std::vector<unsigned long> entryIds;
350
351                 if (entryList.size() > 0) {
352                         for (unsigned int i = 0; i < entryList.size(); i++) {
353                                 entryIds.push_back(entryList[i]->getEntryId());
354                         }
355                         event->setEntryIds(entryIds);
356                         callHistory->removeBatch(event);
357                         CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
358                 } else {
359                         cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid values error : Entry array is empty"));
360                 }
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()));
371         }
372
373         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
374         return JSValueMakeUndefined(context);
375 }
376
377 JSValueRef JSCallHistory::removeAll(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
378         const JSValueRef arguments[], JSValueRef* exception) {
379
380         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
381
382         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
383
384         if (!priv) {
385                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
386         }
387
388         TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVE_ALL);
389
390         JSContextRef gContext = priv->getContext();
391         Converter converter(context);
392
393         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
394
395     try{
396         ArgumentValidator validator(context, argumentCount, arguments);
397
398         JSObjectRef successCB = validator.toFunction(0, true);
399                 JSObjectRef errCB = validator.toFunction(1, true);
400
401                 if(successCB != NULL)
402                         cbm->setOnSuccess(successCB);
403                 if(errCB != NULL)       
404                         cbm->setOnError(errCB);
405
406                 cbm->setObject(thisObject);
407                 EventRemoveAllPtr event(new EventRemoveAll());
408                 ICallHistoryPtr callHistory(priv->getObject());
409
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()));
424         }
425
426         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
427         return JSValueMakeUndefined(context);
428 }
429
430 JSValueRef JSCallHistory::addChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
431         const JSValueRef arguments[], JSValueRef* exception) {
432
433     try{
434         ArgumentValidator validator(context, argumentCount, arguments);
435
436         JSObjectRef observerObj = validator.toCallbackObject(0, false,"onadded","onchanged","onremoved",NULL);
437
438                 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
439
440                 if (!priv) {
441                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
442                 }
443
444                 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_ADDLISTENER);
445
446                 if (argumentCount < 1) {
447                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
448                 }
449
450                 JSContextRef gContext = priv->getContext();
451                 Converter converter(context);
452
453                 long id = 0;
454                 if (argumentCount >= 1) {
455                         EventCallHistoryListenerPrivateDataPtr privData(converter.toEventCallHistoryListenerPrivateData(observerObj, gContext));
456
457                         EventCallHistoryListenerEmitterPtr emitter(new EventCallHistoryListenerEmitter);
458                         emitter->setListener(&CallHistoryStaticController::getInstance());
459                         emitter->setEventPrivateData(DPL::StaticPointerCast<EventCallHistoryListener::PrivateDataType>(privData));
460
461                         ICallHistoryPtr callHistory(priv->getObject());
462                         id = callHistory->addListener(emitter);
463
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);
467                 }
468                 return JSUtil::toJSValueRef(context, id);
469
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());
480         }
481 }
482
483 JSValueRef JSCallHistory::removeChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
484         const JSValueRef arguments[], JSValueRef* exception) {
485
486         long handle = 0;
487
488     try{
489         ArgumentValidator validator(context, argumentCount, arguments);
490
491         handle = validator.toLong(0);
492
493                 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
494
495                 if (!priv) {
496                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
497                 }
498
499                 TIZEN_CHECK_ACCESS(context, exception, priv, CALL_HISTORY_FUNCTION_API_REMOVELISTENER);
500
501                 JSContextRef gContext = priv->getContext();
502
503                 if (handle != 0) {
504                         ICallHistoryPtr callHistory(priv->getObject());
505                         callHistory->removeListener(handle);
506                 } else {
507                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid values error : handle");
508                 }
509
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());
523         }
524
525         return JSValueMakeUndefined(context);
526 }
527
528 }
529 }
530