Initial checkin of the wrt-plugins-ivi-hfp for the HTML5 UI
[profile/ivi/wrt-plugins-ivi-hfp.git] / src / JSPhone.cpp
1 #include "JSPhone.h"
2 #include "Phone.h"
3
4 #include <Logger.h>
5 #include <Commons/Exception.h>
6 #include <CommonsJavaScript/Utils.h>
7 #include <CommonsJavaScript/JSCallbackManager.h>
8 #include <JSWebAPIErrorFactory.h>
9 #include <ArgumentValidator.h>
10 #include <CommonsJavaScript/Converter.h>
11 #include <dpl/scoped_ptr.h>
12 #include <sstream>
13 #include <map>
14
15 #include <json-glib/json-gvariant.h>
16
17 namespace DeviceAPI {
18 namespace Phone {
19
20 using namespace DPL;
21 using namespace DeviceAPI::Common;
22 using namespace WrtDeviceApis::Commons;
23 using namespace WrtDeviceApis::CommonsJavaScript;
24
25 #define PHONE_ACTIVECALL_PROP "activeCall"
26
27 JSClassDefinition JSPhone::m_classInfo = {
28     0,
29     kJSClassAttributeNone,
30     "Phone",
31     0,
32     m_property,
33     m_function,
34     initialize,
35     finalize,
36     NULL, //HasProperty,
37     NULL, //GetProperty,
38     NULL, //SetProperty,
39     NULL, //DeleteProperty,
40     NULL, //GetPropertyNames,
41     NULL, //CallAsFunction,
42     NULL, //CallAsConstructor,
43     hasInstance,
44     NULL, //ConvertToType
45 };
46
47 JSStaticFunction JSPhone::m_function[] = {
48     { "invokeCall", JSPhone::invokeCall, kJSPropertyAttributeNone },
49     { "answerCall", JSPhone::answerCall, kJSPropertyAttributeNone },
50     { "hangupCall", JSPhone::hangupCall, kJSPropertyAttributeNone },
51     { "muteCall", JSPhone::muteCall, kJSPropertyAttributeNone },
52     { "selectRemoteDevice", JSPhone::selectRemoteDevice, kJSPropertyAttributeNone },
53     { "unselectRemoteDevice", JSPhone::unselectRemoteDevice, kJSPropertyAttributeNone },
54     { "addRemoteDeviceSelectedListener", JSPhone::addRemoteDeviceSelectedListener, kJSPropertyAttributeNone },
55     { "removeRemoteDeviceSelectedListener", JSPhone::removeRemoteDeviceSelectedListener, kJSPropertyAttributeNone },
56     { "getSelectedRemoteDevice", JSPhone::getSelectedRemoteDevice, kJSPropertyAttributeNone },
57     { "getContacts", JSPhone::getContacts, kJSPropertyAttributeNone },
58     { "addContactsChangedListener", JSPhone::addContactsChangedListener, kJSPropertyAttributeNone },
59     { "removeContactsChangedListener", JSPhone::removeContactsChangedListener, kJSPropertyAttributeNone },
60     { "getCallHistory", JSPhone::getCallHistory, kJSPropertyAttributeNone },
61     { "addCallHistoryChangedListener", JSPhone::addCallHistoryChangedListener, kJSPropertyAttributeNone },
62     { "removeCallHistoryChangedListener", JSPhone::removeCallHistoryChangedListener, kJSPropertyAttributeNone },
63     { "addCallChangedListener", JSPhone::addCallChangedListener, kJSPropertyAttributeNone },
64     { "removeCallChangedListener", JSPhone::removeCallChangedListener, kJSPropertyAttributeNone },
65     { "addCallHistoryEntryAddedListener", JSPhone::addCallHistoryEntryAddedListener, kJSPropertyAttributeNone },
66     { "removeCallHistoryEntryAddedListener", JSPhone::removeCallHistoryEntryAddedListener, kJSPropertyAttributeNone },
67     { 0, 0, 0 }
68 };
69
70 JSStaticValue JSPhone::m_property[] = {
71     {PHONE_ACTIVECALL_PROP,  getProperty, NULL, kJSPropertyAttributeNone},
72     { 0, 0, 0, 0 }
73 };
74
75 const JSClassRef JSPhone::getClassRef()
76 {
77     if (!m_jsClassRef)
78     {
79         m_jsClassRef = JSClassCreate(&m_classInfo);
80     }
81     return m_jsClassRef;
82 }
83
84 const JSClassDefinition* JSPhone::getClassInfo()
85 {
86     return &m_classInfo;
87 }
88
89 JSValueRef JSPhone::getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
90 {
91     LoggerD("Enter");
92     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(object));
93     if (NULL == privateObject)
94     {
95         LoggerE("private object is null");
96         return JSValueMakeUndefined(context);
97     }
98
99     Try {
100         if (JSStringIsEqualToUTF8CString(propertyName, PHONE_ACTIVECALL_PROP)) {
101             PhonePtr phone(privateObject->getObject());
102             JSStringRef state = JSStringCreateWithUTF8CString(phone->activeCall().c_str());
103             JSValueRef result = JSValueMakeFromJSONString(context, state);
104             return result;
105         }
106     } catch (...) {
107         return JSValueMakeUndefined(context);
108     }
109
110     return JSValueMakeUndefined(context);
111 }
112
113 JSClassRef JSPhone::m_jsClassRef = JSClassCreate(JSPhone::getClassInfo());
114
115 void JSPhone::initialize(JSContextRef context, JSObjectRef object)
116 {
117     LoggerD("Entered");
118
119     PhonePrivObject* priv = static_cast<PhonePrivObject*>(JSObjectGetPrivate(object));
120     if (!priv)
121     {
122         PhonePtr phone(new PhoneMaster());
123         priv = new PhonePrivObject( context, phone);
124         if(!JSObjectSetPrivate(object, static_cast<void*>(priv)))
125         {
126             LoggerE("Object can't store private data.");
127             delete priv;
128         }
129     }
130
131     LoggerD("JSPhone::initialize ");
132 }
133
134 void JSPhone::finalize(JSObjectRef object)
135 {
136     LoggerD("Entered");
137
138     PhonePrivObject* priv = static_cast<PhonePrivObject*>(JSObjectGetPrivate(object));
139     JSObjectSetPrivate(object, NULL);
140     LoggerD("Deleting timeutil");
141     delete priv;
142 }
143
144 bool JSPhone::hasInstance(JSContextRef context,
145                           JSObjectRef constructor,
146                           JSValueRef possibleInstance,
147                           JSValueRef* exception)
148 {
149     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
150 }
151
152 JSValueRef JSPhone::invokeCall(JSContextRef context,
153                                JSObjectRef object,
154                                JSObjectRef thisObject,
155                                size_t argumentCount,
156                                const JSValueRef arguments[],
157                                JSValueRef* exception)
158 {
159     LoggerD("Entered");
160
161     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
162     if (NULL == privateObject)
163     {
164         LoggerE("private object is null");
165         return JSValueMakeUndefined(context);
166     }
167
168     PhonePtr phone(privateObject->getObject());
169
170     JSContextRef gContext = privateObject->getContext();
171
172     ArgumentValidator validator(context, argumentCount, arguments);
173     std::string phoneNumber = validator.toString(0);
174     LoggerD("Dialing phone number: " << phoneNumber);
175
176     JSObjectRef errorCallback = validator.toFunction(1, false);
177
178     JSValueProtect(context, errorCallback);
179
180     phone->invokeCall(phoneNumber, errorCallback, gContext);
181
182     return JSValueMakeUndefined(context);
183 }
184
185 JSValueRef JSPhone::hangupCall(JSContextRef context,
186                                JSObjectRef object,
187                                JSObjectRef thisObject,
188                                size_t argumentCount,
189                                const JSValueRef arguments[],
190                                JSValueRef* exception)
191 {
192     LoggerD("Entered");
193
194     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
195     if (NULL == privateObject)
196     {
197         LoggerE("private object is null");
198         return JSValueMakeUndefined(context);
199     }
200
201     PhonePtr phone(privateObject->getObject());
202
203     JSContextRef gContext = privateObject->getContext();
204
205     ArgumentValidator validator(context, argumentCount, arguments);
206
207     JSObjectRef errorCallback = validator.toFunction(0, false);
208
209     JSValueProtect(context, errorCallback);
210
211     phone->hangupCall(errorCallback, gContext);
212
213     return JSValueMakeUndefined(context);
214 }
215
216 JSValueRef JSPhone::answerCall(JSContextRef context,
217                                JSObjectRef object,
218                                JSObjectRef thisObject,
219                                size_t argumentCount,
220                                const JSValueRef arguments[],
221                                JSValueRef* exception)
222 {
223     LoggerD("Entered");
224
225     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
226     if (NULL == privateObject)
227     {
228         LoggerE("private object is null");
229         return JSValueMakeUndefined(context);
230     }
231
232     PhonePtr phone(privateObject->getObject());
233
234     JSContextRef gContext = privateObject->getContext();
235
236     ArgumentValidator validator(context, argumentCount, arguments);
237
238     JSObjectRef errorCallback = validator.toFunction(0, false);
239
240     JSValueProtect(context, errorCallback);
241
242     phone->answerCall(errorCallback, gContext);
243
244     return JSValueMakeUndefined(context);
245 }
246
247 JSValueRef JSPhone::muteCall(JSContextRef context,
248                              JSObjectRef object,
249                              JSObjectRef thisObject,
250                              size_t argumentCount,
251                              const JSValueRef arguments[],
252                              JSValueRef* exception)
253 {
254     LoggerD("Entered");
255
256     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
257     if (NULL == privateObject)
258     {
259         LoggerE("private object is null");
260         return JSValueMakeUndefined(context);
261     }
262
263     PhonePtr phone(privateObject->getObject());
264
265     JSContextRef gContext = privateObject->getContext();
266
267     ArgumentValidator validator(context, argumentCount, arguments);
268     bool mute = validator.toBool(0);
269     JSObjectRef errorCallback = validator.toFunction(1, false);
270     JSValueProtect(context, errorCallback);
271
272     phone->muteCall(mute, errorCallback, gContext);
273
274     return JSValueMakeUndefined(context);
275 }
276
277 JSValueRef JSPhone::getContacts(JSContextRef context,
278                                 JSObjectRef object,
279                                 JSObjectRef thisObject,
280                                 size_t argumentCount,
281                                 const JSValueRef arguments[],
282                                 JSValueRef* exception)
283 {
284     LoggerD("Entered");
285
286     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
287     if (NULL == privateObject)
288     {
289         LoggerE("private object is null");
290         return JSValueMakeUndefined(context);
291     }
292
293     PhonePtr phone(privateObject->getObject());
294
295     JSContextRef gContext = privateObject->getContext();
296
297     ArgumentValidator validator(context, argumentCount, arguments);
298
299     unsigned long count = validator.toULong(0);
300     LoggerD("Retrieving contacts - the latest " << count << " contacts");
301     JSObjectRef successCallback = validator.toFunction(1, false);
302     JSObjectRef errorCallback = validator.toFunction(2, false);
303
304     JSValueProtect(context, successCallback);
305     JSValueProtect(context, errorCallback);
306
307     phone->getContacts(count, successCallback, errorCallback, gContext);
308
309     return JSValueMakeUndefined(context);
310 }
311
312 JSValueRef JSPhone::getCallHistory(JSContextRef context,
313                                    JSObjectRef object,
314                                    JSObjectRef thisObject,
315                                    size_t argumentCount,
316                                    const JSValueRef arguments[],
317                                    JSValueRef* exception)
318 {
319     LoggerD("Entered");
320
321     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
322     if (NULL == privateObject)
323     {
324         LoggerE("private object is null");
325         return JSValueMakeUndefined(context);
326     }
327
328     PhonePtr phone(privateObject->getObject());
329
330     JSContextRef gContext = privateObject->getContext();
331
332     ArgumentValidator validator(context, argumentCount, arguments);
333
334     unsigned long count = validator.toULong(0);
335     LoggerD("Retrieving call history - the latest " << count << " calls");
336     JSObjectRef successCallback = validator.toFunction(1, false);
337     JSObjectRef errorCallback = validator.toFunction(2, false);
338
339     JSValueProtect(context, successCallback);
340     JSValueProtect(context, errorCallback);
341
342     phone->getCallHistory(count, successCallback, errorCallback, gContext);
343
344     return JSValueMakeUndefined(context);
345 }
346
347 JSValueRef JSPhone::addCallChangedListener(JSContextRef context,
348                                            JSObjectRef object,
349                                            JSObjectRef thisObject,
350                                            size_t argumentCount,
351                                            const JSValueRef arguments[],
352                                            JSValueRef* exception)
353 {
354     LoggerD("Entered");
355
356     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
357     if (NULL == privateObject)
358     {
359         LoggerE("private object is null");
360         return JSValueMakeUndefined(context);
361     }
362
363     PhonePtr phone(privateObject->getObject());
364
365     JSContextRef gContext = privateObject->getContext();
366
367     ArgumentValidator validator(context, argumentCount, arguments);
368
369     JSObjectRef callback = validator.toFunction(0, false);
370
371     JSValueProtect(gContext, callback);
372
373     int id = phone->addCallChangedListener(callback, gContext);
374     if(id>0)
375         return JSValueMakeNumber(context, id);
376
377     return JSValueMakeUndefined(context);
378 }
379
380 JSValueRef JSPhone::selectRemoteDevice(JSContextRef context,
381                                        JSObjectRef object,
382                                        JSObjectRef thisObject,
383                                        size_t argumentCount,
384                                        const JSValueRef arguments[],
385                                        JSValueRef* exception)
386 {
387     LoggerD("Entered");
388
389     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
390     if (NULL == privateObject)
391     {
392         LoggerE("private object is null");
393         return JSValueMakeUndefined(context);
394     }
395
396     PhonePtr phone(privateObject->getObject());
397
398     ArgumentValidator validator(context, argumentCount, arguments);
399     std::string btAddress = validator.toString(0);
400     LoggerD("Selecting device: " << btAddress);
401
402     phone->selectRemoteDevice(btAddress);
403
404     return JSValueMakeUndefined(context);
405 }
406
407 JSValueRef JSPhone::unselectRemoteDevice(JSContextRef context,
408                                          JSObjectRef object,
409                                          JSObjectRef thisObject,
410                                          size_t argumentCount,
411                                          const JSValueRef arguments[],
412                                          JSValueRef* exception)
413 {
414     LoggerD("Entered");
415
416     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
417     if (NULL == privateObject)
418     {
419         LoggerE("private object is null");
420         return JSValueMakeUndefined(context);
421     }
422
423     PhonePtr phone(privateObject->getObject());
424
425     LoggerD("Un-selecting selected device");
426
427     phone->unselectRemoteDevice();
428
429     return JSValueMakeUndefined(context);
430 }
431
432 JSValueRef JSPhone::addRemoteDeviceSelectedListener(JSContextRef context,
433                                                     JSObjectRef object,
434                                                     JSObjectRef thisObject,
435                                                     size_t argumentCount,
436                                                     const JSValueRef arguments[],
437                                                     JSValueRef* exception)
438 {
439     LoggerD("Entered");
440
441     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
442     if (NULL == privateObject)
443     {
444         LoggerE("private object is null");
445         return JSValueMakeUndefined(context);
446     }
447
448     PhonePtr phone(privateObject->getObject());
449     JSContextRef gContext = privateObject->getContext();
450
451     ArgumentValidator validator(context, argumentCount, arguments);
452     JSObjectRef callback = validator.toFunction(0, false);
453     JSValueProtect(gContext, callback);
454
455     int id = phone->addRemoteDeviceSelectedListener(callback, gContext);
456     if(id>0)
457         return JSValueMakeNumber(context, id);
458
459     return JSValueMakeUndefined(context);
460 }
461
462 JSValueRef JSPhone::removeRemoteDeviceSelectedListener(JSContextRef context,
463                                                        JSObjectRef object,
464                                                        JSObjectRef thisObject,
465                                                        size_t argumentCount,
466                                                        const JSValueRef arguments[],
467                                                        JSValueRef* exception)
468 {
469     LoggerD("Entered");
470
471     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
472     if (NULL == privateObject)
473     {
474         LoggerE("private object is null");
475         return JSValueMakeUndefined(context);
476     }
477
478     PhonePtr phone(privateObject->getObject());
479
480     JSContextRef gContext = privateObject->getContext();
481
482     ArgumentValidator validator(context, argumentCount, arguments);
483
484     int id = validator.toNumber(0);
485
486     phone->removeRemoteDeviceSelectedListener(id, gContext);
487
488     return JSValueMakeUndefined(context);
489 }
490
491 JSValueRef JSPhone::getSelectedRemoteDevice(JSContextRef context,
492                                             JSObjectRef object,
493                                             JSObjectRef thisObject,
494                                             size_t argumentCount,
495                                             const JSValueRef arguments[],
496                                             JSValueRef* exception)
497 {
498     LoggerD("Entered");
499
500     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
501     if (NULL == privateObject)
502     {
503         LoggerE("private object is null");
504         return JSValueMakeUndefined(context);
505     }
506
507     PhonePtr phone(privateObject->getObject());
508     JSContextRef gContext = privateObject->getContext();
509     ArgumentValidator validator(context, argumentCount, arguments);
510     JSObjectRef callback = validator.toFunction(0, false);
511     JSValueProtect(gContext, callback);
512     phone->getSelectedRemoteDevice(callback, gContext);
513
514     return JSValueMakeUndefined(context);
515 }
516
517 JSValueRef JSPhone::removeCallChangedListener(JSContextRef context,
518                                               JSObjectRef object,
519                                               JSObjectRef thisObject,
520                                               size_t argumentCount,
521                                               const JSValueRef arguments[],
522                                               JSValueRef* exception)
523 {
524     LoggerD("Entered");
525
526     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
527     if (NULL == privateObject)
528     {
529         LoggerE("private object is null");
530         return JSValueMakeUndefined(context);
531     }
532
533     PhonePtr phone(privateObject->getObject());
534
535     JSContextRef gContext = privateObject->getContext();
536
537     ArgumentValidator validator(context, argumentCount, arguments);
538
539     int id = validator.toNumber(0);
540
541     phone->removeCallChangedListener(id, gContext);
542
543     return JSValueMakeUndefined(context);
544 }
545
546 JSValueRef JSPhone::addCallHistoryEntryAddedListener(JSContextRef context,
547                                                      JSObjectRef object,
548                                                      JSObjectRef thisObject,
549                                                      size_t argumentCount,
550                                                      const JSValueRef arguments[],
551                                                      JSValueRef* exception)
552 {
553     LoggerD("Entered");
554
555     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
556     if (NULL == privateObject)
557     {
558         LoggerE("private object is null");
559         return JSValueMakeUndefined(context);
560     }
561
562     PhonePtr phone(privateObject->getObject());
563
564     JSContextRef gContext = privateObject->getContext();
565
566     ArgumentValidator validator(context, argumentCount, arguments);
567
568     JSObjectRef callback = validator.toFunction(0, false);
569
570     JSValueProtect(gContext, callback);
571
572     int id = phone->addCallHistoryEntryAddedListener(callback, gContext);
573     if(id>0)
574         return JSValueMakeNumber(context, id);
575
576     return JSValueMakeUndefined(context);
577 }
578
579 JSValueRef JSPhone::removeCallHistoryEntryAddedListener(JSContextRef context,
580                                                         JSObjectRef object,
581                                                         JSObjectRef thisObject,
582                                                         size_t argumentCount,
583                                                         const JSValueRef arguments[],
584                                                         JSValueRef* exception)
585 {
586     LoggerD("Entered");
587
588     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
589     if (NULL == privateObject)
590     {
591         LoggerE("private object is null");
592         return JSValueMakeUndefined(context);
593     }
594
595     PhonePtr phone(privateObject->getObject());
596
597     JSContextRef gContext = privateObject->getContext();
598
599     ArgumentValidator validator(context, argumentCount, arguments);
600
601     int id = validator.toNumber(0);
602
603     phone->removeCallHistoryEntryAddedListener(id, gContext);
604
605     return JSValueMakeUndefined(context);
606 }
607
608 JSValueRef JSPhone::addContactsChangedListener(JSContextRef context,
609                                                JSObjectRef object,
610                                                JSObjectRef thisObject,
611                                                size_t argumentCount,
612                                                const JSValueRef arguments[],
613                                                JSValueRef* exception)
614 {
615     LoggerD("Entered");
616
617     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
618     if (NULL == privateObject)
619     {
620         LoggerE("private object is null");
621         return JSValueMakeUndefined(context);
622     }
623
624     PhonePtr phone(privateObject->getObject());
625
626     JSContextRef gContext = privateObject->getContext();
627
628     ArgumentValidator validator(context, argumentCount, arguments);
629
630     JSObjectRef callback = validator.toFunction(0, false);
631
632     JSValueProtect(gContext, callback);
633
634     int id = phone->addContactsChangedListener(callback, gContext);
635     if(id>0)
636         return JSValueMakeNumber(context, id);
637
638     return JSValueMakeUndefined(context);
639 }
640
641 JSValueRef JSPhone::removeContactsChangedListener(JSContextRef context,
642                                                   JSObjectRef object,
643                                                   JSObjectRef thisObject,
644                                                   size_t argumentCount,
645                                                   const JSValueRef arguments[],
646                                                   JSValueRef* exception)
647 {
648     LoggerD("Entered");
649
650     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
651     if (NULL == privateObject)
652     {
653         LoggerE("private object is null");
654         return JSValueMakeUndefined(context);
655     }
656
657     PhonePtr phone(privateObject->getObject());
658
659     JSContextRef gContext = privateObject->getContext();
660
661     ArgumentValidator validator(context, argumentCount, arguments);
662
663     int id = validator.toNumber(0);
664
665     phone->removeContactsChangedListener(id, gContext);
666
667     return JSValueMakeUndefined(context);
668 }
669
670 JSValueRef JSPhone::addCallHistoryChangedListener(JSContextRef context,
671                                                   JSObjectRef object,
672                                                   JSObjectRef thisObject,
673                                                   size_t argumentCount,
674                                                   const JSValueRef arguments[],
675                                                   JSValueRef* exception)
676 {
677     LoggerD("Entered");
678
679     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
680     if (NULL == privateObject)
681     {
682         LoggerE("private object is null");
683         return JSValueMakeUndefined(context);
684     }
685
686     PhonePtr phone(privateObject->getObject());
687
688     JSContextRef gContext = privateObject->getContext();
689
690     ArgumentValidator validator(context, argumentCount, arguments);
691
692     JSObjectRef callback = validator.toFunction(0, false);
693
694     JSValueProtect(gContext, callback);
695
696     int id = phone->addCallHistoryChangedListener(callback, gContext);
697     if(id>0)
698         return JSValueMakeNumber(context, id);
699
700     return JSValueMakeUndefined(context);
701 }
702
703 JSValueRef JSPhone::removeCallHistoryChangedListener(JSContextRef context,
704                                                      JSObjectRef object,
705                                                      JSObjectRef thisObject,
706                                                      size_t argumentCount,
707                                                      const JSValueRef arguments[],
708                                                      JSValueRef* exception)
709 {
710     LoggerD("Entered");
711
712     PhonePrivObject* privateObject = static_cast<PhonePrivObject*>(JSObjectGetPrivate(thisObject));
713     if (NULL == privateObject)
714     {
715         LoggerE("private object is null");
716         return JSValueMakeUndefined(context);
717     }
718
719     PhonePtr phone(privateObject->getObject());
720
721     JSContextRef gContext = privateObject->getContext();
722
723     ArgumentValidator validator(context, argumentCount, arguments);
724
725     int id = validator.toNumber(0);
726
727     phone->removeCallHistoryChangedListener(id, gContext);
728
729     return JSValueMakeUndefined(context);
730 }
731
732 } // Phone
733 } // DeviceAPI
734