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