Update change log and spec for wrt-plugins-tizen_0.4.46
[platform/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.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 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         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
146                         CALL_HISTORY_FUNCTION_API_FIND);
147
148         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
149
150         if (argumentCount < 1) {
151                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
152         }
153
154         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
155
156         if (!priv) {
157                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
158         }
159
160         JSContextRef gContext = priv->getContext();
161         WrtDeviceApis::CommonsJavaScript::Converter converter(context);
162         Validator check(context, exception);
163
164         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
165
166
167     try{
168         ArgumentValidator validator(context, argumentCount, arguments);
169
170                 JSObjectRef successCB = validator.toFunction(0);
171
172                 JSObjectRef errCB = validator.toFunction(1, true);
173
174                 unsigned long limit = validator.toULong(4, true);
175                 unsigned long offset = validator.toULong(5, true);
176
177                 if(successCB != NULL)
178                         cbm->setOnSuccess(successCB);
179
180                 if(errCB != NULL)
181                         cbm->setOnError(errCB);
182
183                 if (argumentCount >= 3) {
184                         if (!JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
185                                 if (!JSValueIsObject(context, arguments[2])) {
186                                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : filter");
187                                 }
188                         }
189                 }
190
191                 cbm->setObject(thisObject);
192
193                 CallHistoryFilterConverterFactory::ConverterType filterConverter =
194                                 CallHistoryFilterConverterFactory::getConverter(context);
195
196                 EventFindCallHistoryPtr event(new EventFindCallHistory());
197                 ICallHistoryPtr callHistory(priv->getObject());
198
199                 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
200                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
201
202                 if (argumentCount >= 3) {
203                         if(JSValueIsUndefined(context, arguments[2])) {
204                                         throw DeviceAPI::Common::TypeMismatchException("Filter is undefined");
205                         }
206
207                         if(!JSValueIsNull(context, arguments[2])){
208                                 FilterPtr filter = filterConverter->toFilter(arguments[2]);
209
210                                 if(filter == NULL){
211                                         throw DeviceAPI::Common::TypeMismatchException("Invalid Filter");
212                                 }else{
213                                         event ->setFilter(filter);
214                                 }
215                         }
216                 }
217
218                 if (argumentCount >= 4) {
219                         if(JSValueIsUndefined(context, arguments[3])) {
220                                         throw DeviceAPI::Common::TypeMismatchException("Sortmode is undefined");
221                         }
222
223                         if (!JSValueIsNull(context, arguments[3])) {
224                                 DeviceAPI::Tizen::SortModePtr sortMode = filterConverter->toSortMode(arguments[3]);
225
226                                 if(sortMode == NULL){
227                                         throw DeviceAPI::Common::TypeMismatchException("Invalid Sortmode");
228                                 }else{
229                                         event->setSortMode(filterConverter->toSortMode(arguments[3]));
230                                 }
231                         }
232                 }
233
234                 event->setLimit(limit);
235                 event->setOffset(offset);
236
237                 callHistory->find(event);
238                 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
239         } catch(const BasePlatformException& err){
240         return JSWebAPIErrorFactory::postException(context, exception, err);
241     } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
242                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
243         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
244                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()));
245         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
246                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
247         } catch(const WrtDeviceApis::Commons::Exception& ex) {
248                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
249         }
250
251         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
252         return JSValueMakeUndefined(context);
253 }
254
255 JSValueRef JSCallHistory::remove(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
256         const JSValueRef arguments[], JSValueRef* exception) {
257
258         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
259         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
260                         CALL_HISTORY_FUNCTION_API_REMOVE);
261
262         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
263
264     try{
265         ArgumentValidator validator(context, argumentCount, arguments);
266
267         JSObjectRef entryObj = validator.toObject(0);
268
269                 if (argumentCount < 1) {
270                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
271                 }
272
273                 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
274
275                 if (!priv) {
276                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
277                 }
278
279                 Converter converter(context);
280
281                 if (!JSValueIsObjectOfClass(context, arguments[0], JSCallHistoryEntry::getClassRef())) {
282                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : CallHistoryEntry");
283                 }
284
285                 ICallHistoryPtr callHistory(priv->getObject());
286                 if(entryObj  != NULL){
287                         CallHistoryEntryPropertiesPtr entry = converter.toCallHistoryEntryProperties(entryObj);
288                         callHistory->remove(entry->getEntryId());
289                 }
290         } catch(const BasePlatformException& err){
291         return JSWebAPIErrorFactory::postException(context, exception, err);
292     } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
293                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
294         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
295                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage());
296         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
297                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
298         } catch(const WrtDeviceApis::Commons::Exception& ex) {
299                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
300         }
301
302         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
303         return JSValueMakeUndefined(context);
304 }
305
306 JSValueRef JSCallHistory::removeBatch(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
307         const JSValueRef arguments[], JSValueRef* exception) {
308
309         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
310         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
311                         CALL_HISTORY_FUNCTION_API_REMOVE_BATCH);
312
313         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
314
315         if (argumentCount < 1) {
316                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
317         }
318
319         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
320
321         if (!priv) {
322                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
323         }
324
325         JSContextRef gContext = priv->getContext();
326         Converter converter(context);
327
328         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
329         
330     try{
331         ArgumentValidator validator(context, argumentCount, arguments);
332
333         JSObjectRef entryObj = validator.toObject(0);
334         JSObjectRef successCB = validator.toFunction(1, true);
335         JSObjectRef errCB = validator.toFunction(2, true);
336
337                 if(successCB != NULL)
338                         cbm->setOnSuccess(successCB);
339
340                 if(errCB != NULL)
341                         cbm->setOnError(errCB);
342
343                 cbm->setObject(thisObject);
344
345                 EventRemoveBatchPtr event(new EventRemoveBatch());
346                 ICallHistoryPtr callHistory(priv->getObject());
347
348                 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
349                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
350
351                 CallHistoryEntryList entryList;
352                 if(entryObj != NULL)
353                         entryList = converter.toVectorOfCallHistoryEntryProperties(entryObj);
354
355                 std::vector<unsigned long> entryIds;
356
357                 if (entryList.size() > 0) {
358                         for (unsigned int i = 0; i < entryList.size(); i++) {
359                                 entryIds.push_back(entryList[i]->getEntryId());
360                         }
361                         event->setEntryIds(entryIds);
362                         callHistory->removeBatch(event);
363                         CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
364                 } else {
365                         cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid values error : Entry array is empty"));
366                 }
367         } catch(const BasePlatformException& err){
368         return JSWebAPIErrorFactory::postException(context, exception, err);
369     } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
370                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
371         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
372                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()));
373         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
374                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
375         } catch(const WrtDeviceApis::Commons::Exception& ex) {
376                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
377         }
378
379         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
380         return JSValueMakeUndefined(context);
381 }
382
383 JSValueRef JSCallHistory::removeAll(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
384         const JSValueRef arguments[], JSValueRef* exception) {
385
386         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
387         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
388                         CALL_HISTORY_FUNCTION_API_REMOVE_ALL);
389
390         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
391
392         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
393
394         if (!priv) {
395                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
396         }
397
398         JSContextRef gContext = priv->getContext();
399         Converter converter(context);
400
401         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
402
403     try{
404         ArgumentValidator validator(context, argumentCount, arguments);
405
406         JSObjectRef successCB = validator.toFunction(0, true);
407                 JSObjectRef errCB = validator.toFunction(1, true);
408
409                 if(successCB != NULL)
410                         cbm->setOnSuccess(successCB);
411                 if(errCB != NULL)       
412                         cbm->setOnError(errCB);
413
414                 cbm->setObject(thisObject);
415                 EventRemoveAllPtr event(new EventRemoveAll());
416                 ICallHistoryPtr callHistory(priv->getObject());
417
418                 event->setPrivateData(DPL::StaticPointerCast<IEventPrivateData> (cbm));
419                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
420                 callHistory->removeAll(event);
421                 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
422         } catch(const BasePlatformException& err){
423         return JSWebAPIErrorFactory::postException(context, exception, err);
424     } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
425                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
426         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
427                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage()));
428         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
429                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
430         } catch(const WrtDeviceApis::Commons::Exception& ex) {
431                 cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage()));
432         }
433
434         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
435         return JSValueMakeUndefined(context);
436 }
437
438 JSValueRef JSCallHistory::addChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
439         const JSValueRef arguments[], JSValueRef* exception) {
440
441         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
442                         CALL_HISTORY_FUNCTION_API_ADDLISTENER);
443
444         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
445
446     try{
447         ArgumentValidator validator(context, argumentCount, arguments);
448
449         JSObjectRef observerObj = validator.toCallbackObject(0, false,"onadded","onchanged","onremoved",NULL);
450
451                 if (argumentCount < 1) {
452                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error");
453                 }
454
455                 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
456
457                 if (!priv) {
458                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
459                 }
460
461                 JSContextRef gContext = priv->getContext();
462                 Converter converter(context);
463
464                 long id = 0;
465                 if (argumentCount >= 1) {
466                         EventCallHistoryListenerPrivateDataPtr privData(converter.toEventCallHistoryListenerPrivateData(observerObj, gContext));
467
468                         EventCallHistoryListenerEmitterPtr emitter(new EventCallHistoryListenerEmitter);
469                         emitter->setListener(&CallHistoryStaticController::getInstance());
470                         emitter->setEventPrivateData(DPL::StaticPointerCast<EventCallHistoryListener::PrivateDataType>(privData));
471
472                         ICallHistoryPtr callHistory(priv->getObject());
473                         id = callHistory->addListener(emitter);
474
475                         CallHistoryListenerCancellerPtr canceller = CallHistoryListenerCancellerPtr(new CallHistoryListenerCanceller(gContext, thisObject, id));
476                         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
477                         CallHistoryListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
478                 }
479                 return JSUtil::toJSValueRef(context, id);
480
481         } catch(const BasePlatformException& err){
482         return JSWebAPIErrorFactory::postException(context, exception, err);
483     } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
484                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
485         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
486                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage());
487         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
488                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
489         } catch(const WrtDeviceApis::Commons::Exception& ex) {
490                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
491         }
492 }
493
494 JSValueRef JSCallHistory::removeChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
495         const JSValueRef arguments[], JSValueRef* exception) {
496
497         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
498                         CALL_HISTORY_FUNCTION_API_REMOVELISTENER);
499
500         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
501         long handle = 0;
502
503     try{
504         ArgumentValidator validator(context, argumentCount, arguments);
505
506         handle = validator.toLong(0);
507
508                 JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
509
510                 if (!priv) {
511                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
512                 }
513
514                 JSContextRef gContext = priv->getContext();
515
516                 if (handle != 0) {
517                         ICallHistoryPtr callHistory(priv->getObject());
518                         callHistory->removeListener(handle);
519                 } else {
520                         return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Invalid values error : handle");
521                 }
522
523                 CallHistoryListenerCancellerPtr canceller = CallHistoryListenerCancellerPtr(new CallHistoryListenerCanceller(gContext, thisObject, handle));
524                 DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
525                 CallHistoryListenerManagerSingleton::Instance().unregisterListener(listenerItem);
526         } catch(const BasePlatformException& err){
527         return JSWebAPIErrorFactory::postException(context, exception, err);
528     } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
529                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, ex.GetMessage());
530         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
531                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, ex.GetMessage());
532         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
533                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
534         } catch(const WrtDeviceApis::Commons::Exception& ex) {
535                 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, ex.GetMessage());
536         }
537
538         return JSValueMakeUndefined(context);
539 }
540
541 }
542 }
543