wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / Contact / JSContactManager.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  * @file        JSContactManager.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.3
22  * @brief
23  */
24
25 #include "JSContactManager.h"
26
27 #include <string>
28 #include <CommonsJavaScript/JSCallbackManager.h>
29 #include <CommonsJavaScript/Validator.h>
30 #include <CommonsJavaScript/Converter.h>
31 #include <CommonsJavaScript/JSUtils.h>
32 #include <CommonsJavaScript/JSPendingOperation.h>
33 #include <JSTizenExceptionFactory.h>
34 #include <JSTizenException.h>
35 #include <SecurityExceptions.h>
36 #include <FilterConverter.h>
37 #include "ContactFactory.h"
38 #include "ContactTypes.h"
39 #include "plugin_config.h"
40 #include "ContactManagerController.h"
41 #include "ContactAsyncCallbackManager.h"
42 #include "ContactListenerManager.h"
43 #include "ContactConverter.h"
44 #include "JSPerson.h"
45 #include "JSContactManagerChangeCallbackManager.h"
46 #include "ContactFilterConverter.h"
47 #include <ArgumentValidator.h>
48 #include <JSWebAPIError.h>
49 #include <TimeTracer.h>
50 #include <Logger.h>
51
52 namespace DeviceAPI {
53 namespace Contact {
54
55 using namespace DeviceAPI::Common;
56 using namespace DeviceAPI::Tizen;
57 using namespace WrtDeviceApis::Commons;
58 using namespace WrtDeviceApis::CommonsJavaScript;
59
60 JSClassDefinition JSContactManager::m_classInfo = {
61         0,
62         kJSClassAttributeNone,
63         "ContactManager",
64         0,
65         m_property,
66         m_function,
67         Initialize,
68         Finalize,
69         NULL, //HasProperty,
70         NULL, //GetProperty,
71         NULL, //SetProperty,
72         NULL, //DeleteProperty,
73         NULL, //GetPropertyNames,
74         NULL, //CallAsFunction,
75         NULL, //CallAsConstructor,
76         NULL, //HasInstance,
77         NULL, //ConvertToType,
78 };
79
80 const JSClassDefinition* JSContactManager::getClassInfo()
81 {
82         return &m_classInfo;
83 }
84
85 JSStaticValue JSContactManager::m_property[] = {
86         { 0, 0, 0, 0 }
87 };
88
89 JSStaticFunction JSContactManager::m_function[] = {
90         { "getAddressBooks", getAddressBooks, kJSPropertyAttributeNone },
91         { "getDefaultAddressBook", getDefaultAddressBook, kJSPropertyAttributeNone },
92         { "getUnifiedAddressBook", getUnifiedAddressBook, kJSPropertyAttributeNone },
93         { "getAddressBook", getAddressBook, kJSPropertyAttributeNone },
94         { "get", get, kJSPropertyAttributeNone },
95         { "update", update, kJSPropertyAttributeNone },
96         { "updateBatch", updateBatch, kJSPropertyAttributeNone },
97         { "remove", remove, kJSPropertyAttributeNone },
98         { "removeBatch", removeBatch, kJSPropertyAttributeNone },
99         { "find", find, kJSPropertyAttributeNone },
100         { "addChangeListener", addChangeListener, kJSPropertyAttributeNone },
101         { "removeChangeListener", removeChangeListener, kJSPropertyAttributeNone },
102         { 0, 0, 0 }
103 };
104
105 JSClassRef JSContactManager::getClassRef()
106 {
107         if (!m_classRef) {
108                 m_classRef = JSClassCreate(&m_classInfo);
109         }
110         return m_classRef;
111 }
112
113 JSClassRef JSContactManager::m_classRef = JSClassCreate(JSContactManager::getClassInfo());
114
115 void JSContactManager::Initialize(JSContextRef context,
116                 JSObjectRef object)
117 {
118         LoggerD("Entered");
119         ContactManagerPtr contactManager = ContactFactory::getInstance().createContactManager();
120
121         ContactManagerController *priv = new ContactManagerController(context, contactManager);
122
123         JSObjectSetPrivate(object, static_cast<void*>(priv));
124 }
125
126 void JSContactManager::Finalize(JSObjectRef object)
127 {
128         LoggerD("entered");
129         ContactManagerController *priv = static_cast<ContactManagerController*>(JSObjectGetPrivate(object));
130         LoggerI("Delete address book manager");
131         delete priv;
132 }
133
134 JSValueRef JSContactManager::getAddressBooks(JSContextRef context,
135                 JSObjectRef object,
136                 JSObjectRef thisObject,
137                 size_t argumentCount,
138                 const JSValueRef arguments[],
139                 JSValueRef* exception)
140 {
141         LoggerD("Entered");
142         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
143         ContactManagerPtr contactManager;
144         JSContextRef gContext;
145         ContactManagerController *controller;
146
147         bool js2ndParamIsFunction = false;
148
149         Try     {
150                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
151                 if (!controller) {
152                         ThrowMsg(InvalidArgumentException, "No private object.");
153                 }
154                 contactManager = controller->getObject();
155                 gContext = controller->getContext();
156         } Catch(Exception) {
157                 LoggerE("No private object");
158                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
159         }
160
161         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_ADDRESS_BOOKS);
162         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
163
164         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
165         try {
166                 ArgumentValidator validator(context, argumentCount, arguments);
167                 validator.toFunction(0, false);
168                 JSObjectRef errorObj = validator.toFunction(1, true);
169                 if(errorObj)
170                         js2ndParamIsFunction = true;
171         } catch (const TypeMismatchException& err ) {
172                 return JSWebAPIError::throwException(context, exception, err);
173         } catch(const BasePlatformException& err) {
174                 return JSWebAPIError::throwException(context, exception, err);
175         } catch(const ConversionException& err) {
176                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
177         } catch(const NullPointerException& err) {
178                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
179         }
180
181         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
182
183         callbackManager->setOnSuccess(arguments[0]);
184
185         if(js2ndParamIsFunction)
186                 callbackManager->setOnError(arguments[1]);
187
188         callbackManager->setObject(thisObject);
189
190         EventContactManagerGetAddressBooksPtr dplEvent(new EventContactManagerGetAddressBooks());
191
192         // set event handler's data
193         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
194         dplEvent->setForAsynchronousCall(controller);
195
196 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
197 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
198
199         Try {
200                 contactManager->getAddressBooks(dplEvent);
201                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
202         } Catch(Exception) {
203                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
204                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
205         }
206
207         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
208 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
209         return JSValueMakeUndefined(context);
210 }
211
212 JSValueRef JSContactManager::getDefaultAddressBook(JSContextRef context,
213                 JSObjectRef object,
214                 JSObjectRef thisObject,
215                 size_t argumentCount,
216                 const JSValueRef arguments[],
217                 JSValueRef* exception)
218 {
219         LoggerD("Entered");
220         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
221         ContactManagerController *priv =
222                 static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
223         if (!priv) {
224                 LoggerE("private object is null");
225                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
226         }
227
228         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_DEFAULT_ADDRESS_BOOK);
229         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
230
231         ContactManagerPtr contactManager;
232         JSContextRef gContext;
233         Try {
234                 contactManager = priv->getObject();
235                 gContext = priv->getContext();
236         } Catch(Exception) {
237                 LoggerE("contact manager or context is null");
238                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
239         }
240
241         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
242
243         EventContactManagerGetDefaultAddressBookPtr dplEvent(new EventContactManagerGetDefaultAddressBook());
244
245     dplEvent->setForSynchronousCall();
246
247         Try {
248                 contactManager->getDefaultAddressBook(dplEvent);
249         } Catch(Exception) {
250                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
251                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
252         }
253
254         if (!dplEvent->getResult() || !dplEvent->getDefaultAddressBookIsSet())
255         {
256                 std::stringstream oss;
257                 switch (dplEvent->getExceptionCode())
258                 {
259                 case ExceptionCodes::NotFoundException:
260                 case ExceptionCodes::InvalidArgumentException:
261                         LoggerE("Not Found error");
262                         oss << "No default address book";
263                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
264                         break;
265                 case ExceptionCodes::PlatformException:
266                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
267                         break;
268                 default:
269                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
270                         break;
271                 }
272         }
273
274         AddressBookPtr defaultAddressBook = dplEvent->getDefaultAddressBook();
275
276         JSValueRef resultValue;
277         Try {
278                 resultValue = converter->toJSValueRef(defaultAddressBook);
279         } Catch(Exception){
280                 LoggerE("Conversion error.");
281                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
282         }
283
284         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
285         return resultValue;
286 }
287
288 JSValueRef JSContactManager::getUnifiedAddressBook(JSContextRef context,
289                 JSObjectRef object,
290                 JSObjectRef thisObject,
291                 size_t argumentCount,
292                 const JSValueRef arguments[],
293                 JSValueRef* exception)
294 {
295         LoggerD("Entered");
296         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
297         ContactManagerController *priv =
298                 static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
299         if (!priv) {
300                 LoggerE("private object is null");
301                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
302         }
303
304         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_UNIFIED_ADDRESS_BOOK);
305         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
306
307         ContactManagerPtr contactManager;
308         JSContextRef gContext;
309         Try {
310                 contactManager = priv->getObject();
311                 gContext = priv->getContext();
312         } Catch(Exception) {
313                 LoggerE("contact manager or context is null");
314                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
315         }
316
317         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
318
319         EventContactManagerGetUnifiedAddressBookPtr dplEvent(new EventContactManagerGetUnifiedAddressBook());
320
321     dplEvent->setForSynchronousCall();
322
323         Try {
324                 contactManager->getUnifiedAddressBook(dplEvent);
325         } Catch(Exception) {
326                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
327                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
328         }
329
330         if (!dplEvent->getResult() || !dplEvent->getUnifiedAddressBookIsSet())
331         {
332                 std::stringstream oss;
333                 switch (dplEvent->getExceptionCode())
334                 {
335                 case ExceptionCodes::NotFoundException:
336                 case ExceptionCodes::InvalidArgumentException:
337                         LoggerE("Not Found error");
338                         oss << "No default address book";
339                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
340                         break;
341                 case ExceptionCodes::PlatformException:
342                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
343                         break;
344                 default:
345                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
346                         break;
347                 }
348         }
349
350         AddressBookPtr unifiedAddressBook = dplEvent->getUnifiedAddressBook();
351
352         JSValueRef resultValue;
353         Try {
354                 resultValue = converter->toJSValueRef(unifiedAddressBook);
355         } Catch(Exception){
356                 LoggerE("Conversion error.");
357                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
358         }
359
360         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
361         return resultValue;
362 }
363
364 JSValueRef JSContactManager::getAddressBook(JSContextRef context,
365                 JSObjectRef object,
366                 JSObjectRef thisObject,
367                 size_t argumentCount,
368                 const JSValueRef arguments[],
369                 JSValueRef* exception)
370 {
371         LoggerD("Entered");
372         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
373         ContactManagerController *priv =
374                 static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
375         if (!priv) {
376                 LoggerE("private object is null");
377                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
378         }
379
380         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET_ADDRESS_BOOK);
381         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
382
383         ContactManagerPtr contactManager;
384         JSContextRef gContext;
385         Try {
386                 contactManager = priv->getObject();
387                 gContext = priv->getContext();
388         } Catch(Exception) {
389                 LoggerE("contact manager or context is null");
390                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
391         }
392
393         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(gContext);
394
395         std::string addressBookId;
396         try {
397                 ArgumentValidator validator(context, argumentCount, arguments);
398                 addressBookId = validator.toString(0, false);
399         } catch (const TypeMismatchException& err ) {
400                 return JSWebAPIError::throwException(context, exception, err);
401         } catch(const BasePlatformException& err) {
402                 return JSWebAPIError::throwException(context, exception, err);
403         } catch(const ConversionException& err) {
404                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
405         } catch(const NullPointerException& err) {
406                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
407         }
408
409         EventContactManagerGetAddressBookPtr dplEvent(new EventContactManagerGetAddressBook());
410
411         dplEvent->setAddressBookId(addressBookId);
412     dplEvent->setForSynchronousCall();
413
414         Try {
415                 contactManager->getAddressBook(dplEvent);
416         } Catch(Exception) {
417                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
418                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
419         }
420
421         if (!dplEvent->getResult() || !dplEvent->getAddressBookIsSet())
422         {
423                 std::stringstream oss;
424                 switch (dplEvent->getExceptionCode())
425                 {
426                 case ExceptionCodes::NotFoundException:
427                 case ExceptionCodes::InvalidArgumentException:
428                         LoggerE("Not Found error : " << addressBookId);
429                         oss << "No Contact id '" << addressBookId << "'";
430                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
431                         break;
432                 case ExceptionCodes::PlatformException:
433                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
434                         break;
435                 default:
436                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
437                         break;
438                 }
439         }
440
441         AddressBookPtr addressBook = dplEvent->getAddressBook();
442
443         JSValueRef resultValue;
444         Try {
445                 resultValue = converter->toJSValueRef(addressBook);
446         } Catch(Exception){
447                 LoggerE("Conversion error.");
448                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
449         }
450
451         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
452         return resultValue;
453 }
454
455 JSValueRef JSContactManager::get(JSContextRef context,
456                 JSObjectRef object,
457                 JSObjectRef thisObject,
458                 size_t argumentCount,
459                 const JSValueRef arguments[],
460                 JSValueRef* exception)
461 {
462         LoggerD("entered");
463         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
464         ContactManagerPtr addressBook;
465         ContactManagerController *controller;
466
467         Try     {
468                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
469                 if (!controller) {
470                         ThrowMsg(InvalidArgumentException, "No private object.");
471                 }
472                 addressBook = controller->getObject();
473         } Catch(Exception) {
474                 LoggerE("No private object");
475                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
476         }
477
478         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_GET);
479         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
480
481         if (argumentCount < 1) {
482                 /* 1st Argument must be string. */
483                 LoggerE("1st argument must not be undefined.");
484                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, "No Contact id 'undefined'");
485         }
486
487         std::string id;
488
489         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
490         try     {
491                 ArgumentValidator validator(context, argumentCount, arguments);
492                 id = validator.toString(0, false);
493         } catch (const TypeMismatchException& err ) {
494                 return JSWebAPIError::throwException(context, exception, err);
495         } catch(const BasePlatformException& err) {
496                 return JSWebAPIError::throwException(context, exception, err);
497         } catch(const ConversionException& err) {
498                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
499         } catch(const NullPointerException& err) {
500                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
501         }
502
503         EventContactManagerGetPtr dplEvent(new EventContactManagerGet());
504
505         dplEvent->setId(id);
506     dplEvent->setForSynchronousCall();
507
508         Try {
509                 addressBook->get(dplEvent);
510         } Catch(Exception) {
511                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
512                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
513         }
514
515         if (!dplEvent->getResult() || !dplEvent->getPersonIsSet())
516         {
517                 std::stringstream oss;
518                 switch (dplEvent->getExceptionCode())
519                 {
520                 case ExceptionCodes::NotFoundException:
521                 case ExceptionCodes::InvalidArgumentException:
522                         LoggerE("Not Found error : " << id);
523                         oss << "No Person id '" << id << "'";
524                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
525                         break;
526                 case ExceptionCodes::PlatformException:
527                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
528                         break;
529                 default:
530                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
531                         break;
532                 }
533         }
534
535         PersonPtr person = dplEvent->getPerson();
536
537         JSValueRef result;
538         Try {
539                 result = converter->toJSValueRef(person);
540         } Catch(Exception) {
541                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
542                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
543         }
544
545         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
546         return result;
547 }
548
549 JSValueRef JSContactManager::update(JSContextRef context,
550                 JSObjectRef object,
551                 JSObjectRef thisObject,
552                 size_t argumentCount,
553                 const JSValueRef arguments[],
554                 JSValueRef* exception)
555 {
556         LoggerD("entered");
557         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
558         ContactManagerPtr addressBook;
559         ContactManagerController *controller;
560
561         Try     {
562                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
563                 if (!controller) {
564                         ThrowMsg(InvalidArgumentException, "No private object.");
565                 }
566                 addressBook = controller->getObject();
567         } Catch(Exception) {
568                 LoggerE("No private object");
569                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
570         }
571
572         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_UPDATE);
573         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
574
575         try {
576                 ArgumentValidator validator(context, argumentCount, arguments);
577                 validator.toObject(0, false);
578         } catch (const TypeMismatchException& err ) {
579                 return JSWebAPIError::throwException(context, exception, err);
580         } catch(const BasePlatformException& err) {
581                 return JSWebAPIError::throwException(context, exception, err);
582         } catch(const ConversionException& err) {
583                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
584         } catch(const NullPointerException& err) {
585                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
586         }
587
588         PersonPtr person(NULL);
589
590         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
591         Try     {
592                 if (!JSPerson::isObjectOfClass(context, arguments[0]))
593                         ThrowMsg(InvalidArgumentException, "1st argument is not a 'Contact object'.");
594                 person = converter->toPerson(arguments[0]);
595         } Catch(Exception) {
596                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
597                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "1st argument is not a 'Contact object'");
598         }
599
600         EventContactManagerUpdatePtr dplEvent(new EventContactManagerUpdate());
601
602         dplEvent->setPerson(person);
603     dplEvent->setForSynchronousCall();
604
605         Try {
606                 addressBook->update(dplEvent);
607         } Catch(Exception) {
608                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
609                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
610         }
611
612         if (!dplEvent->getResult())
613         {
614                 std::stringstream oss;
615                 switch (dplEvent->getExceptionCode())
616                 {
617                 case ExceptionCodes::NotFoundException:
618                 case ExceptionCodes::InvalidArgumentException:
619                         oss << "No Contact id '" << person->getId() << "'";
620                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, oss.str());
621                         break;
622                 case ExceptionCodes::PlatformException:
623                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
624                         break;
625                 default:
626                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
627                         break;
628                 }
629         }
630
631         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
632         return JSValueMakeUndefined(context);
633 }
634
635 JSValueRef JSContactManager::updateBatch(JSContextRef context,
636                 JSObjectRef object,
637                 JSObjectRef thisObject,
638                 size_t argumentCount,
639                 const JSValueRef arguments[],
640                 JSValueRef* exception)
641 {
642         LoggerD("entered");
643         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
644         ContactManagerPtr addressBook;
645         JSContextRef gContext;
646         ContactManagerController *controller;
647
648         bool js2ndParamIsFunction = false;
649         bool js3rdParamIsFunction = false;
650
651         Try     {
652                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
653                 if (!controller) {
654                         ThrowMsg(InvalidArgumentException, "No private object.");
655                 }
656                 addressBook = controller->getObject();
657                 gContext = controller->getContext();
658         } Catch(Exception) {
659                 LoggerE("No private object");
660                 return JSTizenExceptionFactory::postException(context, exception,
661                                 JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
662         }
663
664         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_UPDATE_BATCH);
665         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
666
667         try {
668                 ArgumentValidator validator(context, argumentCount, arguments);
669
670                 validator.toObject(0, false);
671                 JSObjectRef successObj = validator.toFunction(1, true);
672                 if(successObj)
673                         js2ndParamIsFunction = true;
674
675                 JSObjectRef errorObj = validator.toFunction(2, true);
676                 if(errorObj)
677                         js3rdParamIsFunction = true;
678         } catch (const TypeMismatchException& err ) {
679                 return JSWebAPIError::throwException(context, exception, err);
680         } catch(const BasePlatformException& err) {
681                 return JSWebAPIError::throwException(context, exception, err);
682         } catch(const ConversionException& err) {
683                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
684         } catch(const NullPointerException& err) {
685                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
686         }
687
688         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
689
690         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
691
692         if(js2ndParamIsFunction)
693                 callbackManager->setOnSuccess(arguments[1]);
694
695         if(js3rdParamIsFunction)
696                 callbackManager->setOnError(arguments[2]);
697
698         callbackManager->setObject(thisObject);
699
700         EventContactManagerUpdateBatchPtr dplEvent(new EventContactManagerUpdateBatch());
701         Try {
702                 dplEvent->setPersons(converter->toPersonArray(arguments[0]));
703         } Catch(ConversionException) {
704                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
705                 return JSTizenExceptionFactory::postException(context, exception,
706                                 JSTizenException::TYPE_MISMATCH_ERROR, "3rd argument must be a 'function' or a 'null'");
707         }
708
709         // set event handler's data
710         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
711         dplEvent->setForAsynchronousCall(controller);
712
713 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
714 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
715
716         Try {
717                 addressBook->updateBatch(dplEvent);
718                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
719         } Catch(Exception) {
720                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
721                 return JSTizenExceptionFactory::postException(context, exception,
722                                 JSTizenException::UNKNOWN_ERROR, "Internal error");
723         }
724
725         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
726 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
727         return JSValueMakeUndefined(context);
728 }
729
730 JSValueRef JSContactManager::remove(JSContextRef context,
731                 JSObjectRef object,
732                 JSObjectRef thisObject,
733                 size_t argumentCount,
734                 const JSValueRef arguments[],
735                 JSValueRef* exception)
736 {
737         LoggerD("entered");
738         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
739         ContactManagerPtr addressBook;
740         ContactManagerController *controller;
741
742         Try     {
743                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
744                 if (!controller) {
745                         ThrowMsg(InvalidArgumentException, "No private object.");
746                 }
747                 addressBook = controller->getObject();
748         } Catch(Exception) {
749                 LoggerE("No private object");
750                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
751         }
752
753         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_REMOVE);
754         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
755
756         std::string personId;
757
758         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
759         try     {
760                 ArgumentValidator validator(context, argumentCount, arguments);
761                 personId = validator.toString(0, false);
762         } catch (const TypeMismatchException& err ) {
763                 return JSWebAPIError::throwException(context, exception, err);
764         } catch(const BasePlatformException& err) {
765                 return JSWebAPIError::throwException(context, exception, err);
766         } catch(const ConversionException& err) {
767                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
768         } catch(const NullPointerException& err) {
769                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
770         }
771
772         EventContactManagerRemovePtr dplEvent(new EventContactManagerRemove());
773
774         dplEvent->setPersonId(personId);
775     dplEvent->setForSynchronousCall();
776
777         Try {
778                 addressBook->remove(dplEvent);
779         } Catch(Exception) {
780                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
781                 return JSTizenExceptionFactory::postException(context, exception,
782                                 JSTizenException::UNKNOWN_ERROR, "Internal error");
783         }
784
785         if (!dplEvent->getResult())
786         {
787                 std::stringstream oss;
788                 switch (dplEvent->getExceptionCode())
789                 {
790                 case ExceptionCodes::NotFoundException:
791                 case ExceptionCodes::InvalidArgumentException:
792                         LoggerE("Not Found error : " << personId);
793                         oss << "No Contact id '" << personId << "'";
794                         return JSTizenExceptionFactory::postException(context, exception,
795                                         JSTizenException::NOT_FOUND_ERROR, oss.str());
796                         break;
797                 case ExceptionCodes::PlatformException:
798                         return JSTizenExceptionFactory::postException(context, exception,
799                                         JSTizenException::UNKNOWN_ERROR, "Internal error");
800                         break;
801                 default:
802                         return JSTizenExceptionFactory::postException(context, exception,
803                                         JSTizenException::UNKNOWN_ERROR, "Internal error");
804                         break;
805                 }
806         }
807
808         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
809         return JSValueMakeUndefined(context);
810 }
811
812 JSValueRef JSContactManager::removeBatch(JSContextRef context,
813                 JSObjectRef object,
814                 JSObjectRef thisObject,
815                 size_t argumentCount,
816                 const JSValueRef arguments[],
817                 JSValueRef* exception)
818 {
819         LoggerD("entered");
820         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
821         ContactManagerPtr addressBook;
822         JSContextRef gContext;
823         ContactManagerController *controller;
824
825         bool js2ndParamIsFunction = false;
826         bool js3rdParamIsFunction = false;
827
828         Try     {
829                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
830                 if (!controller) {
831                         ThrowMsg(InvalidArgumentException, "No private object.");
832                 }
833                 addressBook = controller->getObject();
834                 gContext = controller->getContext();
835         } Catch(Exception) {
836                 LoggerE("No private object");
837                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
838         }
839
840         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_REMOVE_BATCH);
841         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
842
843         try {
844                 ArgumentValidator validator(context, argumentCount, arguments);
845
846                 validator.toObject(0, false);
847                 JSObjectRef successObj = validator.toFunction(1, true);
848                 if(successObj)
849                         js2ndParamIsFunction = true;
850
851                 JSObjectRef errorObj = validator.toFunction(2, true);
852                 if(errorObj)
853                         js3rdParamIsFunction = true;
854         } catch (const TypeMismatchException& err ) {
855                 return JSWebAPIError::throwException(context, exception, err);
856         } catch(const BasePlatformException& err) {
857                 return JSWebAPIError::throwException(context, exception, err);
858         } catch(const ConversionException& err) {
859                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
860         } catch(const NullPointerException& err) {
861                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
862         }
863
864         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
865
866         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
867
868         if(js2ndParamIsFunction)
869                 callbackManager->setOnSuccess(arguments[1]);
870
871         if(js3rdParamIsFunction)
872                 callbackManager->setOnError(arguments[2]);
873
874         callbackManager->setObject(thisObject);
875
876         EventContactManagerRemoveBatchPtr dplEvent(new EventContactManagerRemoveBatch());
877         Try {
878                 dplEvent->setPersonIds(converter->toStringArray(arguments[0]));
879         } Catch(ConversionException) {
880                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
881                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "3rd argument must be an array of 'Contact id'");
882         }
883
884         // set event handler's data
885         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
886         dplEvent->setForAsynchronousCall(controller);
887
888 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
889 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
890
891         Try {
892                 addressBook->removeBatch(dplEvent);
893                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
894         } Catch(Exception) {
895                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
896                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
897         }
898
899         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
900 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
901         return JSValueMakeUndefined(context);
902 }
903
904 JSValueRef JSContactManager::find(JSContextRef context,
905                 JSObjectRef object,
906                 JSObjectRef thisObject,
907                 size_t argumentCount,
908                 const JSValueRef arguments[],
909                 JSValueRef* exception)
910 {
911         LoggerD("entered");
912         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
913         ContactManagerPtr addressBook;
914         JSContextRef gContext;
915         ContactManagerController *controller;
916
917         bool js2ndParamIsFunction = false;
918         bool js3rdParamIsObject = false;
919         bool js4thParamIsObject = false;
920
921         Try     {
922                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
923                 if (!controller) {
924                         ThrowMsg(InvalidArgumentException, "No private object.");
925                 }
926                 addressBook = controller->getObject();
927                 gContext = controller->getContext();
928         } Catch(Exception) {
929                 LoggerE("No private object");
930                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
931         }
932
933         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_FIND);
934         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
935
936         try {
937                 ArgumentValidator validator(context, argumentCount, arguments);
938
939                 validator.toFunction(0, false);
940                 JSObjectRef errorObj = validator.toFunction(1, true);
941                 if(errorObj)
942                         js2ndParamIsFunction = true;
943
944                 JSObjectRef filterObj = validator.toObject(2, true);
945                 if(filterObj)
946                         js3rdParamIsObject = true;
947
948                 JSObjectRef sortObj = validator.toObject(3, true);
949                 if(sortObj)
950                         js4thParamIsObject = true;
951
952         } catch (const TypeMismatchException& err ) {
953                 return JSWebAPIError::throwException(context, exception, err);
954         } catch(const BasePlatformException& err) {
955                 return JSWebAPIError::throwException(context, exception, err);
956         } catch(const ConversionException& err) {
957                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
958         } catch(const NullPointerException& err) {
959                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
960         }
961
962         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(gContext);
963
964         callbackManager->setOnSuccess(arguments[0]);
965
966         if (js2ndParamIsFunction)
967                 callbackManager->setOnError(arguments[1]);
968
969         callbackManager->setObject(thisObject);
970
971         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
972         PersonFilterConverterFactory::ConverterType filterConverter = PersonFilterConverterFactory::getConverter(context);
973
974         EventContactManagerFindPtr dplEvent(new EventContactManagerFind());
975         Try {
976                 if (js3rdParamIsObject)
977                         dplEvent->setFilter(filterConverter->toFilter(arguments[2]));
978         } Catch(Exception) {
979                 LoggerE("Error on 3rd parameter conversion : " << _rethrown_exception.GetMessage());
980                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "3rd argument must be an 'Filter object' or 'null'");
981         }
982
983         Try {
984                 if (js4thParamIsObject)
985                         dplEvent->setSortMode(filterConverter->toSortMode(arguments[3]));
986         } Catch(Exception) {
987                 LoggerE("Error on 4th parameter conversion : " << _rethrown_exception.GetMessage());
988                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "4th argument must be an 'SortMode object' or 'null'");
989         }
990
991         // set event handler's data
992         dplEvent->setPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
993         dplEvent->setForAsynchronousCall(controller);
994
995 //      DPL::SharedPtr<IEventController> eventContr = DPL::StaticPointerCast< IEventController>(dplEvent);
996 //      IJSPendingOperationPrivateObject *gcPendingOperation = new IJSPendingOperationPrivateObject(eventContr);
997
998         Try {
999                 addressBook->find(dplEvent);
1000                 ContactAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, gContext);
1001         } Catch(Exception) {
1002                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1003                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1004         }
1005
1006         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1007 //      return JSObjectMake(gContext, JSPendingOperation::getClassRef(), gcPendingOperation);
1008         return JSValueMakeUndefined(context);
1009 }
1010
1011 JSValueRef JSContactManager::addChangeListener(JSContextRef context,
1012                 JSObjectRef object,
1013                 JSObjectRef thisObject,
1014                 size_t argumentCount,
1015                 const JSValueRef arguments[],
1016                 JSValueRef* exception)
1017 {
1018         LoggerD("entered");
1019         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1020         ContactManagerPtr addressBook;
1021         JSContextRef gContext;
1022         ContactManagerController *controller;
1023
1024         bool js2ndParamIsFunction = false;
1025
1026         Try     {
1027                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
1028                 if (!controller) {
1029                         ThrowMsg(InvalidArgumentException, "No private object.");
1030                 }
1031                 addressBook = controller->getObject();
1032                 gContext = controller->getContext();
1033         } Catch(Exception) {
1034                 LoggerE("No private object");
1035                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
1036         }
1037
1038         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_ADD_CHANGE_LISTENER);
1039         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1040
1041         BasicValidator validator = BasicValidatorFactory::getValidator(context, exception);
1042         try {
1043                 ArgumentValidator Argvalidator(context, argumentCount, arguments);
1044
1045                 Argvalidator.toObject(0, false);
1046                 JSObjectRef errorObj = Argvalidator.toFunction(1, true);
1047                 if(errorObj)
1048                         js2ndParamIsFunction = true;
1049
1050         } catch (const TypeMismatchException& err ) {
1051                 return JSWebAPIError::throwException(context, exception, err);
1052         } catch(const BasePlatformException& err) {
1053                 return JSWebAPIError::throwException(context, exception, err);
1054         } catch(const ConversionException& err) {
1055                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1056         } catch(const NullPointerException& err) {
1057                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1058         }
1059
1060         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1061
1062         JSValueRef onpersonsadded;
1063         JSValueRef onpersonsupdated;
1064         JSValueRef onpersonsdeleted;
1065         Try {
1066                 JSObjectRef callbackObject = converter->toJSObjectRef(arguments[0]);
1067
1068                 onpersonsadded = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onpersonsadded");
1069                 if (validator->isNullOrUndefined(onpersonsadded))
1070                         onpersonsadded = NULL;
1071                 else if (!validator->isCallback(onpersonsadded)) {
1072                         ThrowMsg(ConversionException, "2nd argument's onpersonsadded attribute is not a 'function'");
1073                 }
1074
1075                 onpersonsupdated = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onpersonsupdated");
1076                 if (validator->isNullOrUndefined(onpersonsupdated))
1077                         onpersonsupdated = NULL;
1078                 else if (!validator->isCallback(onpersonsupdated)) {
1079                         ThrowMsg(ConversionException, "2nd argument's onpersonsupdated attribute is not a 'function'");
1080                 }
1081
1082                 onpersonsdeleted = JSUtils::getJSPropertyOrUndefined(context, callbackObject, "onpersonsremoved");
1083                 if (validator->isNullOrUndefined(onpersonsdeleted))
1084                         onpersonsdeleted = NULL;
1085                 else if (!validator->isCallback(onpersonsdeleted)) {
1086                         ThrowMsg(ConversionException, "2nd argument's onpersonsremoved attribute is not a 'function'");
1087                 }
1088
1089                 if (onpersonsadded == NULL && onpersonsupdated == NULL && onpersonsdeleted == NULL)
1090                         ThrowMsg(ConversionException, "2nd argument must have at least one function");
1091
1092         } Catch(ConversionException) {
1093                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1094                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, _rethrown_exception.GetMessage());
1095         }
1096
1097         JSContactManagerChangeCallbackManagerPtr callbackManager = JSContactManagerChangeCallbackManager::createObject(gContext);
1098
1099         callbackManager->setOnPersonsAdded(onpersonsadded);
1100         callbackManager->setOnPersonsUpdated(onpersonsupdated);
1101         callbackManager->setOnPersonsDeleted(onpersonsdeleted);
1102         if(js2ndParamIsFunction)
1103                 callbackManager->setOnError(arguments[1]);
1104
1105         EventContactManagerChangeListenerEmitterPtr emitter(new EventContactManagerChangeListenerEmitter());
1106
1107         emitter->setEventPrivateData(DPL::StaticPointerCast<IEventPrivateData>(callbackManager));
1108         emitter->setListener(controller);
1109
1110         EventContactManagerAddChangeListenerPtr dplEvent(new EventContactManagerAddChangeListener());
1111
1112         dplEvent->setEmitter(emitter);
1113     dplEvent->setForSynchronousCall();
1114
1115         Try {
1116                 addressBook->addChangeListener(dplEvent);
1117         } Catch(Exception) {
1118                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1119                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1120         }
1121
1122         if (!dplEvent->getResult() || !dplEvent->getIdIsSet())
1123         {
1124                 switch (dplEvent->getExceptionCode())
1125                 {
1126                 case ExceptionCodes::InvalidArgumentException:
1127                 case ExceptionCodes::PlatformException:
1128                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1129                         break;
1130                 default:
1131                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1132                         break;
1133                 }
1134         }
1135
1136         long watchId = dplEvent->getId();
1137
1138         PersonsChangeListenerCancellerPtr canceller = PersonsChangeListenerCancellerPtr(new PersonsChangeListenerCanceller(gContext, thisObject, watchId));
1139         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1140         ContactListenerManagerSingleton::Instance().registerListener(listenerItem, gContext);
1141
1142         JSValueRef result;
1143         Try {
1144                 result = converter->toJSValueRefLong(watchId);
1145         } Catch(Exception) {
1146                 LoggerE("Error on conversion : " << _rethrown_exception.GetMessage());
1147                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1148         }
1149         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1150         return result;
1151 }
1152
1153 JSValueRef JSContactManager::removeChangeListener(JSContextRef context,
1154                 JSObjectRef object,
1155                 JSObjectRef thisObject,
1156                 size_t argumentCount,
1157                 const JSValueRef arguments[],
1158                 JSValueRef* exception)
1159 {
1160         LoggerD("entered");
1161         TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
1162         ContactManagerPtr addressBook;
1163         JSContextRef gContext;
1164         ContactManagerController *controller;
1165
1166         Try     {
1167                 controller = static_cast<ContactManagerController*>(JSObjectGetPrivate(thisObject));
1168                 if (!controller) {
1169                         ThrowMsg(InvalidArgumentException, "No private object.");
1170                 }
1171                 addressBook = controller->getObject();
1172                 gContext = controller->getContext();
1173         } Catch(Exception) {
1174                 LoggerE("No private object");
1175                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Wrong object");
1176         }
1177
1178         AceSecurityStatus status = CONTACT_CHECK_ACCESS(CONTACT_FUNCTION_API_CONTACT_MANAGER_REMOVE_CHANGE_LISTENER);
1179         TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
1180
1181         ContactConverterFactory::ConverterType converter = ContactConverterFactory::getConverter(context);
1182
1183         long watchId = 0;
1184         try {
1185                 ArgumentValidator validator(context, argumentCount, arguments);
1186                 watchId = validator.toLong(0, false, 0);
1187         } catch (const TypeMismatchException& err ) {
1188                 return JSWebAPIError::throwException(context, exception, err);
1189         } catch(const BasePlatformException& err) {
1190                 return JSWebAPIError::throwException(context, exception, err);
1191         } catch(const ConversionException& err) {
1192                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1193         } catch(const NullPointerException& err) {
1194                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "");
1195         }
1196
1197         EventContactManagerRemoveChangeListenerPtr dplEvent(new EventContactManagerRemoveChangeListener());
1198
1199         dplEvent->setId(watchId);
1200     dplEvent->setForSynchronousCall();
1201
1202         Try {
1203                 addressBook->removeChangeListener(dplEvent);
1204         } Catch(Exception) {
1205                 LoggerE("Error on platform : " << _rethrown_exception.GetMessage());
1206                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1207         }
1208
1209         PersonsChangeListenerCancellerPtr canceller = PersonsChangeListenerCancellerPtr(new PersonsChangeListenerCanceller(gContext, thisObject, watchId));
1210         DeviceAPI::Common::IListenerItemPtr listenerItem = DPL::StaticPointerCast<DeviceAPI::Common::IListenerItem>(canceller);
1211         ContactListenerManagerSingleton::Instance().unregisterListener(listenerItem);
1212
1213         if (!dplEvent->getResult())
1214         {
1215                 switch (dplEvent->getExceptionCode())
1216                 {
1217                 case ExceptionCodes::InvalidArgumentException:
1218                 case ExceptionCodes::NotFoundException:
1219                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::NOT_FOUND_ERROR, "Watch id not found");
1220                         break;
1221                 default:
1222                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Internal error");
1223                         break;
1224                 }
1225         }
1226         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
1227         return JSValueMakeUndefined(context);
1228 }
1229
1230 } // Contact
1231 } // DeviceAPI