Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Tapi / Tizen.Tapi / Call.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.Threading.Tasks;
21
22 namespace Tizen.Tapi
23 {
24     /// <summary>
25     /// This class provides functions to manage call related setup and methods.
26     /// </summary>
27     public class Call
28     {
29         private IntPtr _handle;
30         private Dictionary<IntPtr, Interop.Tapi.TapiResponseCallback> _response_map = new Dictionary<IntPtr, Interop.Tapi.TapiResponseCallback>();
31         private Interop.Tapi.CallStatusCallback _callStatusCb;
32         private int _requestId = 0;
33
34         /// <summary>
35         /// A public constructor for Call class to create a Call instance for the given tapi handle.
36         /// </summary>
37         /// <param name="handle">The tapi handle.</param>
38         public Call(TapiHandle handle)
39         {
40             if (handle == null)
41             {
42                 throw new ArgumentNullException("TapiHandle parameter is null");
43             }
44
45             _handle = handle._handle;
46         }
47
48         /// <summary>
49         /// Setup the call to be dialled asynchronously.
50         /// </summary>
51         /// <param name="info">Information of call type and number.</param>
52         /// <returns>A task indicating whether the DialCall method is done or not.</returns>
53         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
54         /// <privlevel>platform</privlevel>
55         /// <feature>http://tizen.org/feature/network.telephony</feature>
56         /// <remarks>
57         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
58         /// </remarks>
59         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
60         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
61         /// <exception cref="System.ArgumentNullException">Thrown when CallInformation argument is null.</exception>
62         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
63         public Task DialCall(CallInformation info)
64         {
65             if (info != null)
66             {
67                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
68                 IntPtr id;
69                 id = (IntPtr)_requestId++;
70                 _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
71                 {
72                     Task resultTask = new Task(() =>
73                     {
74                         if (result != (int)TapiError.Success)
75                         {
76                             Log.Error(TapiUtility.LogTag, "Error occurs during call dial setup, " + (TapiError)result);
77                             task.SetException(new InvalidOperationException("Error occurs during call dial setup, " + (TapiError)result));
78                             return;
79                         }
80
81                         task.SetResult(true);
82                     });
83
84                     resultTask.Start();
85                     resultTask.Wait();
86                     _response_map.Remove(key);
87                 };
88
89                 CallInformationStruct callInfoStruct = CallClassConversions.ConvertCallInformationToStruct(info);
90                 int ret = Interop.Tapi.Call.DialCall(_handle, ref callInfoStruct, _response_map[id], id);
91                 if (ret != (int)TapiError.Success)
92                 {
93                     Log.Error(TapiUtility.LogTag, "Failed to dial call and do the call setup, Error: " + (TapiError)ret);
94                     TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
95                 }
96
97                 return task.Task;
98             }
99
100             else
101             {
102                 throw new ArgumentNullException("CallInformation argument is null");
103             }
104         }
105
106         /// <summary>
107         /// Supports answering the incoming call by accepting or rejecting the call asynchronously.
108         /// </summary>
109         /// <param name="callHandle">Unique handle that refer to the call.</param>
110         /// <param name="type">The answer type.</param>
111         /// <returns>The call id of answer call. This call handle is available to the application through an incoming call(IncomingVoiceCall) event.</returns>
112         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
113         /// <privlevel>platform</privlevel>
114         /// <feature>http://tizen.org/feature/network.telephony</feature>
115         /// <remarks>
116         /// There can be a maximum of one existing call.
117         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
118         /// </remarks>
119         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
120         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
121         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
122         public Task<uint> AnswerCall(uint callHandle, CallAnswerType type)
123         {
124             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
125             IntPtr id;
126             id = (IntPtr)_requestId++;
127             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
128             {
129                 Task resultTask = new Task(() =>
130                 {
131                     if (result != (int)TapiError.Success)
132                     {
133                         Log.Error(TapiUtility.LogTag, "Error occurs during answering call, " + (TapiError)result);
134                         task.SetException(new InvalidOperationException("Error occurs during answering call, " + (TapiError)result));
135                         return;
136                     }
137
138                     CallOperationsStruct ansStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
139                     task.SetResult(ansStruct.id);
140                 });
141
142                 resultTask.Start();
143                 resultTask.Wait();
144                 _response_map.Remove(key);
145             };
146
147             int ret = Interop.Tapi.Call.AnswerCall(_handle, callHandle, type, _response_map[id], id);
148             if (ret != (int)TapiError.Success)
149             {
150                 Log.Error(TapiUtility.LogTag, "Failed to answer the incoming call, Error: " + (TapiError)ret);
151                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
152             }
153
154             return task.Task;
155         }
156
157         /// <summary>
158         /// Releases the call asynchronously irrespective of whether the call is in the hold or active state.
159         /// </summary>
160         /// <param name="callHandle">Unique handle that refer to the call.</param>
161         /// <param name="type">The end call type.</param>
162         /// <returns>Instance of CallEndData.</returns>
163         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
164         /// <privlevel>platform</privlevel>
165         /// <feature>http://tizen.org/feature/network.telephony</feature>
166         /// <remarks>
167         /// There should be an existing call in the active/hold state.
168         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
169         /// </remarks>
170         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
171         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
172         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
173         public Task<CallEndData> EndCall(uint callHandle, CallEndType type)
174         {
175             TaskCompletionSource<CallEndData> task = new TaskCompletionSource<CallEndData>();
176             IntPtr id;
177             id = (IntPtr)_requestId++;
178             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
179             {
180                 Task resultTask = new Task(() =>
181                 {
182                     if (result != (int)TapiError.Success)
183                     {
184                         Log.Error(TapiUtility.LogTag, "Error occurs during ending call, " + (TapiError)result);
185                         task.SetException(new InvalidOperationException("Error occurs during ending call, " + (TapiError)result));
186                         return;
187                     }
188
189                     CallEndStruct endStruct = Marshal.PtrToStructure<CallEndStruct>(data);
190                     CallEndData endDataClass = new CallEndData(endStruct.type, endStruct.id);
191                     task.SetResult(endDataClass);
192                 });
193
194                 resultTask.Start();
195                 resultTask.Wait();
196                 _response_map.Remove(key);
197             };
198
199             int ret = Interop.Tapi.Call.EndCall(_handle, callHandle, type, _response_map[id], id);
200             if (ret != (int)TapiError.Success)
201             {
202                 Log.Error(TapiUtility.LogTag, "Failed to end the call, Error: " + (TapiError)ret);
203                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
204             }
205
206             return task.Task;
207         }
208
209         /// <summary>
210         /// Puts the given call on hold asynchoronously.
211         /// </summary>
212         /// <param name="callHandle">Unique handle for referring the call.</param>
213         /// <returns>The call id of hold call.</returns>
214         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
215         /// <privlevel>platform</privlevel>
216         /// <feature>http://tizen.org/feature/network.telephony</feature>
217         /// <remarks>
218         /// The call should be in the active state.
219         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
220         /// </remarks>
221         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
222         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
223         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
224         public Task<uint> HoldCall(uint callHandle)
225         {
226             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
227             IntPtr id;
228             id = (IntPtr)_requestId++;
229             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
230             {
231                 Task resultTask = new Task(() =>
232                 {
233                     if (result != (int)TapiError.Success)
234                     {
235                         Log.Error(TapiUtility.LogTag, "Error occurs during putting call on hold, " + (TapiError)result);
236                         task.SetException(new InvalidOperationException("Error occurs during putting call on hold, " + (TapiError)result));
237                         return;
238                     }
239
240                     CallOperationsStruct holdStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
241                     task.SetResult(holdStruct.id);
242                 });
243
244                 resultTask.Start();
245                 resultTask.Wait();
246                 _response_map.Remove(key);
247             };
248
249             int ret = Interop.Tapi.Call.HoldCall(_handle, callHandle, _response_map[id], id);
250             if (ret != (int)TapiError.Success)
251             {
252                 Log.Error(TapiUtility.LogTag, "Failed to put the call on hold, Error: " + (TapiError)ret);
253                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
254             }
255
256             return task.Task;
257         }
258
259         /// <summary>
260         /// Retrieves the call being held asynchoronously.
261         /// </summary>
262         /// <param name="callHandle">Unique handle for referring the call.</param>
263         /// <returns>The call id of active call.</returns>
264         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
265         /// <privlevel>platform</privlevel>
266         /// <feature>http://tizen.org/feature/network.telephony</feature>
267         /// <remarks>
268         /// Call should be in the held state in order to retrieve it into the active state unless no active call is present.
269         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
270         /// </remarks>
271         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
272         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
273         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
274         public Task<uint> ActiveCall(uint callHandle)
275         {
276             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
277             IntPtr id;
278             id = (IntPtr)_requestId++;
279             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
280             {
281                 Task resultTask = new Task(() =>
282                 {
283                     if (result != (int)TapiError.Success)
284                     {
285                         Log.Error(TapiUtility.LogTag, "Error occurs during retrieving the hold call, " + (TapiError)result);
286                         task.SetException(new InvalidOperationException("Error occurs during retrieving the hold call, " + (TapiError)result));
287                         return;
288                     }
289
290                     CallOperationsStruct activeStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
291                     task.SetResult(activeStruct.id);
292                 });
293
294                 resultTask.Start();
295                 resultTask.Wait();
296                 _response_map.Remove(key);
297             };
298
299             int ret = Interop.Tapi.Call.ActiveCall(_handle, callHandle, _response_map[id], id);
300             if (ret != (int)TapiError.Success)
301             {
302                 Log.Error(TapiUtility.LogTag, "Failed to retrieve the call which was on hold, Error: " + (TapiError)ret);
303                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
304             }
305
306             return task.Task;
307         }
308
309         /// <summary>
310         /// Swaps calls asynchoronously. This is only for calls dialed or answered with Telephony.
311         /// </summary>
312         /// <param name="activeCallHandle">Active call.</param>
313         /// <param name="heldCallHandle">Held call.</param>
314         /// <returns>The call id of swap call.</returns>
315         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
316         /// <privlevel>platform</privlevel>
317         /// <feature>http://tizen.org/feature/network.telephony</feature>
318         /// <remarks>
319         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
320         /// </remarks>
321         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
322         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
323         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
324         public Task<uint> SwapCall(uint activeCallHandle, uint heldCallHandle)
325         {
326             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
327             IntPtr id;
328             id = (IntPtr)_requestId++;
329             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
330             {
331                 Task resultTask = new Task(() =>
332                 {
333                     if (result != (int)TapiError.Success)
334                     {
335                         Log.Error(TapiUtility.LogTag, "Error occurs during swapping calls, " + (TapiError)result);
336                         task.SetException(new InvalidOperationException("Error occurs during swapping calls, " + (TapiError)result));
337                         return;
338                     }
339
340                     CallOperationsStruct activeStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
341                     task.SetResult(activeStruct.id);
342                 });
343
344                 resultTask.Start();
345                 resultTask.Wait();
346                 _response_map.Remove(key);
347             };
348
349             int ret = Interop.Tapi.Call.SwapCall(_handle, activeCallHandle, heldCallHandle, _response_map[id], id);
350             if (ret != (int)TapiError.Success)
351             {
352                 Log.Error(TapiUtility.LogTag, "Failed to swap the active and held calls, Error: " + (TapiError)ret);
353                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
354             }
355
356             return task.Task;
357         }
358
359         /// <summary>
360         /// Starts continuous dtmf by sending a single digit during the call asynchronously.
361         /// </summary>
362         /// <param name="digit">The dtmf digit to be sent.</param>
363         /// <returns>A task indicating whether the StartContDtmfCall method is done or not.</returns>
364         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
365         /// <privlevel>platform</privlevel>
366         /// <feature>http://tizen.org/feature/network.telephony</feature>
367         /// <remarks> An active call should be present. This is to be invoked in the following cases:
368         /// i. Key Release (post key press) during on-going call.
369         /// ii. Dtmf digits passed with PAUSE(,) or WAIT(;).
370         /// In case of PAUSE and WAIT, every StartContDtmfCall() call needs to be followed by StopContDtmfCall() sequentially (for every digit) without waiting for response from StartContDtmfCall().
371         /// </remarks>
372         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
373         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
374         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
375         public Task StartContDtmfCall(byte digit)
376         {
377             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
378             IntPtr id;
379             id = (IntPtr)_requestId++;
380             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
381             {
382                 Task resultTask = new Task(() =>
383                 {
384                     if (result != (int)TapiError.Success)
385                     {
386                         Log.Error(TapiUtility.LogTag, "Error occurs during starting continuous dtmf, " + (TapiError)result);
387                         task.SetException(new InvalidOperationException("Error occurs during starting continuous dtmf, " + (TapiError)result));
388                         return;
389                     }
390
391                     task.SetResult(true);
392                 });
393
394                 resultTask.Start();
395                 resultTask.Wait();
396                 _response_map.Remove(key);
397             };
398
399             int ret = Interop.Tapi.Call.StartContDtmfCall(_handle, digit, _response_map[id], id);
400             if (ret != (int)TapiError.Success)
401             {
402                 Log.Error(TapiUtility.LogTag, "Failed to start continuous dtmf during the call, Error: " + (TapiError)ret);
403                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
404             }
405
406             return task.Task;
407         }
408
409         /// <summary>
410         /// Stops continuous dtmf during the call asynchronously.
411         /// </summary>
412         /// <returns>A task indicating whether the StopContDtmfCall method is done or not.</returns>
413         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
414         /// <privlevel>platform</privlevel>
415         /// <feature>http://tizen.org/feature/network.telephony</feature>
416         /// <remarks> An active call should be present. This is to be invoked in the following cases:
417         /// i. Key Release (post key press) during on-going call.
418         /// ii. Dtmf digits passed with PAUSE(,) or WAIT(;).
419         /// Every StartContDtmfCall() call needs to be followed by StopContDtmfCall() sequentially.
420         /// </remarks>
421         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
422         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
423         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
424         public Task StopContDtmfCall()
425         {
426             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
427             IntPtr id;
428             id = (IntPtr)_requestId++;
429             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
430             {
431                 Task resultTask = new Task(() =>
432                 {
433                     if (result != (int)TapiError.Success)
434                     {
435                         Log.Error(TapiUtility.LogTag, "Error occurs during stopping continuous dtmf, " + (TapiError)result);
436                         task.SetException(new InvalidOperationException("Error occurs during stopping continuous dtmf, " + (TapiError)result));
437                         return;
438                     }
439
440                     task.SetResult(true);
441                 });
442
443                 resultTask.Start();
444                 resultTask.Wait();
445                 _response_map.Remove(key);
446             };
447
448             int ret = Interop.Tapi.Call.StopContDtmfCall(_handle, _response_map[id], id);
449             if (ret != (int)TapiError.Success)
450             {
451                 Log.Error(TapiUtility.LogTag, "Failed to stop continuous dtmf during the call, Error: " + (TapiError)ret);
452                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
453             }
454
455             return task.Task;
456         }
457
458         /// <summary>
459         /// Send one or more dtmf digits during the call asynchronously.
460         /// </summary>
461         /// <param name="dtmfData">A burst dtmf info containing dtmf string, pulse width, and inter digit interval.</param>
462         /// <returns>A task indicating whether the SendBurstDtmfCall method is done or not.</returns>
463         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
464         /// <privlevel>platform</privlevel>
465         /// <feature>http://tizen.org/feature/network.telephony</feature>
466         /// <remarks>
467         /// There will be a single asynchronous notification for all the dtmf digits sent. If the users of this API need an asynchronous
468         /// response for each dtmf digit then the user has to call this API multiple times passing each single dtmf digit in CallBurstDtmfData.
469         /// </remarks>
470         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
471         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
472         /// <exception cref="System.ArgumentNullException">Thrown when CallBurstDtmfData argument is null.</exception>
473         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
474         public Task SendBurstDtmfCall(CallBurstDtmfData dtmfData)
475         {
476             if (dtmfData != null)
477             {
478                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
479                 IntPtr id;
480                 id = (IntPtr)_requestId++;
481                 _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
482                 {
483                     Task resultTask = new Task(() =>
484                     {
485                         if (result != (int)TapiError.Success)
486                         {
487                             Log.Error(TapiUtility.LogTag, "Error occurs while sending dtmf digits, " + (TapiError)result);
488                             task.SetException(new InvalidOperationException("Error occurs while sending dtmf digits, " + (TapiError)result));
489                             return;
490                         }
491
492                         task.SetResult(true);
493                     });
494
495                     resultTask.Start();
496                     resultTask.Wait();
497                     _response_map.Remove(key);
498                 };
499
500                 CallBurstDtmfStruct callBurstStruct = CallClassConversions.ConvertCallBurstToStruct(dtmfData);
501                 int ret = Interop.Tapi.Call.SendBurstDtmfCall(_handle, ref callBurstStruct, _response_map[id], id);
502                 if (ret != (int)TapiError.Success)
503                 {
504                     Log.Error(TapiUtility.LogTag, "Failed to send dtmf digits during the call, Error: " + (TapiError)ret);
505                     TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
506                 }
507
508                 return task.Task;
509             }
510
511             else
512             {
513                 throw new ArgumentNullException("CallBurstDtmfData argument is null");
514             }
515         }
516
517         /// <summary>
518         /// Joins the given two calls (one call in the active conversation state and the other call in the held state) into conference asynchronously.
519         /// </summary>
520         /// <param name="activeCallhandle">Unique handle which is either an active call or a held call.</param>
521         /// <param name="callHandle">Unique call handle.</param>
522         /// <returns>The call id of join call.</returns>
523         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
524         /// <privlevel>platform</privlevel>
525         /// <feature>http://tizen.org/feature/network.telephony</feature>
526         /// <remarks>
527         /// For a multiparty call or for joining two calls into conference, there should be one call in the active state and another call in the held state.
528         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
529         /// </remarks>
530         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
531         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
532         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
533         public Task<uint> JoinCall(uint activeCallhandle, uint callHandle)
534         {
535             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
536             IntPtr id;
537             id = (IntPtr)_requestId++;
538             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
539             {
540                 Task resultTask = new Task(() =>
541                 {
542                     if (result != (int)TapiError.Success)
543                     {
544                         Log.Error(TapiUtility.LogTag, "Error occurs during joining the two calls, " + (TapiError)result);
545                         task.SetException(new InvalidOperationException("Error occurs during joining the two calls, " + (TapiError)result));
546                         return;
547                     }
548
549                     CallOperationsStruct joinStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
550                     task.SetResult(joinStruct.id);
551                 });
552
553                 resultTask.Start();
554                 resultTask.Wait();
555                 _response_map.Remove(key);
556             };
557
558             int ret = Interop.Tapi.Call.JoinCall(_handle, activeCallhandle, callHandle, _response_map[id], id);
559             if (ret != (int)TapiError.Success)
560             {
561                 Log.Error(TapiUtility.LogTag, "Failed to join the given two calls into conference, Error: " + (TapiError)ret);
562                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
563             }
564
565             return task.Task;
566         }
567
568         /// <summary>
569         /// Triggers splitting a private call from a multiparty call asynchronously.
570         /// </summary>
571         /// <param name="callHandle">The handle of the call to be made private. The call handle referring to the call that is to be split from the conference.</param>
572         /// <returns>The call id of split call.</returns>
573         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
574         /// <privlevel>platform</privlevel>
575         /// <feature>http://tizen.org/feature/network.telephony</feature>
576         /// <remarks>
577         /// The call should be in a multiparty conference call.The split call will be the active call and the conference call will be the held call.
578         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
579         /// </remarks>
580         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
581         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
582         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
583         public Task<uint> SplitCall(uint callHandle)
584         {
585             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
586             IntPtr id;
587             id = (IntPtr)_requestId++;
588             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
589             {
590                 Task resultTask = new Task(() =>
591                 {
592                     if (result != (int)TapiError.Success)
593                     {
594                         Log.Error(TapiUtility.LogTag, "Error occurs during splitting a private call from a multiparty call, " + (TapiError)result);
595                         task.SetException(new InvalidOperationException("Error occurs during splitting a private call from a multiparty call, " + (TapiError)result));
596                         return;
597                     }
598
599                     CallOperationsStruct splitStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
600                     task.SetResult(splitStruct.id);
601                 });
602
603                 resultTask.Start();
604                 resultTask.Wait();
605                 _response_map.Remove(key);
606             };
607
608             int ret = Interop.Tapi.Call.SplitCall(_handle, callHandle, _response_map[id], id);
609             if (ret != (int)TapiError.Success)
610             {
611                 Log.Error(TapiUtility.LogTag, "Failed to split a private call from a multiparty call, Error: " + (TapiError)ret);
612                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
613             }
614
615             return task.Task;
616         }
617
618         /// <summary>
619         /// Triggers making an explicit call transfer by connecting the two parties where one party is being active(active state) and another party is being held(held state) asynchronously.
620         /// </summary>
621         /// <param name="activeCallHandle">The call handle of an active call.</param>
622         /// <returns>The call id of transferred call.</returns>
623         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
624         /// <privlevel>platform</privlevel>
625         /// <feature>http://tizen.org/feature/network.telephony</feature>
626         /// <remarks>
627         /// In order to transfer call, served mobile subscriber should have 2 calls, one in the active state and another one in the held state.
628         /// Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.
629         /// </remarks>
630         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
631         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
632         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
633         public Task<uint> TransferCall(uint activeCallHandle)
634         {
635             TaskCompletionSource<uint> task = new TaskCompletionSource<uint>();
636             IntPtr id;
637             id = (IntPtr)_requestId++;
638             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
639             {
640                 Task resultTask = new Task(() =>
641                 {
642                     if (result != (int)TapiError.Success)
643                     {
644                         Log.Error(TapiUtility.LogTag, "Error occurs during transferring call, " + (TapiError)result);
645                         task.SetException(new InvalidOperationException("Error occurs during transferring call, " + (TapiError)result));
646                         return;
647                     }
648
649                     CallOperationsStruct splitStruct = Marshal.PtrToStructure<CallOperationsStruct>(data);
650                     task.SetResult(splitStruct.id);
651                 });
652
653                 resultTask.Start();
654                 resultTask.Wait();
655                 _response_map.Remove(key);
656             };
657
658             int ret = Interop.Tapi.Call.TransferCall(_handle, activeCallHandle, _response_map[id], id);
659             if (ret != (int)TapiError.Success)
660             {
661                 Log.Error(TapiUtility.LogTag, "Failed to make explicit call transfer by connecting two calls - active call and held call, Error: " + (TapiError)ret);
662                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
663             }
664
665             return task.Task;
666         }
667
668         /// <summary>
669         /// Redirects the incoming call to another subscriber asynchronously.
670         /// </summary>
671         /// <param name="incomingCallHandle">Incoming call handle.</param>
672         /// <param name="destinationNumber">The destination number.</param>
673         /// <returns>A task indicating whether the DeflectCall method is done or not.</returns>
674         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
675         /// <privlevel>platform</privlevel>
676         /// <feature>http://tizen.org/feature/network.telephony</feature>
677         /// <remarks>Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.</remarks>
678         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
679         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
680         /// <exception cref="System.ArgumentException">Thrown when destinationNumber argument is invalid.</exception>
681         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
682         public Task DeflectCall(uint incomingCallHandle, byte[] destinationNumber)
683         {
684             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
685             IntPtr id;
686             id = (IntPtr)_requestId++;
687             CallDeflectDestStruct deflectStruct = CallClassConversions.ConvertByteDestinationToStruct(destinationNumber);
688             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
689             {
690                 Task resultTask = new Task(() =>
691                 {
692                     if (result != (int)TapiError.Success)
693                     {
694                         Log.Error(TapiUtility.LogTag, "Error occurs during deflecting incoming call, " + (TapiError)result);
695                         task.SetException(new InvalidOperationException("Error occurs during deflecting incoming call, " + (TapiError)result));
696                         return;
697                     }
698
699                     task.SetResult(true);
700                 });
701
702                 resultTask.Start();
703                 resultTask.Wait();
704                 _response_map.Remove(key);
705                 Marshal.FreeHGlobal(deflectStruct.DestinationNumber);
706             };
707
708             int ret = Interop.Tapi.Call.DeflectCall(_handle, incomingCallHandle, ref deflectStruct, _response_map[id], id);
709             if (ret != (int)TapiError.Success)
710             {
711                 Log.Error(TapiUtility.LogTag, "Failed to redirect the incoming call to another subscriber, Error: " + (TapiError)ret);
712                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
713             }
714
715             return task.Task;
716         }
717
718         /// <summary>
719         /// Gets the status of the current call.
720         /// </summary>
721         /// <param name="callId">A unique handle for referring the call.</param>
722         /// <returns>The call status information like destination number, call direction, call type, whether call is in the conference state or not.</returns>
723         /// <privilege>http://tizen.org/privilege/telephony</privilege>
724         /// <feature>http://tizen.org/feature/network.telephony</feature>
725         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
726         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
727         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
728         public CallStatus GetCallStatus(int callId)
729         {
730             CallStatusStruct statusStruct;
731             int ret = Interop.Tapi.Call.GetCallStatus(_handle, callId, out statusStruct);
732             if (ret != (int)TapiError.Success)
733             {
734                 Log.Error(TapiUtility.LogTag, "Failed to get the status of the current call, Error: " + (TapiError)ret);
735                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony");
736             }
737
738             CallStatus statusData = CallStructConversions.ConvertStatusStruct(statusStruct);
739             return statusData;
740         }
741
742         /// <summary>
743         /// Get the list of status of the current call.
744         /// </summary>
745         /// <returns>List of CallStatus.</returns>
746         /// <privilege>http://tizen.org/privilege/telephony</privilege>
747         /// <feature>http://tizen.org/feature/network.telephony</feature>
748         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
749         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
750         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
751         public IEnumerable<CallStatus> GetAllCallStatus()
752         {
753             List<CallStatus> callStatusList = new List<CallStatus>();
754             _callStatusCb = (ref CallStatusStruct info, IntPtr userData) =>
755             {
756                 if (!info.Equals(null))
757                 {
758                     callStatusList.Add(CallStructConversions.ConvertStatusStruct(info));
759                 }
760             };
761
762             int ret = Interop.Tapi.Call.GetAllCallStatus(_handle, _callStatusCb, IntPtr.Zero);
763             if (ret != (int)TapiError.Success)
764             {
765                 Log.Error(TapiUtility.LogTag, "Failed to get all status of the current call, Error: " + (TapiError)ret);
766                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony");
767             }
768
769             return callStatusList;
770         }
771
772         /// <summary>
773         /// Get the call volume asynchronously.
774         /// </summary>
775         /// <param name="device">The sound device.</param>
776         /// <param name="type">The sound type.</param>
777         /// <returns>Instance of CallVolumeInfo.</returns>
778         /// <privilege>http://tizen.org/privilege/telephony</privilege>
779         /// <feature>http://tizen.org/feature/network.telephony</feature>
780         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
781         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
782         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
783         public Task<CallVolumeInfo> GetCallVolumeInfo(SoundDevice device, SoundType type)
784         {
785             TaskCompletionSource<CallVolumeInfo> task = new TaskCompletionSource<CallVolumeInfo>();
786             IntPtr id;
787             id = (IntPtr)_requestId++;
788             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
789             {
790                 Task resultTask = new Task(() =>
791                 {
792                     if (result != (int)TapiError.Success)
793                     {
794                         Log.Error(TapiUtility.LogTag, "Error occurs during getting the call volume, " + (TapiError)result);
795                         task.SetException(new InvalidOperationException("Error occurs during getting the call volume, " + (TapiError)result));
796                         return;
797                     }
798
799                     CallVolumeStruct volumeStruct = Marshal.PtrToStructure<CallVolumeStruct>(data);
800                     CallVolumeInfo volumeInfo = CallStructConversions.ConvertVolumeStruct(volumeStruct);
801                     task.SetResult(volumeInfo);
802                 });
803
804                 resultTask.Start();
805                 resultTask.Wait();
806                 _response_map.Remove(key);
807             };
808
809             int ret = Interop.Tapi.Call.GetCallVolumeInfo(_handle, device, type, _response_map[id], id);
810             if (ret != (int)TapiError.Success)
811             {
812                 Log.Error(TapiUtility.LogTag, "Failed to get the call volume, Error: " + (TapiError)ret);
813                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony");
814             }
815
816             return task.Task;
817         }
818
819         /// <summary>
820         /// Set the call volume asynchronously.
821         /// </summary>
822         /// <param name="record">The call volume information.</param>
823         /// <returns>A task indicating whether the SetCallVolumeInfo method is done or not.</returns>
824         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
825         /// <privlevel>platform</privlevel>
826         /// <feature>http://tizen.org/feature/network.telephony</feature>
827         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
828         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
829         /// <exception cref="System.ArgumentNullException">Thrown when CallVolumeRecord argument is null.</exception>
830         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
831         public Task SetCallVolumeInfo(CallVolumeRecord record)
832         {
833             if (record != null)
834             {
835                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
836                 IntPtr id;
837                 id = (IntPtr)_requestId++;
838                 _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
839                 {
840                     Task resultTask = new Task(() =>
841                     {
842                         if (result != (int)TapiError.Success)
843                         {
844                             Log.Error(TapiUtility.LogTag, "Error occurs during setting the call volume, " + (TapiError)result);
845                             task.SetException(new InvalidOperationException("Error occurs during setting the call volume, " + (TapiError)result));
846                             return;
847                         }
848
849                         task.SetResult(true);
850                     });
851
852                     resultTask.Start();
853                     resultTask.Wait();
854                     _response_map.Remove(key);
855                 };
856
857                 CallVolumeRecordStruct volumeStruct = CallClassConversions.ConvertVolumeRecordToStruct(record);
858                 int ret = Interop.Tapi.Call.SetCallVolumeInfo(_handle, ref volumeStruct, _response_map[id], id);
859                 if (ret != (int)TapiError.Success)
860                 {
861                     Log.Error(TapiUtility.LogTag, "Failed to set the call volume, Error: " + (TapiError)ret);
862                     TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
863                 }
864
865                 return task.Task;
866             }
867
868             else
869             {
870                 throw new ArgumentNullException("CallVolumeRecord argument is null");
871             }
872         }
873
874         /// <summary>
875         /// Set the call sound path asynchronously.
876         /// </summary>
877         /// <param name="path">The call sound path information.</param>
878         /// <returns>A task indicating whether the SetCallSoundPath method is done or not.</returns>
879         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
880         /// <privlevel>platform</privlevel>
881         /// <feature>http://tizen.org/feature/network.telephony</feature>
882         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
883         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
884         /// <exception cref="System.ArgumentNullException">Thrown when CallSoundPathInfo argument is null.</exception>
885         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
886         public Task SetCallSoundPath(CallSoundPathInfo path)
887         {
888             if (path != null)
889             {
890                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
891                 IntPtr id;
892                 id = (IntPtr)_requestId++;
893                 _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
894                 {
895                     Task resultTask = new Task(() =>
896                     {
897                         if (result != (int)TapiError.Success)
898                         {
899                             Log.Error(TapiUtility.LogTag, "Error occurs during setting the call sound path, " + (TapiError)result);
900                             task.SetException(new InvalidOperationException("Error occurs during setting the call sound path, " + (TapiError)result));
901                             return;
902                         }
903
904                         task.SetResult(true);
905                     });
906
907                     resultTask.Start();
908                     resultTask.Wait();
909                     _response_map.Remove(key);
910                 };
911
912                 CallSoundPathStruct pathStruct = CallClassConversions.ConvertSoundPathToStruct(path);
913                 int ret = Interop.Tapi.Call.SetCallSoundPath(_handle, ref pathStruct, _response_map[id], id);
914                 if (ret != (int)TapiError.Success)
915                 {
916                     Log.Error(TapiUtility.LogTag, "Failed to set the call sound path, Error: " + (TapiError)ret);
917                     TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
918                 }
919
920                 return task.Task;
921             }
922
923             else
924             {
925                 throw new ArgumentNullException("CallSoundPathInfo argument is null");
926             }
927         }
928
929         /// <summary>
930         /// Set the call mute state asynchronously.
931         /// </summary>
932         /// <param name="record">The call mute status information.</param>
933         /// <returns>A task indicating whether the SetCallMuteStatus method is done or not.</returns>
934         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
935         /// <privlevel>platform</privlevel>
936         /// <feature>http://tizen.org/feature/network.telephony</feature>
937         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
938         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
939         /// <exception cref="System.ArgumentNullException">Thrown when CallMuteStatusRecord argument is null.</exception>
940         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
941         public Task SetCallMuteStatus(CallMuteStatusRecord record)
942         {
943             if (record != null)
944             {
945                 TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
946                 IntPtr id;
947                 id = (IntPtr)_requestId++;
948                 _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
949                 {
950                     Task resultTask = new Task(() =>
951                     {
952                         if (result != (int)TapiError.Success)
953                         {
954                             Log.Error(TapiUtility.LogTag, "Error occurs during setting the call mute state, " + (TapiError)result);
955                             task.SetException(new InvalidOperationException("Error occurs during setting the call mute state, " + (TapiError)result));
956                             return;
957                         }
958
959                         task.SetResult(true);
960                     });
961
962                     resultTask.Start();
963                     resultTask.Wait();
964                     _response_map.Remove(key);
965                 };
966
967                 int ret = Interop.Tapi.Call.SetCallMuteStatus(_handle, record.Status, record.Path, _response_map[id], id);
968                 if (ret != (int)TapiError.Success)
969                 {
970                     Log.Error(TapiUtility.LogTag, "Failed to set the call mute state, Error: " + (TapiError)ret);
971                     TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
972                 }
973
974                 return task.Task;
975             }
976
977             else
978             {
979                 throw new ArgumentNullException("CallMuteStatusRecord argument is null");
980             }
981         }
982
983         /// <summary>
984         /// Get the call mute state asynchronously.
985         /// </summary>
986         /// <returns>Instance of CallMuteStatusRecord.</returns>
987         /// <privilege>http://tizen.org/privilege/telephony</privilege>
988         /// <feature>http://tizen.org/feature/network.telephony</feature>
989         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
990         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
991         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
992         public Task<CallMuteStatusRecord> GetCallMuteStatus()
993         {
994             TaskCompletionSource<CallMuteStatusRecord> task = new TaskCompletionSource<CallMuteStatusRecord>();
995             IntPtr id;
996             id = (IntPtr)_requestId++;
997             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
998             {
999                 Task resultTask = new Task(() =>
1000                 {
1001                     if (result != (int)TapiError.Success)
1002                     {
1003                         Log.Error(TapiUtility.LogTag, "Error occurs during getting the call mute state, " + (TapiError)result);
1004                         task.SetException(new InvalidOperationException("Error occurs during getting the call mute state, " + (TapiError)result));
1005                         return;
1006                     }
1007
1008                     CallMuteStatusStruct muteStruct = Marshal.PtrToStructure<CallMuteStatusStruct>(data);
1009                     CallMuteStatusRecord muteStatusRecord = new CallMuteStatusRecord(muteStruct.Path, muteStruct.Status);
1010                     task.SetResult(muteStatusRecord);
1011                 });
1012
1013                 resultTask.Start();
1014                 resultTask.Wait();
1015                 _response_map.Remove(key);
1016             };
1017
1018             int ret = Interop.Tapi.Call.GetCallMuteStatus(_handle, _response_map[id], id);
1019             if (ret != (int)TapiError.Success)
1020             {
1021                 Log.Error(TapiUtility.LogTag, "Failed to get the call mute state, Error: " + (TapiError)ret);
1022                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony");
1023             }
1024
1025             return task.Task;
1026         }
1027
1028         /// <summary>
1029         /// Get the voice privacy mode in the phone asynchronously.
1030         /// </summary>
1031         /// <returns>CallPrivacyMode value.</returns>
1032         /// <privilege>http://tizen.org/privilege/telephony</privilege>
1033         /// <feature>http://tizen.org/feature/network.telephony</feature>
1034         /// <remarks>Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.</remarks>
1035         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
1036         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1037         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
1038         public Task<CallPrivacyMode> GetCallPrivacyMode()
1039         {
1040             TaskCompletionSource<CallPrivacyMode> task = new TaskCompletionSource<CallPrivacyMode>();
1041             IntPtr id;
1042             id = (IntPtr)_requestId++;
1043             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
1044             {
1045                 Task resultTask = new Task(() =>
1046                 {
1047                     if (result != (int)TapiError.Success)
1048                     {
1049                         Log.Error(TapiUtility.LogTag, "Error occurs during getting the voice privacy mode, " + (TapiError)result);
1050                         task.SetException(new InvalidOperationException("Error occurs during getting the voice privacy mode, " + (TapiError)result));
1051                         return;
1052                     }
1053
1054                     CallPrivacyModeStruct privacyStruct = Marshal.PtrToStructure<CallPrivacyModeStruct>(data);
1055                     CallPrivacyMode mode = privacyStruct.Mode;
1056                     task.SetResult(mode);
1057                 });
1058
1059                 resultTask.Start();
1060                 resultTask.Wait();
1061                 _response_map.Remove(key);
1062             };
1063
1064             int ret = Interop.Tapi.Call.GetCallMuteStatus(_handle, _response_map[id], id);
1065             if (ret != (int)TapiError.Success)
1066             {
1067                 Log.Error(TapiUtility.LogTag, "Failed to get the voice privacy mode in the phone, Error: " + (TapiError)ret);
1068                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony");
1069             }
1070
1071             return task.Task;
1072         }
1073
1074         /// <summary>
1075         /// Set the voice privacy mode in the phone asynchronously. It is available only where a call exists.
1076         /// </summary>
1077         /// <param name="mode">Voice privacy option mode value.</param>
1078         /// <returns>A task indicating whether the SetCallPrivacyMode method is done or not.</returns>
1079         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
1080         /// <privlevel>platform</privlevel>
1081         /// <feature>http://tizen.org/feature/network.telephony</feature>
1082         /// <remarks>Register the telephony event with proper Notification enum value which is to be listened using RegisterNotiEvent.</remarks>
1083         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
1084         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1085         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
1086         public Task SetCallPrivacyMode(CallPrivacyMode mode)
1087         {
1088             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
1089             IntPtr id;
1090             id = (IntPtr)_requestId++;
1091             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
1092             {
1093                 Task resultTask = new Task(() =>
1094                 {
1095                     if (result != (int)TapiError.Success)
1096                     {
1097                         Log.Error(TapiUtility.LogTag, "Error occurs during setting the voice privacy mode, " + (TapiError)result);
1098                         task.SetException(new InvalidOperationException("Error occurs during setting the voice privacy mode, " + (TapiError)result));
1099                         return;
1100                     }
1101
1102                     task.SetResult(true);
1103                 });
1104
1105                 resultTask.Start();
1106                 resultTask.Wait();
1107                 _response_map.Remove(key);
1108             };
1109
1110             int ret = Interop.Tapi.Call.SetCallPrivacyMode(_handle, mode, _response_map[id], id);
1111             if (ret != (int)TapiError.Success)
1112             {
1113                 Log.Error(TapiUtility.LogTag, "Failed to set the voice privacy mode, Error: " + (TapiError)ret);
1114                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
1115             }
1116
1117             return task.Task;
1118         }
1119
1120         /// <summary>
1121         /// Set the preferred voice subscription asynchronously.
1122         /// </summary>
1123         /// <param name="subscription">Preferred voice subscription value.</param>
1124         /// <returns>A task indicating whether the SetCallPreferredVoiceSubscription method is done or not.</returns>
1125         /// <privilege>http://tizen.org/privilege/telephony.admin</privilege>
1126         /// <privlevel>platform</privlevel>
1127         /// <feature>http://tizen.org/feature/network.telephony</feature>
1128         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
1129         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1130         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
1131         public Task SetCallPreferredVoiceSubscription(CallPreferredVoiceSubscription subscription)
1132         {
1133             TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
1134             IntPtr id;
1135             id = (IntPtr)_requestId++;
1136             _response_map[id] = (IntPtr handle, int result, IntPtr data, IntPtr key) =>
1137             {
1138                 Task resultTask = new Task(() =>
1139                 {
1140                     if (result != (int)TapiError.Success)
1141                     {
1142                         Log.Error(TapiUtility.LogTag, "Error occurs during setting preferred voice subscription, " + (TapiError)result);
1143                         task.SetException(new InvalidOperationException("Error occurs during setting preferred voice subscription, " + (TapiError)result));
1144                         return;
1145                     }
1146
1147                     task.SetResult(true);
1148                 });
1149
1150                 resultTask.Start();
1151                 resultTask.Wait();
1152                 _response_map.Remove(key);
1153             };
1154
1155             int ret = Interop.Tapi.Call.SetCallPreferredVoiceSubs(_handle, subscription, _response_map[id], id);
1156             if (ret != (int)TapiError.Success)
1157             {
1158                 Log.Error(TapiUtility.LogTag, "Failed to set preferred voice subscription, Error: " + (TapiError)ret);
1159                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony.admin");
1160             }
1161
1162             return task.Task;
1163         }
1164
1165         /// <summary>
1166         /// Get the preferred voice subscription.
1167         /// </summary>
1168         /// <returns>CallPreferredVoiceSubscription value.</returns>
1169         /// <privilege>http://tizen.org/privilege/telephony</privilege>
1170         /// <feature>http://tizen.org/feature/network.telephony</feature>
1171         /// <exception cref="System.NotSupportedException">Thrown when feature is not supported.</exception>
1172         /// <exception cref="System.UnauthorizedAccessException">Thrown when privilege access is denied.</exception>
1173         /// <exception cref="System.InvalidOperationException">Thrown when call instance is invalid or when method failed due to invalid operation.</exception>
1174         public CallPreferredVoiceSubscription GetCallPreferredVoiceSubscription()
1175         {
1176             CallPreferredVoiceSubscription subscription;
1177             int ret = Interop.Tapi.Call.GetCallPreferredVoiceSubs(_handle, out subscription);
1178             if (ret != (int)TapiError.Success)
1179             {
1180                 Log.Error(TapiUtility.LogTag, "Failed to get preferred voice subscription, Error: " + (TapiError)ret);
1181                 TapiUtility.ThrowTapiException(ret, _handle, "http://tizen.org/privilege/telephony");
1182             }
1183
1184             return subscription;
1185         }
1186     }
1187 }