Update change log and spec for wrt-plugins-tizen_0.4.9
[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 <JSTizenExceptionFactory.h>
31 #include <JSTizenException.h>
32 #include <SecurityExceptions.h>
33 #include <JSUtil.h>
34
35 #include "JSCallHistoryEntry.h"
36 #include "JSCallHistory.h"
37 #include "CallHistoryStaticController.h"
38 #include "CallHistoryMultiCallback.h"
39 #include "ResponseDispatcher.h"
40 #include "Converter.h"
41 #include "plugin_config.h"
42 #include "CallHistoryAsyncCallbackManager.h"
43 #include "CallHistoryListenerManager.h"
44
45
46
47 using namespace std;
48 using namespace DPL;
49 using namespace WrtDeviceApis::Commons;
50 using namespace WrtDeviceApis::CommonsJavaScript;
51 using namespace DeviceAPI::Tizen;
52 using namespace DeviceAPI::Common;
53
54 namespace DeviceAPI {
55 namespace CallHistory {
56
57
58 JSClassRef JSCallHistory::m_jsClassRef = NULL;
59
60 JSClassDefinition JSCallHistory::m_classInfo =
61 {
62         0,
63         kJSClassAttributeNone,
64         "callhistory",
65         NULL,
66         m_property,
67         m_function,
68         initialize,
69         finalize,
70         NULL,
71         NULL,
72         NULL,
73         NULL,
74         NULL,
75         NULL,
76         NULL,
77         hasInstance,
78         NULL
79 };
80
81 JSStaticValue JSCallHistory::m_property[] = {
82         { 0, 0, 0, 0 }
83 };
84
85 JSStaticFunction JSCallHistory::m_function[] =
86 {
87         { "find", JSCallHistory::find, kJSPropertyAttributeNone },
88         { "remove",      JSCallHistory::remove,      kJSPropertyAttributeNone },
89         { "removeBatch",      JSCallHistory::removeBatch,      kJSPropertyAttributeNone },
90         { "removeAll",      JSCallHistory::removeAll,      kJSPropertyAttributeNone },
91         { "addChangeListener",      JSCallHistory::addChangeListener,      kJSPropertyAttributeNone },
92         { "removeChangeListener",      JSCallHistory::removeChangeListener,      kJSPropertyAttributeNone },
93         { 0, 0, 0 }
94 };
95
96 const JSClassRef JSCallHistory::getClassRef() {
97         if (!m_jsClassRef) {
98                 m_jsClassRef = JSClassCreate(&m_classInfo);
99         }
100         return m_jsClassRef;
101 }
102
103 const JSClassDefinition* JSCallHistory::getClassInfo(){
104         return &m_classInfo;
105 }
106
107 void JSCallHistory::initialize(JSContextRef context, JSObjectRef object) {
108         JSCallHistoryPriv* priv = static_cast<JSCallHistoryPriv*>(JSObjectGetPrivate(object));
109
110         if (priv == NULL) {
111                 ICallHistoryPtr CallHistory(CallHistoryFactory::getInstance().getCallHistoryObject());
112                 priv = new JSCallHistoryPriv(context, CallHistory);
113                 if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) {
114                         delete priv;
115                 }
116         }
117 }
118
119 void JSCallHistory::finalize(JSObjectRef object) {
120         JSCallHistoryPriv* priv = static_cast<JSCallHistoryPriv*>(JSObjectGetPrivate(object));
121         if (priv != NULL) {
122                 JSObjectSetPrivate(object, NULL);
123                 delete priv;
124         }
125 }
126
127 JSObjectRef JSCallHistory::createJSObject(JSContextRef context, JSObjectRef object)
128 {
129         ICallHistoryPtr CallHistory(CallHistoryFactory::getInstance().getCallHistoryObject());
130         JSCallHistoryPriv* priv = new JSCallHistoryPriv(context, CallHistory);
131
132         return JSObjectMake(context, getClassRef(), priv);
133 }
134
135 bool JSCallHistory::hasInstance(JSContextRef context, JSObjectRef constructor,
136         JSValueRef possibleInstance, JSValueRef* exception) {
137         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
138 }
139
140 JSValueRef JSCallHistory::find(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
141         const JSValueRef arguments[], JSValueRef* exception) {
142
143         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
144                         CALL_HISTORY_FUNCTION_API_FIND);
145
146         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
147
148         if (argumentCount < 1) {
149                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
150         }
151
152         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
153
154         if (!priv) {
155                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
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         try {
165                 if (argumentCount >= 1) {
166                         if (JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0])) {
167                                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : success callback ");
168                         } else if (!JSObjectIsFunction(context, converter.toJSObjectRef(arguments[0]))) {
169                                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : success callback ");
170                         }
171                         cbm->setOnSuccess(arguments[0]);
172                 }
173
174                 if (argumentCount >= 2) {
175                         if (!JSValueIsNull(context, arguments[1]) && !JSValueIsUndefined(context, arguments[1])) {
176                                 if (!JSObjectIsFunction(context, converter.toJSObjectRef(arguments[1]))) {
177                                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : error callback ");
178                                 }
179                                 cbm->setOnError(arguments[1]);
180                         }
181                 }
182
183                 if (argumentCount >= 3) {
184                         if (!JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
185                                 if (!JSValueIsObject(context, arguments[2])) {
186                                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : filter");
187                                 }
188                         }
189                 }
190
191                 cbm->setObject(thisObject);
192
193                 FilterConverterFactory::ConverterType filterConverter = FilterConverterFactory::getConverter(context);
194
195                 EventFindCallHistoryPtr event(new EventFindCallHistory());
196                 ICallHistoryPtr callHistory(priv->getObject());
197
198                 event->setPrivateData(StaticPointerCast<IEventPrivateData> (cbm));
199                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
200
201                 if (argumentCount >= 3) {
202                         if (!check.isNullOrUndefined(arguments[2])) {
203                                 FilterPtr filter = filterConverter->toFilter(arguments[2]);
204                                 event ->setFilter(filter);
205                         }
206                 }
207
208                 if (argumentCount >= 4) {
209                         if (!check.isNullOrUndefined(arguments[3])) {
210                                 event->setSortMode(filterConverter->toSortMode(arguments[3]));
211                         }
212                 }
213
214                 if (argumentCount >= 5) {
215                         if (!check.isNullOrUndefined(arguments[4])) {
216                                 event->setLimit(converter.toULong(arguments[4]));
217                         }
218                 }
219
220                 if (argumentCount >= 6) {
221                         if (!check.isNullOrUndefined(arguments[5])) {
222                                 event->setOffset(converter.toULong(arguments[5]));
223                         }
224                 }
225                 callHistory->find(event);
226                 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
227         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
228                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
229         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
230                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage()));
231         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
232                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, ex.GetMessage()));
233         } catch(const WrtDeviceApis::Commons::Exception& ex) {
234                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, ex.GetMessage()));
235         }
236
237         return JSValueMakeUndefined(context);
238 }
239
240 JSValueRef JSCallHistory::remove(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
241         const JSValueRef arguments[], JSValueRef* exception) {
242
243         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
244                         CALL_HISTORY_FUNCTION_API_REMOVE);
245
246         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
247
248         if (argumentCount < 1) {
249                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
250         }
251
252         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
253
254         if (!priv) {
255                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
256         }
257
258         Converter converter(context);
259
260         try {
261                 if (!JSValueIsObjectOfClass(context, arguments[0], JSCallHistoryEntry::getClassRef())) {
262                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : CallHistoryEntry");
263                 }
264
265                 ICallHistoryPtr callHistory(priv->getObject());
266                 CallHistoryEntryPropertiesPtr entry = converter.toCallHistoryEntryProperties(arguments[0]);
267                 callHistory->remove(entry->getEntryId());
268         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
269                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
270         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
271                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
272         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
273                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
274         } catch(const WrtDeviceApis::Commons::Exception& ex) {
275                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
276         }
277
278         return JSValueMakeUndefined(context);
279 }
280
281 JSValueRef JSCallHistory::removeBatch(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
282         const JSValueRef arguments[], JSValueRef* exception) {
283
284         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
285                         CALL_HISTORY_FUNCTION_API_REMOVE_BATCH);
286
287         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
288
289         if (argumentCount < 1) {
290                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
291         }
292
293         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
294
295         if (!priv) {
296                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
297         }
298
299         JSContextRef gContext = priv->getContext();
300         Converter converter(context);
301
302         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
303         try {
304                 if (JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0])) {
305                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Invalid values error : CallHistoryEntry array");
306                 } else if (!JSIsArrayValue(context, arguments[0])) {
307                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : CallHistoryEntry array");
308                 }
309
310                 if (argumentCount >= 2) {
311                         if (!JSValueIsNull(context, arguments[1]) && !JSValueIsUndefined(context, arguments[1])) {
312                                 if (!JSObjectIsFunction(context, converter.toJSObjectRef(arguments[1]))) {
313                                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : success callback");
314                                 }
315                                 cbm->setOnSuccess(arguments[1]);
316                         }
317                 }
318
319                 if (argumentCount >= 3) {
320                         if (!JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
321                                 if (!JSObjectIsFunction(context, converter.toJSObjectRef(arguments[2]))) {
322                                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : error callback");
323                                 }
324                                 cbm->setOnError(arguments[2]);
325                         }
326                 }
327
328                 cbm->setObject(thisObject);
329
330                 EventRemoveBatchPtr event(new EventRemoveBatch());
331                 ICallHistoryPtr callHistory(priv->getObject());
332
333                 event->setPrivateData(StaticPointerCast<IEventPrivateData> (cbm));
334                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
335
336                 CallHistoryEntryList entryList = converter.toVectorOfCallHistoryEntryProperties(arguments[0]);
337
338                 std::vector<unsigned long> entryIds;
339
340                 if (entryList.size() > 0) {
341                         for (unsigned int i = 0; i < entryList.size(); i++) {
342                                 entryIds.push_back(entryList[i]->getEntryId());
343                         }
344                         event->setEntryIds(entryIds);
345                         callHistory->removeBatch(event);
346                         CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
347                 } else {
348                         cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid values error : Entry array is empty"));
349                 }
350         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
351                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
352         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
353                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage()));
354         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
355                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, ex.GetMessage()));
356         } catch(const WrtDeviceApis::Commons::Exception& ex) {
357                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, ex.GetMessage()));
358         }
359
360         return JSValueMakeUndefined(context);
361 }
362
363 JSValueRef JSCallHistory::removeAll(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
364         const JSValueRef arguments[], JSValueRef* exception) {
365
366         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
367                         CALL_HISTORY_FUNCTION_API_REMOVE_ALL);
368
369         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
370
371         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
372
373         if (!priv) {
374                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
375         }
376
377         JSContextRef gContext = priv->getContext();
378         Converter converter(context);
379
380         JSCallbackManagerPtr cbm(JSCallbackManager::createObject(gContext));
381
382         try {
383                 if (argumentCount >= 1) {
384                         if (!JSValueIsNull(context, arguments[0]) && !JSValueIsUndefined(context, arguments[0])) {
385                                 if (!JSObjectIsFunction(context, converter.toJSObjectRef(arguments[0]))) {
386                                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : success callback");
387                                 }
388                                 cbm->setOnSuccess(arguments[0]);
389                         }
390                 }
391
392                 if (argumentCount >= 2) {
393                         if (!JSValueIsNull(context, arguments[1]) && !JSValueIsUndefined(context, arguments[1])) {
394                                 if (!JSObjectIsFunction(context, converter.toJSObjectRef(arguments[1]))) {
395                                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : error callback");
396                                 }
397                                 cbm->setOnError(arguments[1]);
398                         }
399                 }
400
401                 cbm->setObject(thisObject);
402                 EventRemoveAllPtr event(new EventRemoveAll());
403                 ICallHistoryPtr callHistory(priv->getObject());
404
405                 event->setPrivateData(StaticPointerCast<IEventPrivateData> (cbm));
406                 event->setForAsynchronousCall(&ResponseDispatcher::getInstance());
407                 callHistory->removeAll(event);
408                 CallHistoryAsyncCallbackManagerSingleton::Instance().registerCallbackManager(cbm, gContext);
409         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
410                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
411         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
412                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage()));
413         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
414                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, ex.GetMessage()));
415         } catch(const WrtDeviceApis::Commons::Exception& ex) {
416                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR, ex.GetMessage()));
417         }
418
419         return JSValueMakeUndefined(context);
420 }
421
422 JSValueRef JSCallHistory::deleteRecording(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
423         const JSValueRef arguments[], JSValueRef* exception) {
424
425         return JSValueMakeUndefined(context);
426 }
427
428 JSValueRef JSCallHistory::addChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
429         const JSValueRef arguments[], JSValueRef* exception) {
430
431         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
432                         CALL_HISTORY_FUNCTION_API_ADDLISTENER);
433
434         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
435
436         if (argumentCount < 1) {
437                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
438         }
439
440         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
441
442         if (!priv) {
443                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
444         }
445
446         JSContextRef gContext = priv->getContext();
447         Converter converter(context);
448
449         try {
450                 long id = 0;
451                 if (argumentCount >= 1) {
452                         EventCallHistoryListenerPrivateDataPtr privData(converter.toEventCallHistoryListenerPrivateData(arguments[0], gContext));
453
454                         EventCallHistoryListenerEmitterPtr emitter(new EventCallHistoryListenerEmitter);
455                         emitter->setListener(&CallHistoryStaticController::getInstance());
456                         emitter->setEventPrivateData(DPL::StaticPointerCast<EventCallHistoryListener::PrivateDataType>(privData));
457
458                         ICallHistoryPtr callHistory(priv->getObject());
459                         id = callHistory->addListener(emitter);
460
461                         LogDebug("addChangeListener : id [" <<id<<"]");
462
463                         CallHistoryListenerCancellerPtr canceller = CallHistoryListenerCancellerPtr(new CallHistoryListenerCanceller(gContext, thisObject, id));
464                         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
465                         CallHistoryListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
466                 }
467                 return JSUtil::toJSValueRef(context, id);
468
469         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
470                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
471         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
472                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
473         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
474                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
475         } catch(const WrtDeviceApis::Commons::Exception& ex) {
476                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
477         }
478 }
479
480 JSValueRef JSCallHistory::removeChangeListener(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount,
481         const JSValueRef arguments[], JSValueRef* exception) {
482
483         AceSecurityStatus status = CALLHISTORY_CHECK_ACCESS(
484                         CALL_HISTORY_FUNCTION_API_REMOVELISTENER);
485
486         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
487
488         if (argumentCount < 1) {
489                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error");
490         }
491
492         JSCallHistoryPriv *priv = static_cast<JSCallHistoryPriv*> (JSObjectGetPrivate(thisObject));
493
494         if (!priv) {
495                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type missmatch error : Invalid private pointer");
496         }
497
498         JSContextRef gContext = priv->getContext();
499         Converter converter(context);
500         Validator check(context, exception);
501
502         try {
503                 long id = 0;
504
505                 if (argumentCount >= 1) {
506                         if (check.isNullOrUndefined(arguments[0])) {
507                                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid values error : handle");
508                         }
509
510                         id=JSUtil::JSValueToLong(context, arguments[0]);
511                         LogDebug("removeChangeListener : id [" <<id<<"]");
512                 }
513
514                 if (id != 0) {
515                         ICallHistoryPtr callHistory(priv->getObject());
516                         callHistory->removeListener(id);
517                 } else {
518                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Invalid values error : handle");
519                 }
520
521                 CallHistoryListenerCancellerPtr canceller = CallHistoryListenerCancellerPtr(new CallHistoryListenerCanceller(gContext, thisObject, id));
522                 DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
523                 CallHistoryListenerManagerSingleton::Instance().unregisterListener(listenerItem);
524         } catch(const WrtDeviceApis::Commons::ConversionException& ex) {
525                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, ex.GetMessage());
526         } catch(const WrtDeviceApis::Commons::InvalidArgumentException& ex) {
527                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, ex.GetMessage());
528         } catch(const WrtDeviceApis::Commons::PlatformException& ex) {
529                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
530         } catch(const WrtDeviceApis::Commons::Exception& ex) {
531                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, ex.GetMessage());
532         }
533
534         return JSValueMakeUndefined(context);
535 }
536
537 }
538 }
539