Release 4.0.0-preview1-00285
[platform/core/csapi/tizenfx.git] / src / Tizen.CallManager / Tizen.CallManager / CmClientHandle.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.Linq;
21
22 namespace Tizen.CallManager
23 {
24     /// <summary>
25     /// A class which manages call manager events, properties and functions.
26     /// </summary>
27     public class CmClientHandle
28     {
29         internal IntPtr _handle = IntPtr.Zero;
30         private event EventHandler<CallStatusChangedEventArgs> _callStatusChanged;
31         private event EventHandler<CallMuteStatusChangedEventArgs> _callMuteStatusChanged;
32         private event EventHandler<CallEventEventArgs> _callEvent;
33         private event EventHandler<DialStatusEventArgs> _dialStatusChanged;
34         private event EventHandler<AudioStatusChangedEventArgs> _audioStateChanged;
35         private event EventHandler<DtmfIndicationEventArgs> _dtmfIndication;
36         private event EventHandler<EventArgs> _goForeGround;
37         private event EventHandler<VoiceRecordStatusEventArgs> _voiceRecordStatusChanged;
38
39         private Interop.CallManager.CallStatusChangedCallback _callStatusChangedCb;
40         private Interop.CallManager.CallMuteStatusChangedCallback _callMuteStatusChangedCb;
41         private Interop.CallManager.CallEventNotificationCallback _callEventCb;
42         private Interop.CallManager.DialStatusChangedCallback _dialStatusChangedCb;
43         private Interop.CallManager.AudioStateChangedCallback _audioStateChangedCb;
44         private Interop.CallManager.DtmfIndicationChangedCallback _dtmfIndicationChangedCb;
45         private Interop.CallManager.GoForegroundCallback _goForeGroundCb;
46         private Interop.CallManager.VoiceRecordStatusChangedCallback _voiceRecordStatusChangedCb;
47
48         internal CmClientHandle(IntPtr handle)
49         {
50             _handle = handle;
51         }
52
53         /// <summary>
54         /// This event is raised when call status changes.
55         /// </summary>
56         public event EventHandler<CallStatusChangedEventArgs> CallStatusChanged
57         {
58             add
59             {
60                 if (_callStatusChanged == null)
61                 {
62                     RegisterCallStatusChangedEvent();
63                 }
64
65                 _callStatusChanged += value;
66             }
67
68             remove
69             {
70                 _callStatusChanged -= value;
71                 if (_callStatusChanged == null)
72                 {
73                     UnregisterCallStatusChangedEvent();
74                 }
75             }
76         }
77
78         /// <summary>
79         /// This event is raised when the mute status changes.
80         /// </summary>
81         public event EventHandler<CallMuteStatusChangedEventArgs> CallMuteStatusChanged
82         {
83             add
84             {
85                 if (_callMuteStatusChanged == null)
86                 {
87                     RegisterCallMuteStatusChangedEvent();
88                 }
89
90                 _callMuteStatusChanged += value;
91             }
92
93             remove
94             {
95                 _callMuteStatusChanged -= value;
96                 if (_callMuteStatusChanged == null)
97                 {
98                     UnregisterCallMuteStatusChangedEvent();
99                 }
100             }
101         }
102
103         /// <summary>
104         /// This event is raised when call events change.
105         /// </summary>
106         public event EventHandler<CallEventEventArgs> CallEvent
107         {
108             add
109             {
110                 if (_callEvent == null)
111                 {
112                     RegisterCallEventNotification();
113                 }
114
115                 _callEvent += value;
116             }
117
118             remove
119             {
120                 _callEvent -= value;
121                 if (_callEvent == null)
122                 {
123                     UnregisterCallEventNotification();
124                 }
125             }
126         }
127
128         /// <summary>
129         /// This event is raised when dial status changes.
130         /// </summary>
131         public event EventHandler<DialStatusEventArgs> DialStatusChanged
132         {
133             add
134             {
135                 if (_dialStatusChanged == null)
136                 {
137                     RegisterDialStatusEvent();
138                 }
139
140                 _dialStatusChanged += value;
141             }
142
143             remove
144             {
145                 _dialStatusChanged -= value;
146                 if (_dialStatusChanged == null)
147                 {
148                     UnregisterDialStatusEvent();
149                 }
150             }
151         }
152
153         /// <summary>
154         /// This event is raised when audio status changes.
155         /// </summary>
156         public event EventHandler<AudioStatusChangedEventArgs> AudioStateChanged
157         {
158             add
159             {
160                 if (_audioStateChanged == null)
161                 {
162                     RegisterAudioStateChangedEvent();
163                 }
164
165                 _audioStateChanged += value;
166             }
167
168             remove
169             {
170                 _audioStateChanged -= value;
171                 if (_audioStateChanged == null)
172                 {
173                     UnregisterAudioStateChangedEvent();
174                 }
175             }
176         }
177
178         /// <summary>
179         /// This event is raised during DTMF indication.
180         /// </summary>
181         public event EventHandler<DtmfIndicationEventArgs> DtmfIndication
182         {
183             add
184             {
185                 if (_dtmfIndication == null)
186                 {
187                     RegisterDtmfIndicationEvent();
188                 }
189
190                 _dtmfIndication += value;
191             }
192
193             remove
194             {
195                 _dtmfIndication -= value;
196                 if (_dtmfIndication == null)
197                 {
198                     UnregisterDtmfIndicationEvent();
199                 }
200             }
201         }
202
203         /// <summary>
204         /// This event is raised when call comes to foreground.
205         /// </summary>
206         public event EventHandler<EventArgs> GoForeground
207         {
208             add
209             {
210                 if (_goForeGround == null)
211                 {
212                     RegisterGoForegroundEvent();
213                 }
214
215                 _goForeGround += value;
216             }
217
218             remove
219             {
220                 _goForeGround -= value;
221                 if (_goForeGround == null)
222                 {
223                     UnregisterGoForegroundEvent();
224                 }
225             }
226         }
227
228         /// <summary>
229         /// This event is raised when voice record status is changed.
230         /// </summary>
231         public event EventHandler<VoiceRecordStatusEventArgs> VoiceRecordStatusChanged
232         {
233             add
234             {
235                 if (_voiceRecordStatusChanged == null)
236                 {
237                     RegisterVoiceRecordStatusEvent();
238                 }
239
240                 _voiceRecordStatusChanged += value;
241             }
242
243             remove
244             {
245                 _voiceRecordStatusChanged -= value;
246                 if (_voiceRecordStatusChanged == null)
247                 {
248                     UnregisterVoiceRecordStatusEvent();
249                 }
250             }
251         }
252
253         private void RegisterCallStatusChangedEvent()
254         {
255             _callStatusChangedCb = (CallStatus status, IntPtr number, IntPtr userData) =>
256             {
257                 _callStatusChanged?.Invoke(null, new CallStatusChangedEventArgs(status, Marshal.PtrToStringAnsi(number)));
258             };
259             int ret = Interop.CallManager.SetCallStatusCallback(_handle, _callStatusChangedCb, IntPtr.Zero);
260             if (ret != (int)CmError.None)
261             {
262                 Log.Error(CmUtility.LogTag, "Failed to set call status changed callback, Error: " + (CmError)ret);
263                 CmUtility.ThrowCmException(ret, _handle);
264             }
265         }
266
267         private void UnregisterCallStatusChangedEvent()
268         {
269             int ret = Interop.CallManager.UnsetCallstatusCallback(_handle);
270             if (ret != (int)CmError.None)
271             {
272                 Log.Error(CmUtility.LogTag, "Failed to unset call status changed callback, Error: " + (CmError)ret);
273                 CmUtility.ThrowCmException(ret, _handle);
274             }
275         }
276
277         private void RegisterCallMuteStatusChangedEvent()
278         {
279             _callMuteStatusChangedCb = (CallMuteStatus muteStatus, IntPtr userData) =>
280             {
281                 _callMuteStatusChanged?.Invoke(null, new CallMuteStatusChangedEventArgs(muteStatus));
282             };
283             int ret = Interop.CallManager.SetCallMuteStatusCallback(_handle, _callMuteStatusChangedCb, IntPtr.Zero);
284             if (ret != (int)CmError.None)
285             {
286                 Log.Error(CmUtility.LogTag, "Failed to set call mute status changed callback, Error: " + (CmError)ret);
287                 CmUtility.ThrowCmException(ret, _handle);
288             }
289         }
290
291         private void UnregisterCallMuteStatusChangedEvent()
292         {
293             int ret = Interop.CallManager.UnsetCallMuteStatusCallback(_handle);
294             if (ret != (int)CmError.None)
295             {
296                 Log.Error(CmUtility.LogTag, "Failed to unset call mute status changed callback, Error: " + (CmError)ret);
297                 CmUtility.ThrowCmException(ret, _handle);
298             }
299         }
300
301         private void RegisterCallEventNotification()
302         {
303             _callEventCb = (CallEvent callEvent, IntPtr eventData, IntPtr userData) =>
304             {
305                 _callEvent?.Invoke(null, new CallEventEventArgs(callEvent, CmUtility.GetCallEventData(callEvent, eventData)));
306             };
307             int ret = Interop.CallManager.SetCallEventCb(_handle, _callEventCb, IntPtr.Zero);
308             if (ret != (int)CmError.None)
309             {
310                 Log.Error(CmUtility.LogTag, "Failed to set call event notification callback, Error: " + (CmError)ret);
311                 CmUtility.ThrowCmException(ret, _handle);
312             }
313         }
314
315         private void UnregisterCallEventNotification()
316         {
317             int ret = Interop.CallManager.UnsetCallEventCb(_handle);
318             if (ret != (int)CmError.None)
319             {
320                 Log.Error(CmUtility.LogTag, "Failed to unset call event notification callback, Error: " + (CmError)ret);
321                 CmUtility.ThrowCmException(ret, _handle);
322             }
323         }
324
325         private void RegisterDialStatusEvent()
326         {
327             _dialStatusChangedCb = (DialStatus status, IntPtr userData) =>
328             {
329                 _dialStatusChanged?.Invoke(null, new DialStatusEventArgs(status));
330             };
331             int ret = Interop.CallManager.SetDialStatusCb(_handle, _dialStatusChangedCb, IntPtr.Zero);
332             if (ret != (int)CmError.None)
333             {
334                 Log.Error(CmUtility.LogTag, "Failed to set dial status changed callback, Error: " + (CmError)ret);
335                 CmUtility.ThrowCmException(ret, _handle);
336             }
337         }
338
339         private void UnregisterDialStatusEvent()
340         {
341             int ret = Interop.CallManager.UnsetDialStatusCb(_handle);
342             if (ret != (int)CmError.None)
343             {
344                 Log.Error(CmUtility.LogTag, "Failed to unset dial status changed callback, Error: " + (CmError)ret);
345                 CmUtility.ThrowCmException(ret, _handle);
346             }
347         }
348
349         private void RegisterAudioStateChangedEvent()
350         {
351             _audioStateChangedCb = (AudioState state, IntPtr userData) =>
352             {
353                 _audioStateChanged?.Invoke(null, new AudioStatusChangedEventArgs(state));
354             };
355             int ret = Interop.CallManager.SetAudioStateChangedCb(_handle, _audioStateChangedCb, IntPtr.Zero);
356             if (ret != (int)CmError.None)
357             {
358                 Log.Error(CmUtility.LogTag, "Failed to set audio state changed callback, Error: " + (CmError)ret);
359                 CmUtility.ThrowCmException(ret, _handle);
360             }
361         }
362
363         private void UnregisterAudioStateChangedEvent()
364         {
365             int ret = Interop.CallManager.UnsetAudioStateChangedCb(_handle);
366             if (ret != (int)CmError.None)
367             {
368                 Log.Error(CmUtility.LogTag, "Failed to unset audio state changed callback, Error: " + (CmError)ret);
369                 CmUtility.ThrowCmException(ret, _handle);
370             }
371         }
372
373         private void RegisterDtmfIndicationEvent()
374         {
375             _dtmfIndicationChangedCb = (DtmfIndication indiType, string number, IntPtr userData) =>
376             {
377                 _dtmfIndication?.Invoke(null, new DtmfIndicationEventArgs(indiType, number));
378             };
379             int ret = Interop.CallManager.SetDtmfIndicationCb(_handle, _dtmfIndicationChangedCb, IntPtr.Zero);
380             if (ret != (int)CmError.None)
381             {
382                 Log.Error(CmUtility.LogTag, "Failed to set DTMF indication changed callback, Error: " + (CmError)ret);
383                 CmUtility.ThrowCmException(ret, _handle);
384             }
385         }
386
387         private void UnregisterDtmfIndicationEvent()
388         {
389             int ret = Interop.CallManager.UnsetDtmfIndicationCb(_handle);
390             if (ret != (int)CmError.None)
391             {
392                 Log.Error(CmUtility.LogTag, "Failed to unset DTMF indication changed callback, Error: " + (CmError)ret);
393                 CmUtility.ThrowCmException(ret, _handle);
394             }
395         }
396
397         private void RegisterGoForegroundEvent()
398         {
399             _goForeGroundCb = (IntPtr userData) =>
400             {
401                 _goForeGround?.Invoke(null, EventArgs.Empty);
402             };
403             int ret = Interop.CallManager.SetForegroundCb(_handle, _goForeGroundCb, IntPtr.Zero);
404             if (ret != (int)CmError.None)
405             {
406                 Log.Error(CmUtility.LogTag, "Failed to set go foreground callback, Error: " + (CmError)ret);
407                 CmUtility.ThrowCmException(ret, _handle);
408             }
409         }
410
411         private void UnregisterGoForegroundEvent()
412         {
413             int ret = Interop.CallManager.UnsetForegroundCb(_handle);
414             if (ret != (int)CmError.None)
415             {
416                 Log.Error(CmUtility.LogTag, "Failed to unset go foreground callback, Error: " + (CmError)ret);
417                 CmUtility.ThrowCmException(ret, _handle);
418             }
419         }
420
421         private void RegisterVoiceRecordStatusEvent()
422         {
423             _voiceRecordStatusChangedCb = (VrStatus vrStatus, VrStatusExtraType extraType, IntPtr userData) =>
424             {
425                 _voiceRecordStatusChanged?.Invoke(null, new VoiceRecordStatusEventArgs(vrStatus, extraType));
426             };
427             int ret = Interop.CallManager.SetVoiceRecordStatusCb(_handle, _voiceRecordStatusChangedCb, IntPtr.Zero);
428             if (ret != (int)CmError.None)
429             {
430                 Log.Error(CmUtility.LogTag, "Failed to set voice record status changed callback, Error: " + (CmError)ret);
431                 CmUtility.ThrowCmException(ret, _handle);
432             }
433         }
434
435         private void UnregisterVoiceRecordStatusEvent()
436         {
437             int ret = Interop.CallManager.UnsetVoiceRecordStatusCb(_handle);
438             if (ret != (int)CmError.None)
439             {
440                 Log.Error(CmUtility.LogTag, "Failed to unset voice record status changed callback, Error: " + (CmError)ret);
441                 CmUtility.ThrowCmException(ret, _handle);
442             }
443         }
444
445         /// <summary>
446         /// Gets the status of the current call.
447         /// </summary>
448         public CallStatus CallStatus
449         {
450             get
451             {
452                 int ret = Interop.CallManager.GetStatus(_handle, out CallStatus status);
453                 if (ret != (int)CmError.None)
454                 {
455                     Log.Error(CmUtility.LogTag, "Failed to get call status, Error: " + (CmError)ret);
456                     return default(CallStatus);
457                 }
458
459                 return status;
460             }
461         }
462
463         /// <summary>
464         /// Gets the mute status.
465         /// </summary>
466         public CallMuteStatus CallMuteStatus
467         {
468             get
469             {
470                 int ret = Interop.CallManager.GetMuteStatus(_handle, out CallMuteStatus status);
471                 if (ret != (int)CmError.None)
472                 {
473                     Log.Error(CmUtility.LogTag, "Failed to get call mute status, Error: " + (CmError)ret);
474                     return default(CallMuteStatus);
475                 }
476
477                 return status;
478             }
479         }
480
481         /// <summary>
482         /// Gets the audio state.
483         /// </summary>
484         public AudioState AudioState
485         {
486             get
487             {
488                 int ret = Interop.CallManager.GetAudioState(_handle, out AudioState state);
489                 if (ret != (int)CmError.None)
490                 {
491                     Log.Error(CmUtility.LogTag, "Failed to get audio state, Error: " + (CmError)ret);
492                     return default(AudioState);
493                 }
494
495                 return state;
496             }
497         }
498
499         /// <summary>
500         /// Gets the list of call data.
501         /// </summary>
502         public IEnumerable<CallData> AllCalls
503         {
504             get
505             {
506                 int ret = Interop.CallManager.GetAllCallList(_handle, out IntPtr list);
507                 if (ret != (int)CmError.None)
508                 {
509                     Log.Error(CmUtility.LogTag, "Failed to get all call list, Error: " + (CmError)ret);
510                     return null;
511                 }
512
513                 int length = Interop.GsList.GetLength(list);
514                 if (length == 0)
515                 {
516                     Log.Debug(CmUtility.LogTag, "Call list is empty");
517                     return Enumerable.Empty<CallData>();
518                 }
519
520                 List<CallData> callList = new List<CallData>();
521                 IntPtr callData = IntPtr.Zero;
522                 for (int index = 0; index < length; index++)
523                 {
524                     callData = Interop.GsList.GetDataByIndex(list, index);
525                     if (callData != IntPtr.Zero)
526                     {
527                         callList.Add(CmUtility.GetCallData(callData));
528                     }
529                 }
530
531                 return callList;
532             }
533         }
534
535         /// <summary>
536         /// Gets the list of conference call data.
537         /// </summary>
538         public IEnumerable<ConferenceCallData> AllConferenceCalls
539         {
540             get
541             {
542                 int ret = Interop.CallManager.GetConferenceCallList(_handle, out IntPtr list);
543                 if (ret != (int)CmError.None)
544                 {
545                     Log.Error(CmUtility.LogTag, "Failed to get conference call list, Error: " + (CmError)ret);
546                     return null;
547                 }
548
549                 int length = Interop.GsList.GetLength(list);
550                 if (length == 0)
551                 {
552                     Log.Debug(CmUtility.LogTag, "Conf call list is empty");
553                     return Enumerable.Empty<ConferenceCallData>();
554                 }
555                 List<ConferenceCallData> confList = new List<ConferenceCallData>();
556                 IntPtr confData = IntPtr.Zero;
557                 for (int index = 0; index < length; index++)
558                 {
559                     confData = Interop.GsList.GetDataByIndex(list, index);
560                     if (confData != IntPtr.Zero)
561                     {
562                         confList.Add(CmUtility.GetConfCallData(confData));
563                     }
564                 }
565
566                 return confList;
567             }
568         }
569
570         /// <summary>
571         /// Rejects the incoming call.
572         /// </summary>
573         /// <privlevel>partner</privlevel>
574         /// <privilege>http://developer.samsung.com/tizen/privilege/call.reject</privilege>
575         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
576         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
577         public void RejectCall()
578         {
579             int ret = Interop.CallManager.RejectCall(_handle);
580             if (ret != (int)CmError.None)
581             {
582                 Log.Error(CmUtility.LogTag, "Failed to reject call, Error: " + (CmError)ret);
583                 CmUtility.ThrowCmException(ret, _handle, "http://developer.samsung.com/tizen/privilege/call.reject");
584             }
585         }
586
587         /// <summary>
588         /// Starts incoming call alert ringtone.
589         /// </summary>
590         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
591         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
592         public void StartAlert()
593         {
594             int ret = Interop.CallManager.StartAlert(_handle);
595             if (ret != (int)CmError.None)
596             {
597                 Log.Error(CmUtility.LogTag, "Failed to start incoming call alert, Error: " + (CmError)ret);
598                 CmUtility.ThrowCmException(ret, _handle);
599             }
600         }
601
602         /// <summary>
603         /// Stops incoming call alert ringtone.
604         /// </summary>
605         /// <privlevel>partner</privlevel>
606         /// <privilege>http://developer.samsung.com/tizen/privilege/call.reject</privilege>
607         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
608         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
609         public void StopAlert()
610         {
611             int ret = Interop.CallManager.StopAlert(_handle);
612             if (ret != (int)CmError.None)
613             {
614                 Log.Error(CmUtility.LogTag, "Failed to stop incoming call alert, Error: " + (CmError)ret);
615                 CmUtility.ThrowCmException(ret, _handle, "http://developer.samsung.com/tizen/privilege/call.reject");
616             }
617         }
618
619         /// <summary>
620         /// Enables call recovery.
621         /// </summary>
622         /// <param name="appId">App ID to be recovered.</param>
623         /// <exception cref="ArgumentNullException">Thrown appId is passed as null.</exception>
624         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
625         public void EnableRecovery(string appId)
626         {
627             if (appId == null)
628             {
629                 throw new ArgumentNullException("App ID is null");
630             }
631
632             int ret = Interop.CallManager.EnableRecovery(_handle, appId);
633             if (ret != (int)CmError.None)
634             {
635                 Log.Error(CmUtility.LogTag, "Failed to enable recovery, Error: " + (CmError)ret);
636                 CmUtility.ThrowCmException(ret, _handle);
637             }
638         }
639
640         /// <summary>
641         /// Dials a call.
642         /// </summary>
643         /// <param name="number">Calling number to be dialed.</param>
644         /// <param name="type">Type of the call to be dialed.</param>
645         /// <param name="slot">Multi sim slot type in which the call is dialed.</param>
646         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
647         /// <exception cref="ArgumentNullException">Thrown number is passed as null.</exception>
648         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
649         public void DialCall(string number, CallType type, MultiSimSlot slot)
650         {
651             if (number == null)
652             {
653                 throw new ArgumentNullException("Calling number is null");
654             }
655
656             int ret = Interop.CallManager.DialCall(_handle, number, type, slot);
657             if (ret != (int)CmError.None)
658             {
659                 Log.Error(CmUtility.LogTag, "Failed to dial call, Error: " + (CmError)ret);
660                 CmUtility.ThrowCmException(ret, _handle);
661             }
662         }
663
664         /// <summary>
665         /// Swaps the calls.
666         /// </summary>
667         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
668         public void SwapCall()
669         {
670             int ret = Interop.CallManager.SwapCall(_handle);
671             if (ret != (int)CmError.None)
672             {
673                 Log.Error(CmUtility.LogTag, "Failed to swap call, Error: " + (CmError)ret);
674                 CmUtility.ThrowCmException(ret, _handle);
675             }
676         }
677
678         /// <summary>
679         /// Joins a call with another.
680         /// </summary>
681         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
682         public void JoinCall()
683         {
684             int ret = Interop.CallManager.JoinCall(_handle);
685             if (ret != (int)CmError.None)
686             {
687                 Log.Error(CmUtility.LogTag, "Failed to join call, Error: " + (CmError)ret);
688                 CmUtility.ThrowCmException(ret, _handle);
689             }
690         }
691
692         /// <summary>
693         /// Splits a call.
694         /// </summary>
695         /// <param name="id">Call id to be splitted.</param>
696         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
697         public void SplitCall(uint id)
698         {
699             int ret = Interop.CallManager.SplitCall(_handle, id);
700             if (ret != (int)CmError.None)
701             {
702                 Log.Error(CmUtility.LogTag, "Failed to split call, Error: " + (CmError)ret);
703                 CmUtility.ThrowCmException(ret, _handle);
704             }
705         }
706
707         /// <summary>
708         /// Transfers a call.
709         /// </summary>
710         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
711         public void TransferCall()
712         {
713             int ret = Interop.CallManager.TransferCall(_handle);
714             if (ret != (int)CmError.None)
715             {
716                 Log.Error(CmUtility.LogTag, "Failed to transfer call, Error: " + (CmError)ret);
717                 CmUtility.ThrowCmException(ret, _handle);
718             }
719         }
720
721         /// <summary>
722         /// Accepts MT ViLTE call as VoLTE.
723         /// </summary>
724         /// <param name="answerType">Call answer type.</param>
725         /// <param name="type">Call type.</param>
726         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
727         public void AnswerCallEx(CallAnswerType answerType, CallType type)
728         {
729             int ret = Interop.CallManager.AnswerCallEx(_handle, answerType, type);
730             if (ret != (int)CmError.None)
731             {
732                 Log.Error(CmUtility.LogTag, "Failed to answer call, Error: " + (CmError)ret);
733                 CmUtility.ThrowCmException(ret, _handle);
734             }
735         }
736
737         /// <summary>
738         /// Answers an incoming call.
739         /// </summary>
740         /// <param name="answerType">Call answer type.</param>
741         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
742         public void AnswerCall(CallAnswerType answerType)
743         {
744             int ret = Interop.CallManager.AnswerCall(_handle, answerType);
745             if (ret != (int)CmError.None)
746             {
747                 Log.Error(CmUtility.LogTag, "Failed to answer call, Error: " + (CmError)ret);
748                 CmUtility.ThrowCmException(ret, _handle);
749             }
750         }
751
752         /// <summary>
753         /// Upgrades a call.
754         /// </summary>
755         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
756         public void UpgradeCall()
757         {
758             int ret = Interop.CallManager.UpgradeCall(_handle);
759             if (ret != (int)CmError.None)
760             {
761                 Log.Error(CmUtility.LogTag, "Failed to upgrade call, Error: " + (CmError)ret);
762                 CmUtility.ThrowCmException(ret, _handle);
763             }
764         }
765
766         /// <summary>
767         /// Downgrades a call.
768         /// </summary>
769         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
770         public void DowngradeCall()
771         {
772             int ret = Interop.CallManager.DowngradeCall(_handle);
773             if (ret != (int)CmError.None)
774             {
775                 Log.Error(CmUtility.LogTag, "Failed to downgrade call, Error: " + (CmError)ret);
776                 CmUtility.ThrowCmException(ret, _handle);
777             }
778         }
779
780         /// <summary>
781         /// Confirms upgrade call request.
782         /// </summary>
783         /// <param name="response">Upgrade response type.</param>
784         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
785         public void ConfirmUpgradeCall(CallUpgradeResponseType response)
786         {
787             int ret = Interop.CallManager.ConfirmUpgradeCall(_handle, response);
788             if (ret != (int)CmError.None)
789             {
790                 Log.Error(CmUtility.LogTag, "Failed to confirm upgrade call, Error: " + (CmError)ret);
791                 CmUtility.ThrowCmException(ret, _handle);
792             }
793         }
794
795         /// <summary>
796         /// Sets the speaker on/off.
797         /// </summary>
798         /// <param name="status">Status of the speaker to be set.</param>
799         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
800         public void ManageSpeaker(FeatureStatus status)
801         {
802             int ret = -1;
803             if (status == FeatureStatus.Off)
804             {
805                 ret = Interop.CallManager.SpeakerOff(_handle);
806             }
807
808             else if (status == FeatureStatus.On)
809             {
810                 ret = Interop.CallManager.SpeakerOn(_handle);
811             }
812
813             if (ret != (int)CmError.None)
814             {
815                 Log.Error(CmUtility.LogTag, "Failed to manage speaker, Error: " + (CmError)ret);
816                 CmUtility.ThrowCmException(ret, _handle);
817             }
818         }
819
820         /// <summary>
821         /// Sets the bluetooth feature on/off.
822         /// </summary>
823         /// <param name="status">Status of the bluetooth to be set.</param>
824         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
825         public void ManageBluetooth(FeatureStatus status)
826         {
827             int ret = -1;
828             if (status == FeatureStatus.Off)
829             {
830                 ret = Interop.CallManager.BluetoothOff(_handle);
831             }
832
833             else if (status == FeatureStatus.On)
834             {
835                 ret = Interop.CallManager.BluetoothOn(_handle);
836             }
837
838             if (ret != (int)CmError.None)
839             {
840                 Log.Error(CmUtility.LogTag, "Failed to manage bluetooth, Error: " + (CmError)ret);
841                 CmUtility.ThrowCmException(ret, _handle);
842             }
843         }
844
845         /// <summary>
846         /// Sets extra volume if needed.
847         /// </summary>
848         /// <param name="isExtraVolume">Boolean value to indicate if the call is set to have extra volume.</param>
849         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
850         public void SetExtraVolume(bool isExtraVolume)
851         {
852             int ret = Interop.CallManager.SetExtraVolume(_handle, isExtraVolume);
853             if (ret != (int)CmError.None)
854             {
855                 Log.Error(CmUtility.LogTag, "Failed to set extra volume, Error: " + (CmError)ret);
856                 CmUtility.ThrowCmException(ret, _handle);
857             }
858         }
859
860         /// <summary>
861         /// Sets the noise reduction feature during call.
862         /// </summary>
863         /// <param name="isNoiceReduction">Boolean value to indicate whether the call needs noise reduction.</param>
864         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
865         public void SetNoiseReduction(bool isNoiceReduction)
866         {
867             int ret = Interop.CallManager.SetNoiseReduction(_handle, isNoiceReduction);
868             if (ret != (int)CmError.None)
869             {
870                 Log.Error(CmUtility.LogTag, "Failed to set noise reduction, Error: " + (CmError)ret);
871                 CmUtility.ThrowCmException(ret, _handle);
872             }
873         }
874
875         /// <summary>
876         /// Sets the mute state of the call.
877         /// </summary>
878         /// <param name="isMuteState">Mute state to be set.</param>
879         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
880         public void SetMuteState(bool isMuteState)
881         {
882             int ret = Interop.CallManager.SetMuteState(_handle, isMuteState);
883             if (ret != (int)CmError.None)
884             {
885                 Log.Error(CmUtility.LogTag, "Failed to set mute state, Error: " + (CmError)ret);
886                 CmUtility.ThrowCmException(ret, _handle);
887             }
888         }
889
890         /// <summary>
891         /// Starts sending signal through DTMF digit.
892         /// </summary>
893         /// <param name="dtmfDigit">DTMF digit to be pressed on the phone.</param>
894         /// <exception cref="ArgumentException">Thrown when method failed due to invalid parameter.</exception>
895         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
896         public void StartDtmf(byte dtmfDigit)
897         {
898             int ret = Interop.CallManager.StartDtmf(_handle, dtmfDigit);
899             if (ret != (int)CmError.None)
900             {
901                 Log.Error(CmUtility.LogTag, "Failed to start DTMF, Error: " + (CmError)ret);
902                 CmUtility.ThrowCmException(ret, _handle);
903             }
904         }
905
906         /// <summary>
907         /// Stops sending DTMF signal.
908         /// </summary>
909         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
910         public void StopDtmf()
911         {
912             int ret = Interop.CallManager.StopDtmf(_handle);
913             if (ret != (int)CmError.None)
914             {
915                 Log.Error(CmUtility.LogTag, "Failed to stop DTMF, Error: " + (CmError)ret);
916                 CmUtility.ThrowCmException(ret, _handle);
917             }
918         }
919
920         /// <summary>
921         /// Sends signal through DTMF digits.
922         /// </summary>
923         /// <param name="dtmfDigits">DTMF digits.</param>
924         /// <exception cref="ArgumentNullException">Thrown when dtmfDigits is passed as null.</exception>
925         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
926         public void BurstDtmf(string dtmfDigits)
927         {
928             if (dtmfDigits == null)
929             {
930                 throw new ArgumentNullException("DTMF digits is null");
931             }
932
933             int ret = Interop.CallManager.BurstDtmf(_handle, dtmfDigits);
934             if (ret != (int)CmError.None)
935             {
936                 Log.Error(CmUtility.LogTag, "Failed to burst DTMF, Error: " + (CmError)ret);
937                 CmUtility.ThrowCmException(ret, _handle);
938             }
939         }
940
941         /// <summary>
942         /// Sends DTMF response.
943         /// </summary>
944         /// <param name="response">DTMF response type.</param>
945         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
946         public void SendDtmfResponse(DtmfResponseType response)
947         {
948             int ret = Interop.CallManager.SendDtmfResponse(_handle, response);
949             if (ret != (int)CmError.None)
950             {
951                 Log.Error(CmUtility.LogTag, "Failed to send DTMF response, Error: " + (CmError)ret);
952                 CmUtility.ThrowCmException(ret, _handle);
953             }
954         }
955
956         /// <summary>
957         /// Activates call manager UI.
958         /// </summary>
959         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
960         public void ActivateUi()
961         {
962             int ret = Interop.CallManager.ActivateUi(_handle);
963             if (ret != (int)CmError.None)
964             {
965                 Log.Error(CmUtility.LogTag, "Failed to activate UI, Error: " + (CmError)ret);
966                 CmUtility.ThrowCmException(ret, _handle);
967             }
968         }
969
970         /// <summary>
971         /// Sets device LCD time out.
972         /// </summary>
973         /// <param name="timeout">LCD timeout to be set.</param>
974         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
975         public void SetLcdTimeout(LcdTimeOut timeout)
976         {
977             int ret = Interop.CallManager.SetLcdTimeOut(_handle, timeout);
978             if (ret != (int)CmError.None)
979             {
980                 Log.Error(CmUtility.LogTag, "Failed to set LCD timeout, Error: " + (CmError)ret);
981                 CmUtility.ThrowCmException(ret, _handle);
982             }
983         }
984
985         /// <summary>
986         /// Starts voice recording.
987         /// </summary>
988         /// <param name="number">Call number.</param>
989         /// <exception cref="ArgumentNullException">Thrown when number is passed as null.</exception>
990         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
991         public void StartVoiceRecord(string number)
992         {
993             if (number == null)
994             {
995                 throw new ArgumentNullException("Call number is null");
996             }
997
998             int ret = Interop.CallManager.StartVoiceRecord(_handle, number);
999             if (ret != (int)CmError.None)
1000             {
1001                 Log.Error(CmUtility.LogTag, "Failed to start voice record, Error: " + (CmError)ret);
1002                 CmUtility.ThrowCmException(ret, _handle);
1003             }
1004         }
1005
1006         /// <summary>
1007         /// Stops voice record.
1008         /// </summary>
1009         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
1010         public void StopVoiceRecord()
1011         {
1012             int ret = Interop.CallManager.StopVoiceRecord(_handle);
1013             if (ret != (int)CmError.None)
1014             {
1015                 Log.Error(CmUtility.LogTag, "Failed to stop voice record, Error: " + (CmError)ret);
1016                 CmUtility.ThrowCmException(ret, _handle);
1017             }
1018         }
1019
1020         /// <summary>
1021         /// Gets all current call data.
1022         /// </summary>
1023         /// <param name="incoming">Incoming calldata instance to be filled.</param>
1024         /// <param name="active">Active calldata instance to be filled.</param>
1025         /// <param name="held">Held calldata instance to be filled.</param>
1026         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
1027         public void GetAllCallData(out CallData incoming, out CallData active, out CallData held)
1028         {
1029             int ret = Interop.CallManager.GetAllCallData(_handle, out IntPtr incomingCall, out IntPtr activeCall, out IntPtr heldCall);
1030             if (ret != (int)CmError.None)
1031             {
1032                 Log.Error(CmUtility.LogTag, "Failed to get all call data, Error: " + (CmError)ret);
1033                 CmUtility.ThrowCmException(ret, _handle);
1034             }
1035
1036             incoming = CmUtility.GetCallData(incomingCall);
1037             active = CmUtility.GetCallData(activeCall);
1038             held = CmUtility.GetCallData(heldCall);
1039         }
1040
1041         /// <summary>
1042         /// Holds the active call.
1043         /// </summary>
1044         /// <privlevel>platform</privlevel>
1045         /// <privilege>http://developer.samsung.com/tizen/privilege/call.admin</privilege>
1046         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1047         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
1048         public void HoldCall()
1049         {
1050             int ret = Interop.CallManager.HoldCall(_handle);
1051             if (ret != (int)CmError.None)
1052             {
1053                 Log.Error(CmUtility.LogTag, "Failed to hold call, Error: " + (CmError)ret);
1054                 CmUtility.ThrowCmException(ret, _handle, "http://developer.samsung.com/tizen/privilege/call.admin");
1055             }
1056         }
1057
1058         /// <summary>
1059         /// Unholds the active call.
1060         /// </summary>
1061         /// <privlevel>platform</privlevel>
1062         /// <privilege>http://developer.samsung.com/tizen/privilege/call.admin</privilege>
1063         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1064         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
1065         public void UnholdCall()
1066         {
1067             int ret = Interop.CallManager.UnholdCall(_handle);
1068             if (ret != (int)CmError.None)
1069             {
1070                 Log.Error(CmUtility.LogTag, "Failed to unhold call, Error: " + (CmError)ret);
1071                 CmUtility.ThrowCmException(ret, _handle, "http://developer.samsung.com/tizen/privilege/call.admin");
1072             }
1073         }
1074
1075         /// <summary>
1076         /// Ends ongoing call.
1077         /// </summary>
1078         /// <param name="id">ID of the call which is to be ended.</param>
1079         /// <param name="type">Call release type.</param>
1080         /// <privlevel>platform</privlevel>
1081         /// <privilege>http://developer.samsung.com/tizen/privilege/call.admin</privilege>
1082         /// <exception cref="UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1083         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation.</exception>
1084         public void EndCall(uint id, CallReleaseType type)
1085         {
1086             int ret = Interop.CallManager.EndCall(_handle, id, type);
1087             if (ret != (int)CmError.None)
1088             {
1089                 Log.Error(CmUtility.LogTag, "Failed to end call, Error: " + (CmError)ret);
1090                 CmUtility.ThrowCmException(ret, _handle, "http://developer.samsung.com/tizen/privilege/call.admin");
1091             }
1092         }
1093     }
1094 }