[Stt] Fix lock issue (#127)
[platform/core/csapi/tizenfx.git] / src / Tizen.Uix.Stt / Tizen.Uix.Stt / SttClient.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
18 using System;
19 using System.Collections.Generic;
20 using System.Runtime.InteropServices;
21 using static Interop.Stt;
22
23 namespace Tizen.Uix.Stt
24 {
25     /// <summary>
26     /// The token event.
27     /// </summary>
28     /// <since_tizen> 3 </since_tizen>
29     public enum ResultEvent
30     {
31         /// <summary>
32         /// Event when the recognition for full or last result is ready.
33         /// </summary>
34         /// <since_tizen> 3 </since_tizen>
35         FinalResult = 0,
36         /// <summary>
37         /// Event when the recognition for partial result is ready.
38         /// </summary>
39         /// <since_tizen> 3 </since_tizen>
40         PartialResult,
41         /// <summary>
42         /// Event when the recognition has failed.
43         /// </summary>
44         /// <since_tizen> 3 </since_tizen>
45         Error
46     };
47
48     /// <summary>
49     /// Enumeration for representing the result message.
50     /// </summary>
51     /// <since_tizen> 3 </since_tizen>
52     public enum ResultMessage
53     {
54         /// <summary>
55         /// No Error.
56         /// </summary>
57         /// <since_tizen> 3 </since_tizen>
58         None,
59         /// <summary>
60         /// Recognition failed  because the speech started too soon.
61         /// </summary>
62         /// <since_tizen> 3 </since_tizen>
63         TooSoon,
64         /// <summary>
65         /// Recognition failed  because the speech is too short.
66         /// </summary>
67         /// <since_tizen> 3 </since_tizen>
68         TooShort,
69         /// <summary>
70         /// Recognition failed  because the speech is too long.
71         /// </summary>
72         /// <since_tizen> 3 </since_tizen>
73         TooLong,
74         /// <summary>
75         /// Recognition failed  because the speech is too quiet to listen.
76         /// </summary>
77         /// <since_tizen> 3 </since_tizen>
78         TooQuiet,
79         /// <summary>
80         /// Recognition failed  because the speech is too loud to listen.
81         /// </summary>
82         /// <since_tizen> 3 </since_tizen>
83         TooLoud,
84         /// <summary>
85         /// Recognition failed  because the speech is too fast to listen.
86         /// </summary>
87         /// <since_tizen> 3 </since_tizen>
88         TooFast
89     };
90
91     /// <summary>
92     /// Enumeration for the token types.
93     /// </summary>
94     /// <since_tizen> 3 </since_tizen>
95     public enum TimeEvent
96     {
97         /// <summary>
98         /// Event when the token is beginning type.
99         /// </summary>
100         /// <since_tizen> 3 </since_tizen>
101         Beginning = 0,
102         /// <summary>
103         /// Event when the token is middle type.
104         /// </summary>
105         /// <since_tizen> 3 </since_tizen>
106         Middle = 1,
107         /// <summary>
108         /// Event when the token is end type.
109         /// </summary>
110         /// <since_tizen> 3 </since_tizen>
111         End = 2
112     };
113
114     /// <summary>
115     /// Enumeration for the error values that can occur.
116     /// </summary>
117     /// <since_tizen> 3 </since_tizen>
118     public enum Error
119     {
120         /// <summary>
121         /// Successful, No error.
122         /// </summary>
123         /// <since_tizen> 3 </since_tizen>
124         None,
125         /// <summary>
126         /// Out of Memory.
127         /// </summary>
128         /// <since_tizen> 3 </since_tizen>.
129         OutOfMemory,
130         /// <summary>
131         /// I/O error.
132         /// </summary>
133         /// <since_tizen> 3 </since_tizen>.
134         IoError,
135         /// <summary>
136         /// Invalid parameter.
137         /// </summary>
138         /// <since_tizen> 3 </since_tizen>
139         InvalidParameter,
140         /// <summary>
141         /// No answer from the STT service.
142         /// </summary>
143         /// <since_tizen> 3 </since_tizen>
144         TimedOut,
145         /// <summary>
146         /// Device or resource busy.
147         /// </summary>
148         /// <since_tizen> 3 </since_tizen>
149         RecorderBusy,
150         /// <summary>
151         /// Network is down.
152         /// </summary>
153         /// <since_tizen> 3 </since_tizen>
154         OutOfNetwork,
155         /// <summary>
156         /// Permission denied.
157         /// </summary>
158         /// <since_tizen> 3 </since_tizen>
159         PermissionDenied,
160         /// <summary>
161         /// STT NOT supported.
162         /// </summary>
163         /// <since_tizen> 3 </since_tizen>
164         NotSupported,
165         /// <summary>
166         /// Invalid state.
167         /// </summary>
168         /// <since_tizen> 3 </since_tizen>
169         InvalidState,
170         /// <summary>
171         /// Invalid language.
172         /// </summary>
173         /// <since_tizen> 3 </since_tizen>
174         InvalidLanguage,
175         /// <summary>
176         /// No available engine.
177         /// </summary>
178         /// <since_tizen> 3 </since_tizen>
179         EngineNotFound,
180         /// <summary>
181         /// Operation failed.
182         /// </summary>
183         /// <since_tizen> 3 </since_tizen>
184         OperationFailed,
185         /// <summary>
186         /// Not supported feature of current engine.
187         /// </summary>
188         /// <since_tizen> 3 </since_tizen>
189         NotSupportedFeature,
190         /// <summary>
191         /// Recording timed out.
192         /// </summary>
193         /// <since_tizen> 3 </since_tizen>
194         RecordingTimedOut,
195         /// <summary>
196         /// No speech while recording.
197         /// </summary>
198         /// <since_tizen> 3 </since_tizen>
199         NoSpeech,
200         /// <summary>
201         /// Progress to ready is not finished.
202         /// </summary>
203         /// <since_tizen> 3 </since_tizen>
204         InProgressToReady,
205         /// <summary>
206         /// Progress to recording is not finished.
207         /// </summary>
208         /// <since_tizen> 3 </since_tizen>
209         InProgressToRecording,
210         /// <summary>
211         /// Progress to processing is not finished.
212         /// </summary>
213         /// <since_tizen> 3 </since_tizen>
214         InProgressToProcessing,
215         /// <summary>
216         /// Service reset.
217         /// </summary>
218         /// <since_tizen> 3 </since_tizen>
219         ServiceReset
220     };
221
222     /// <summary>
223     /// Enumeration for the recognition types.
224     /// </summary>
225     /// <since_tizen> 3 </since_tizen>
226     public enum RecognitionType
227     {
228         /// <summary>
229         /// Free form dictation.
230         /// </summary>
231         /// <since_tizen> 3 </since_tizen>
232         Free,
233         /// <summary>
234         /// Continuous free dictation.
235         /// </summary>
236         /// <since_tizen> 3 </since_tizen>
237         Partial,
238         /// <summary>
239         /// Search.
240         /// </summary>
241         /// <since_tizen> 3 </since_tizen>
242         Search,
243         /// <summary>
244         /// Web search.
245         /// </summary>
246         /// <since_tizen> 3 </since_tizen>
247         WebSearch,
248         /// <summary>
249         /// Map.
250         /// </summary>
251         /// <since_tizen> 3 </since_tizen>
252         Map
253     };
254
255     /// <summary>
256     /// Enumeration for the state types.
257     /// </summary>
258     /// <since_tizen> 3 </since_tizen>
259     public enum State
260     {
261         /// <summary>
262         /// Created state.
263         /// </summary>
264         /// <since_tizen> 3 </since_tizen>
265         Created = 0,
266         /// <summary>
267         /// Ready state.
268         /// </summary>
269         /// <since_tizen> 3 </since_tizen>
270         Ready = 1,
271         /// <summary>
272         /// Recording state.
273         /// </summary>
274         /// <since_tizen> 3 </since_tizen>
275         Recording = 2,
276         /// <summary>
277         /// Processing state.
278         /// </summary>
279         /// <since_tizen> 3 </since_tizen>
280         Processing = 3,
281         /// <summary>
282         /// Unavailable.
283         /// </summary>
284         /// <since_tizen> 3 </since_tizen>
285         Unavailable
286     };
287
288     /// <summary>
289     /// Enumeration for the silence detection types.
290     /// </summary>
291     /// <since_tizen> 3 </since_tizen>
292     public enum SilenceDetection
293     {
294         /// <summary>
295         /// Silence detection type - False.
296         /// </summary>
297         /// <since_tizen> 3 </since_tizen>
298         False = 0,
299         /// <summary>
300         /// Silence detection type - True.
301         /// </summary>
302         /// <since_tizen> 3 </since_tizen>
303         True = 1,
304         /// <summary>
305         /// Silence detection type - Auto.
306         /// </summary>
307         /// <since_tizen> 3 </since_tizen>
308         Auto = 2
309     };
310
311     /// <summary>
312     /// A main function of Speech-To-Text (below STT) API recognizes sound data recorded by users.
313     /// After choosing a language, the applications will start recording and recognizing.
314     /// After recording, the applications will receive the recognized result.
315     /// The STT has a client-server for the service of multi-applications.
316     /// The STT service always works in the background as a server. If the service is not working, client library will invoke it and the client will communicate with it.
317     /// The service has engines and a recorder, so that the client does not have the recorder itself. Only the client request commands to the STT service for using STT.
318     /// </summary>
319     /// <since_tizen> 3 </since_tizen>
320     public class SttClient : IDisposable
321     {
322         private IntPtr _handle;
323         private Object thisLock = new Object();
324         private event EventHandler<RecognitionResultEventArgs> _recognitionResult;
325         private event EventHandler<StateChangedEventArgs> _stateChanged;
326         private event EventHandler<ErrorOccurredEventArgs> _errorOccurred;
327         private event EventHandler<DefaultLanguageChangedEventArgs> _defaultLanguageChanged;
328         private event EventHandler<EngineChangedEventArgs> _engineChanged;
329         private bool disposedValue = false;
330         private Interop.Stt.RecognitionResultCallback _resultDelegate;
331         private Interop.Stt.StateChangedCallback _stateDelegate;
332         private Interop.Stt.ErrorCallback _errorDelegate;
333         private Interop.Stt.DefaultLanguageChangedCallback _languageDelegate;
334         private Interop.Stt.EngineChangedCallback _engineDelegate;
335         private ResultTime _result;
336         private ResultTimeCallback _resultTimeDelegate;
337
338         /// <summary>
339         /// Constructor to create a STT instance.
340         /// </summary>
341         /// <since_tizen> 3 </since_tizen>
342         /// <privilege>
343         /// http://tizen.org/privilege/recorder
344         /// </privilege>
345         /// <feature>
346         /// http://tizen.org/feature/speech.recognition
347         /// http://tizen.org/feature/microphone
348         /// </feature>
349         /// <exception cref="InvalidOperationException">This exception can be due to operation failed.</exception>
350         /// <exception cref="OutOfMemoryException">This exception can be due to out of memory.</exception>
351         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
352         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
353         public SttClient()
354         {
355             IntPtr handle;
356             SttError error = SttCreate(out handle);
357             if (error != SttError.None)
358             {
359                 Log.Error(LogTag, "Create Failed with error " + error);
360                 throw ExceptionFactory.CreateException(error);
361             }
362
363             _handle = handle;
364         }
365
366         /// <summary>
367         /// Event to be invoked when the recognition is done.
368         /// </summary>
369         /// <since_tizen> 3 </since_tizen>
370         public event EventHandler<RecognitionResultEventArgs> RecognitionResult
371         {
372             add
373             {
374                 lock (thisLock)
375                 {
376                     _resultDelegate = (IntPtr handle, ResultEvent e, IntPtr data, int dataCount, IntPtr msg, IntPtr userData) =>
377                     {
378                         Log.Info(LogTag, "Recognition Result Event Triggered");
379                         if (data != null && msg != null)
380                         {
381                             RecognitionResultEventArgs args = new RecognitionResultEventArgs(e, data, dataCount, Marshal.PtrToStringAnsi(msg));
382                             _recognitionResult?.Invoke(this, args);
383                         }
384                         else
385                         {
386                             Log.Info(LogTag, "Recognition Result Event null received");
387                         }
388                     };
389                     SttError error = SttSetRecognitionResultCB(_handle, _resultDelegate, IntPtr.Zero);
390                     if (error != SttError.None)
391                     {
392                         Log.Error(LogTag, "Add RecognitionResult Failed with error " + error);
393                     }
394                     else
395                     {
396                         _recognitionResult += value;
397                     }
398                 }
399             }
400
401             remove
402             {
403                 lock (thisLock)
404                 {
405                     SttError error = SttUnsetRecognitionResultCB(_handle);
406                     if (error != SttError.None)
407                     {
408                         Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error);
409                     }
410
411                     _recognitionResult -= value;
412                 }
413             }
414         }
415
416         /// <summary>
417         /// Event to be invoked when the STT state changes.
418         /// </summary>
419         /// <since_tizen> 3 </since_tizen>
420         public event EventHandler<StateChangedEventArgs> StateChanged
421         {
422             add
423             {
424                 lock (thisLock)
425                 {
426                     SttClient obj = this;
427                     _stateDelegate = (IntPtr handle, State previous, State current, IntPtr userData) =>
428                     {
429                         StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
430                         _stateChanged?.Invoke(obj, args);
431                     };
432                     SttError error = SttSetStateChangedCB(_handle, _stateDelegate, IntPtr.Zero);
433                     if (error != SttError.None)
434                     {
435                         Log.Error(LogTag, "Add StateChanged Failed with error " + error);
436                     }
437                     else
438                     {
439                         _stateChanged += value;
440                     }
441                 }
442             }
443
444             remove
445             {
446                 lock (thisLock)
447                 {
448                     SttError error = SttUnsetStateChangedCB(_handle);
449                     if (error != SttError.None)
450                     {
451                         Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
452                     }
453
454                     _stateChanged -= value;
455                 }
456             }
457
458         }
459
460         /// <summary>
461         /// Event to be invoked when an error occurs.
462         /// </summary>
463         /// <since_tizen> 4 </since_tizen>
464         public event EventHandler<ErrorOccurredEventArgs> ErrorOccurred
465         {
466             add
467             {
468                 lock (thisLock)
469                 {
470                     _errorDelegate = (IntPtr handle, SttError reason, IntPtr userData) =>
471                     {
472                         ErrorOccurredEventArgs args = new ErrorOccurredEventArgs(handle, reason);
473                         _errorOccurred?.Invoke(this, args);
474                     };
475                     SttError error = SttSetErrorCB(_handle, _errorDelegate, IntPtr.Zero);
476                     if (error != SttError.None)
477                     {
478                         Log.Error(LogTag, "Add ErrorOccurred Failed with error " + error);
479                     }
480
481                     else
482                     {
483                         _errorOccurred += value;
484                     }
485                 }
486             }
487
488             remove
489             {
490                 lock (thisLock)
491                 {
492                     SttError error = SttUnsetErrorCB(_handle);
493                     if (error != SttError.None)
494                     {
495                         Log.Error(LogTag, "Remove ErrorOccurred Failed with error " + error);
496                     }
497
498                     _errorOccurred -= value;
499                 }
500             }
501         }
502
503         /// <summary>
504         /// Event to be invoked when the default language changes.
505         /// </summary>
506         /// <since_tizen> 3 </since_tizen>
507         public event EventHandler<DefaultLanguageChangedEventArgs> DefaultLanguageChanged
508         {
509             add
510             {
511                 lock (thisLock)
512                 {
513                     _languageDelegate = (IntPtr handle, IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) =>
514                     {
515                         string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
516                         string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
517                         DefaultLanguageChangedEventArgs args = new DefaultLanguageChangedEventArgs(previousLanguageString, currentLanguageString);
518                         _defaultLanguageChanged?.Invoke(this, args);
519                     };
520                     SttError error = SttSetDefaultLanguageChangedCB(_handle, _languageDelegate, IntPtr.Zero);
521                     if (error != SttError.None)
522                     {
523                         Log.Error(LogTag, "Add DefaultLanguageChanged Failed with error " + error);
524                     }
525
526                     else
527                     {
528                         _defaultLanguageChanged += value;
529                     }
530                 }
531             }
532
533             remove
534             {
535                 lock (thisLock)
536                 {
537                     SttError error = SttUnsetDefaultLanguageChangedCB(_handle);
538                     if (error != SttError.None)
539                     {
540                         Log.Error(LogTag, "Remove DefaultLanguageChanged Failed with error " + error);
541                     }
542
543                     _defaultLanguageChanged -= value;
544                 }
545             }
546
547         }
548
549         /// <summary>
550         /// Event to be invoked to detect the engine change.
551         /// </summary>
552         /// <since_tizen> 3 </since_tizen>
553         public event EventHandler<EngineChangedEventArgs> EngineChanged
554         {
555             add
556             {
557                 lock (thisLock)
558                 {
559                     _engineDelegate = (IntPtr handle, IntPtr engineId, IntPtr language, bool supportSilence, bool needCredential, IntPtr userData) =>
560                     {
561                         string engineIdString = Marshal.PtrToStringAnsi(engineId);
562                         string languageString = Marshal.PtrToStringAnsi(language);
563                         EngineChangedEventArgs args = new EngineChangedEventArgs(engineIdString, languageString, supportSilence, needCredential);
564                         _engineChanged?.Invoke(this, args);
565                     };
566                     SttError error = SttSetEngineChangedCB(_handle, _engineDelegate, IntPtr.Zero);
567                     if (error != SttError.None)
568                     {
569                         Log.Error(LogTag, "Add EngineChanged Failed with error " + error);
570                     }
571                     else
572                     {
573                         _engineChanged += value;
574                     }
575                 }
576             }
577
578             remove
579             {
580                 lock (thisLock)
581                 {
582                     SttError error = SttUnsetEngineChangedCB(_handle);
583                     if (error != SttError.None)
584                     {
585                         Log.Error(LogTag, "Remove EngineChanged Failed with error " + error);
586                     }
587
588                     _engineChanged -= value;
589                 }
590             }
591         }
592
593         /// <summary>
594         /// Gets the default language set by the user.
595         /// The language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
596         /// For example, "ko_KR" for Korean, "en_US" for American English.
597         /// </summary>
598         /// <since_tizen> 3 </since_tizen>
599         /// <value>
600         /// Default language in STT.
601         /// </value>
602         /// <privilege>
603         /// http://tizen.org/privilege/recorder
604         /// </privilege>
605         /// <returns>
606         /// Default Language string value.
607         /// </returns>
608         public string DefaultLanguage
609         {
610             get
611             {
612                 string language;
613                 lock (thisLock)
614                 {
615                     SttError error = SttGetDefaultLanguage(_handle, out language);
616                     if (error != SttError.None)
617                     {
618                         Log.Error(LogTag, "DefaultLanguage Failed with error " + error);
619                         return "";
620                     }
621                 }
622
623                 return language;
624             }
625         }
626
627         /// <summary>
628         /// Gets the microphone volume during recording.
629         /// </summary>
630         /// <since_tizen> 3 </since_tizen>
631         /// <value>
632         /// Recording volume in STT.
633         /// </value>
634         /// <privilege>
635         /// http://tizen.org/privilege/recorder
636         /// </privilege>
637         /// <pre>
638         /// The state must be recording.
639         /// </pre>
640         public float RecordingVolume
641         {
642             get
643             {
644                 float volume;
645                 lock (thisLock)
646                 {
647                     SttError error = SttGetRecordingVolume(_handle, out volume);
648                     if (error != SttError.None)
649                     {
650                         Log.Error(LogTag, "GetRecordingVolume Failed with error " + error);
651                         return 0.0f;
652                     }
653                 }
654
655                 return volume;
656             }
657
658         }
659
660         /// <summary>
661         /// Gets the current STT state.
662         /// </summary>
663         /// <since_tizen> 3 </since_tizen>
664         /// <value>
665         /// Current state of STT.
666         /// </value>
667         /// <privilege>
668         /// http://tizen.org/privilege/recorder
669         /// </privilege>
670         /// <returns>
671         /// Current STT state value.
672         /// </returns>
673         public State CurrentState
674         {
675             get
676             {
677                 State state;
678                 lock (thisLock)
679                 {
680                     SttError error = SttGetState(_handle, out state);
681                     if (error != SttError.None)
682                     {
683                         Log.Error(LogTag, "GetState Failed with error " + error);
684                         return State.Unavailable;
685                     }
686                 }
687
688                 return state;
689             }
690
691         }
692
693         /// <summary>
694         /// This property can be used to get and set the current engine id.
695         /// </summary>
696         /// <since_tizen> 3 </since_tizen>
697         /// <value>
698         /// Current STT engine id.
699         /// </value>
700         /// <privilege>
701         /// http://tizen.org/privilege/recorder
702         /// </privilege>
703         /// <exception cref="InvalidOperationException">
704         /// This exceptioncan occur while setting due to the following reasons:
705         /// 1. Operation Failed
706         /// 2. Invalid State
707         /// </exception>
708         /// <exception cref="OutOfMemoryException">This exception can be due to out of memory.</exception>
709         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
710         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
711         /// <exception cref="ArgumentException">This can happen if improper EngineId is provided while setting the value.</exception>
712         /// <pre>
713         /// The state must be created.
714         /// </pre>
715         public string Engine
716         {
717             get
718             {
719                 string engineId;
720                 lock (thisLock)
721                 {
722                     SttError error = SttGetEngine(_handle, out engineId);
723                     if (error != SttError.None)
724                     {
725                         Log.Error(LogTag, "Get EngineId Failed with error " + error);
726                         return "";
727                     }
728                 }
729
730                 return engineId;
731             }
732             set
733             {
734                 lock (thisLock)
735                 {
736                     SttError error = SttSetEngine(_handle, value);
737                     if (error != SttError.None)
738                     {
739                         Log.Error(LogTag, "Set EngineId Failed with error " + error);
740                         throw ExceptionFactory.CreateException(error);
741                     }
742                 }
743
744             }
745         }
746
747         /// <summary>
748         /// Retrieves the time stamp of the current recognition result.
749         /// </summary>
750         /// <since_tizen> 3 </since_tizen>
751         /// <returns>
752         /// List of ResultTime.
753         /// </returns>
754         /// <privilege>
755         /// http://tizen.org/privilege/recorder
756         /// </privilege>
757         /// <feature>
758         /// http://tizen.org/feature/speech.recognition
759         /// http://tizen.org/feature/microphone
760         /// </feature>
761         /// <remarks>
762         /// This function should only be called in the RecognitionResult event.
763         /// </remarks>
764         /// <exception cref="InvalidOperationException">This exception can be due to operation failed.</exception>
765         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
766         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
767         public IEnumerable<ResultTime> GetDetailedResult()
768         {
769             List<ResultTime> list = new List<ResultTime>();
770             lock (thisLock)
771             {
772                 _resultTimeDelegate = (IntPtr handle, int index, TimeEvent e, IntPtr text, IntPtr startTime, IntPtr endTime, IntPtr userData) =>
773                 {
774                     _result = new ResultTime(index, e, Marshal.PtrToStringAnsi(text), (long)startTime, (long)endTime);
775                     list.Add(_result);
776                     return true;
777                 };
778                 SttError error = SttForeachDetailedResult(_handle, _resultTimeDelegate, IntPtr.Zero);
779                 if (error != SttError.None)
780                 {
781                     Log.Error(LogTag, "GetDetailedResult Failed with error " + error);
782                     throw ExceptionFactory.CreateException(error);
783                 }
784             }
785             return list;
786         }
787
788
789         /// <summary>
790         /// Gets the private data from the STT engine.
791         /// </summary>
792         /// <since_tizen> 3 </since_tizen>
793         /// <param name="key">
794         /// The key string.
795         /// </param>
796         /// <returns>
797         /// The data corresponding to the key is provided.
798         /// </returns>
799         /// <privilege>
800         /// http://tizen.org/privilege/recorder
801         /// </privilege>
802         /// <feature>
803         /// http://tizen.org/feature/speech.recognition
804         /// http://tizen.org/feature/microphone
805         /// </feature>
806         /// <exception cref="InvalidOperationException">This exception can be due to invalid state.</exception>
807         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
808         /// <exception cref="TimeoutException">This exception can be due to No Answer from STT Service.</exception>
809         /// <pre>
810         /// The state must be ready.
811         /// </pre>
812         public string GetPrivateData(string key)
813         {
814             string data;
815             lock (thisLock)
816             {
817                 SttError error = SttGetPrivateData(_handle, key, out data);
818                 if (error != SttError.None)
819                 {
820                     Log.Error(LogTag, "GetPrivateData Failed with error " + error);
821                     throw ExceptionFactory.CreateException(error);
822                 }
823             }
824
825             return data;
826         }
827
828         /// <summary>
829         /// Sets the private data to the STT engine.
830         /// </summary>
831         /// <since_tizen> 3 </since_tizen>
832         /// <param name="key">
833         /// The key string.
834         /// </param>
835         /// <param name="data">
836         /// The data string.
837         /// </param>
838         /// <privilege>
839         /// http://tizen.org/privilege/recorder
840         /// </privilege>
841         /// <feature>
842         /// http://tizen.org/feature/speech.recognition
843         /// http://tizen.org/feature/microphone
844         /// </feature>
845         /// <exception cref="InvalidOperationException">This exception can be due to invalid state.</exception>
846         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
847         /// <exception cref="TimeoutException">This exception can be due to No Answer from STT Service.</exception>
848         /// <exception cref="ArgumentException"> This can happen if Improper value is provided while setting the value. </exception>
849         /// <pre>
850         /// The state must be ready.
851         /// </pre>
852         public void SetPrivateData(string key, string data)
853         {
854             lock (thisLock)
855             {
856                 SttError error = SttSetPrivateData(_handle, key, data);
857                 if (error != SttError.None)
858                 {
859                     Log.Error(LogTag, "SetPrivateData Failed with error " + error);
860                     throw ExceptionFactory.CreateException(error);
861                 }
862             }
863         }
864
865         /// <summary>
866         /// Gets the list of supported engines.
867         /// </summary>
868         /// <since_tizen> 3 </since_tizen>
869         /// <returns>
870         /// IEnumerable&lt;SupportedEngine&gt; list of supported engines.
871         /// </returns>
872         /// <privilege>
873         /// http://tizen.org/privilege/recorder
874         /// </privilege>
875         /// <feature>
876         /// http://tizen.org/feature/speech.recognition
877         /// http://tizen.org/feature/microphone
878         /// </feature>
879         /// <exception cref="InvalidOperationException">This exception can be due to operation failed.</exception>
880         /// <exception cref="OutOfMemoryException">This exception can be due to out of memory.</exception>
881         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
882         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
883         public IEnumerable<SupportedEngine> GetSupportedEngines()
884         {
885             List<SupportedEngine> engineList = new List<SupportedEngine>();
886             lock (thisLock)
887             {
888                 SupportedEngineCallback supportedEngineDelegate = (IntPtr handle, IntPtr engineId, IntPtr engineName, IntPtr userData) =>
889                 {
890                     string id = Marshal.PtrToStringAnsi(engineId);
891                     string name = Marshal.PtrToStringAnsi(engineName);
892                     SupportedEngine engine = new SupportedEngine(id, name);
893                     engineList.Add(engine);
894                     return true;
895                 };
896                 SttError error = SttForeEachSupportedEngines(_handle, supportedEngineDelegate, IntPtr.Zero);
897                 if (error != SttError.None)
898                 {
899                     Log.Error(LogTag, "Create Failed with error " + error);
900                     throw ExceptionFactory.CreateException(error);
901                 }
902             }
903
904             return engineList;
905         }
906
907         /// <summary>
908         /// Sets the application credential.
909         /// </summary>
910         /// <since_tizen> 3 </since_tizen>
911         /// <param name="credential">
912         /// The credential string.
913         /// </param>
914         /// <privilege>
915         /// http://tizen.org/privilege/recorder
916         /// </privilege>
917         /// <feature>
918         /// http://tizen.org/feature/speech.recognition
919         /// http://tizen.org/feature/microphone
920         /// </feature>
921         /// <exception cref="InvalidOperationException">
922         /// This exceptioncan be due to the following reasons:
923         /// 1. Operation Failed
924         /// 2. Invalid State
925         /// </exception>
926         /// <exception cref="OutOfMemoryException">This exception can be due to out of memory.</exception>
927         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
928         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
929         /// <exception cref="ArgumentException"> This can happen if Improper value is provided while setting the value. </exception>
930         /// <pre>
931         /// The state must be created.
932         /// </pre>
933         public void SetCredential(string credential)
934         {
935             lock (thisLock)
936             {
937                 SttError error = SttSetcredential(_handle, credential);
938                 if (error != SttError.None)
939                 {
940                     Log.Error(LogTag, "SetCredential Failed with error " + error);
941                     throw ExceptionFactory.CreateException(error);
942                 }
943             }
944         }
945
946         /// <summary>
947         /// Connects to the STT service asynchronously.
948         /// </summary>
949         /// <since_tizen> 3 </since_tizen>
950         /// <privilege>
951         /// http://tizen.org/privilege/recorder
952         /// </privilege>
953         /// <feature>
954         /// http://tizen.org/feature/speech.recognition
955         /// http://tizen.org/feature/microphone
956         /// </feature>
957         /// <exception cref="InvalidOperationException">This exception can be due to invalid state.</exception>
958         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
959         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
960         /// <pre>
961         /// The state must be created.
962         /// </pre>
963         /// <post>
964         /// If this function is successful, the STT state will be ready.
965         /// If this function is unsuccessful, ErrorOccurred event will be invoked.
966         /// </post>
967         public void Prepare()
968         {
969             lock (thisLock)
970             {
971                 SttError error = SttPrepare(_handle);
972                 if (error != SttError.None)
973                 {
974                     Log.Error(LogTag, "SetEngine Failed with error " + error);
975                     throw ExceptionFactory.CreateException(error);
976                 }
977             }
978         }
979
980         /// <summary>
981         /// Disconnects from the STT service.
982         /// </summary>
983         /// <since_tizen> 3 </since_tizen>
984         /// <privilege>
985         /// http://tizen.org/privilege/recorder
986         /// </privilege>
987         /// <feature>
988         /// http://tizen.org/feature/speech.recognition
989         /// http://tizen.org/feature/microphone
990         /// </feature>
991         /// <exception cref="InvalidOperationException">This exception can be due to invalid state.</exception>
992         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
993         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
994         /// <pre>
995         /// The state must be ready.
996         /// </pre>
997         /// <post>
998         /// If this function is successful, the STT state will be Created.
999         /// </post>
1000         public void Unprepare()
1001         {
1002             lock (thisLock)
1003             {
1004                 SttError error = SttUnprepare(_handle);
1005                 if (error != SttError.None)
1006                 {
1007                     Log.Error(LogTag, "Unprepare Failed with error " + error);
1008                     throw ExceptionFactory.CreateException(error);
1009                 }
1010             }
1011         }
1012
1013         /// <summary>
1014         /// Retrieves all the supported languages of the current engine.
1015         /// The language is specified as an ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code.
1016         /// For example, "ko_KR" for Korean, "en_US" for American English.
1017         /// </summary>
1018         /// <since_tizen> 4 </since_tizen>
1019         /// <privilege>
1020         /// http://tizen.org/privilege/recorder
1021         /// </privilege>
1022         /// <returns>
1023         /// List of strings for supported languages.
1024         /// </returns>
1025         /// <feature>
1026         /// http://tizen.org/feature/speech.recognition
1027         /// http://tizen.org/feature/microphone
1028         /// </feature>
1029         /// <exception cref="InvalidOperationException">
1030         /// This exception can be due to the following reasons:
1031         /// 1. Engine Not Found.
1032         /// 2. Operation Failed.
1033         /// </exception>
1034         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1035         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1036         public IEnumerable<string> GetSupportedLanguages()
1037         {
1038             List<string> languageList = new List<string>();
1039             lock (thisLock)
1040             {
1041                 SupportedLanguageCallback supportedLanguageDelegate = (IntPtr handle, IntPtr language, IntPtr userData) =>
1042                 {
1043                     string lang = Marshal.PtrToStringAnsi(language);
1044                     languageList.Add(lang);
1045                     return true;
1046                 };
1047
1048                 SttError error = SttForeachSupportedLanguages(_handle, supportedLanguageDelegate, IntPtr.Zero);
1049                 if (error != SttError.None)
1050                 {
1051                     Log.Error(LogTag, "GetSupportedLanguages Failed with error " + error);
1052                     throw ExceptionFactory.CreateException(error);
1053                 }
1054             }
1055
1056             return languageList;
1057         }
1058
1059         /// <summary>
1060         /// Checks whether the recognition type is supported.
1061         /// </summary>
1062         /// <since_tizen> 3 </since_tizen>
1063         /// <privilege>
1064         /// http://tizen.org/privilege/recorder
1065         /// </privilege>
1066         /// <param name="type">
1067         /// RecognitionType value.
1068         /// </param>
1069         /// <returns>
1070         /// Bool value indicating whether the recognition type is supported.
1071         /// </returns>
1072         /// <feature>
1073         /// http://tizen.org/feature/speech.recognition
1074         /// http://tizen.org/feature/microphone
1075         /// </feature>
1076         /// <exception cref="InvalidOperationException">
1077         /// This exception can be due to the following reasons:
1078         /// 1. Invalid State
1079         /// 2. Engine Not Found
1080         /// 3. Operation Failed
1081         /// </exception>
1082         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1083         /// <pre>
1084         /// The state should be ready.
1085         /// </pre>
1086         public bool IsRecognitionTypeSupported(RecognitionType type)
1087         {
1088             bool supported;
1089             lock (thisLock)
1090             {
1091                 string recType = "stt.recognition.type.FREE";
1092                 switch (type)
1093                 {
1094                     case RecognitionType.Free:
1095                         {
1096                             recType = "stt.recognition.type.FREE";
1097                             break;
1098                         }
1099
1100                     case RecognitionType.Partial:
1101                         {
1102                             recType = "stt.recognition.type.FREE.PARTIAL";
1103                             break;
1104                         }
1105
1106                     case RecognitionType.Search:
1107                         {
1108                             recType = "stt.recognition.type.SEARCH";
1109                             break;
1110                         }
1111
1112                     case RecognitionType.WebSearch:
1113                         {
1114                             recType = "stt.recognition.type.WEB_SEARCH";
1115                             break;
1116                         }
1117
1118                     case RecognitionType.Map:
1119                         {
1120                             recType = "stt.recognition.type.MAP";
1121                             break;
1122                         }
1123                 }
1124
1125                 SttError error = SttIsRecognitionTypeSupported(_handle, recType, out supported);
1126                 if (error != SttError.None)
1127                 {
1128                     Log.Error(LogTag, "IsRecognitionTypeSupported Failed with error " + error);
1129                     throw ExceptionFactory.CreateException(error);
1130                 }
1131             }
1132
1133             return supported;
1134         }
1135
1136         /// <summary>
1137         /// Sets the silence detection.
1138         /// </summary>
1139         /// <since_tizen> 3 </since_tizen>
1140         /// <privilege>
1141         /// http://tizen.org/privilege/recorder
1142         /// </privilege>
1143         /// <param name="type">
1144         /// SilenceDetection value.
1145         /// </param>
1146         /// <feature>
1147         /// http://tizen.org/feature/speech.recognition
1148         /// http://tizen.org/feature/microphone
1149         /// </feature>
1150         /// <exception cref="InvalidOperationException">
1151         /// This exception can be due to the following reasons:
1152         /// 1. Invalid State
1153         /// 2. Not supported feature of current engine
1154         /// 3. Operation Failed
1155         /// </exception>
1156         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1157         /// <pre>
1158         /// The state should be ready.
1159         /// </pre>
1160         public void SetSilenceDetection(SilenceDetection type)
1161         {
1162             lock (thisLock)
1163             {
1164                 SttError error = SttSetSilenceDetection(_handle, type);
1165                 if (error != SttError.None)
1166                 {
1167                     Log.Error(LogTag, "SetSilenceDetection Failed with error " + error);
1168                     throw ExceptionFactory.CreateException(error);
1169                 }
1170             }
1171         }
1172
1173         /// <summary>
1174         /// Sets the sound to start recording.
1175         /// Sound file type should be .wav type.
1176         /// </summary>
1177         /// <since_tizen> 3 </since_tizen>
1178         /// <privilege>
1179         /// http://tizen.org/privilege/recorder
1180         /// </privilege>
1181         /// <param name="filePath">
1182         /// File path for the sound.
1183         /// </param>
1184         /// <feature>
1185         /// http://tizen.org/feature/speech.recognition
1186         /// http://tizen.org/feature/microphone
1187         /// </feature>
1188         /// <exception cref="InvalidOperationException">
1189         /// This exception can be due to the following reasons:
1190         /// 1. Invalid State
1191         /// 2. Operation Failed
1192         /// </exception>
1193         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1194         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1195         /// <exception cref="ArgumentException"> If an Invalid Parameter is provided. </exception>
1196         /// <pre>
1197         /// The state should be ready.
1198         /// </pre>
1199         public void SetStartSound(string filePath)
1200         {
1201             lock (thisLock)
1202             {
1203                 SttError error = SttSetStartSound(_handle, filePath);
1204                 if (error != SttError.None)
1205                 {
1206                     Log.Error(LogTag, "SetStartSound Failed with error " + error);
1207                     throw ExceptionFactory.CreateException(error);
1208                 }
1209             }
1210         }
1211
1212         /// <summary>
1213         /// Unsets the sound to start recording.
1214         /// </summary>
1215         /// <since_tizen> 3 </since_tizen>
1216         /// <privilege>
1217         /// http://tizen.org/privilege/recorder
1218         /// </privilege>
1219         /// <feature>
1220         /// http://tizen.org/feature/speech.recognition
1221         /// http://tizen.org/feature/microphone
1222         /// </feature>
1223         /// <exception cref="InvalidOperationException">
1224         /// This exception can be due to the following reasons:
1225         /// 1. Invalid State
1226         /// 2. Operation Failed
1227         /// </exception>
1228         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1229         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1230         /// <pre>
1231         /// The state should be ready.
1232         /// </pre>
1233         public void UnsetStartSound()
1234         {
1235             lock (thisLock)
1236             {
1237                 SttError error = SttUnsetStartSound(_handle);
1238                 if (error != SttError.None)
1239                 {
1240                     Log.Error(LogTag, "UnsetStartSound Failed with error " + error);
1241                     throw ExceptionFactory.CreateException(error);
1242                 }
1243             }
1244         }
1245
1246         /// <summary>
1247         /// Sets the sound to stop recording.
1248         /// Sound file type should be .wav type.
1249         /// </summary>
1250         /// <since_tizen> 3 </since_tizen>
1251         /// <privilege>
1252         /// http://tizen.org/privilege/recorder
1253         /// </privilege>
1254         /// <param name="filePath">
1255         /// File Path for the sound.
1256         /// </param>
1257         /// <feature>
1258         /// http://tizen.org/feature/speech.recognition
1259         /// http://tizen.org/feature/microphone
1260         /// </feature>
1261         /// <exception cref="InvalidOperationException">
1262         /// This exception can be due to the following reasons:
1263         /// 1. Invalid State
1264         /// 2. Operation Failed
1265         /// </exception>
1266         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1267         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1268         /// <exception cref="ArgumentException">This exception can be due to Invalid Parameter.</exception>
1269         /// <pre>
1270         /// The state should be ready.
1271         /// </pre>
1272         public void SetStopSound(string filePath)
1273         {
1274             lock (thisLock)
1275             {
1276                 SttError error = SttSetStopSound(_handle, filePath);
1277                 if (error != SttError.None)
1278                 {
1279                     Log.Error(LogTag, "SetStopSound Failed with error " + error);
1280                     throw ExceptionFactory.CreateException(error);
1281                 }
1282             }
1283         }
1284
1285         /// <summary>
1286         /// Unsets the sound to stop recording.
1287         /// </summary>
1288         /// <since_tizen> 3 </since_tizen>
1289         /// <privilege>
1290         /// http://tizen.org/privilege/recorder
1291         /// </privilege>
1292         /// <feature>
1293         /// http://tizen.org/feature/speech.recognition
1294         /// http://tizen.org/feature/microphone
1295         /// </feature>
1296         /// <exception cref="InvalidOperationException">
1297         /// This exception can be due to the following reasons:
1298         /// 1. Invalid State
1299         /// 2. Operation Failed
1300         /// </exception>
1301         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1302         /// <exception cref="UnauthorizedAccessException"> his exception can be due to permission denied.</exception>
1303         /// <pre>
1304         /// The state should be ready.
1305         /// </pre>
1306         public void UnsetStopSound()
1307         {
1308             lock (thisLock)
1309             {
1310                 SttError error = SttUnsetStopSound(_handle);
1311                 if (error != SttError.None)
1312                 {
1313                     Log.Error(LogTag, "UnsetStopSound Failed with error " + error);
1314                     throw ExceptionFactory.CreateException(error);
1315                 }
1316             }
1317         }
1318
1319         /// <summary>
1320         /// Starts the recording and recognition asynchronously.
1321         /// This function starts recording in the STT service and sends the recording data to the engine.
1322         /// This work continues until stop, cancel, or silence is detected by engine.
1323         /// </summary>
1324         /// <since_tizen> 3 </since_tizen>
1325         /// <privilege>
1326         /// http://tizen.org/privilege/recorder
1327         /// </privilege>
1328         /// <param name="language">
1329         /// The language selected.
1330         /// </param>
1331         /// <param name="type">
1332         /// The type for recognition.
1333         /// </param>
1334         /// <feature>
1335         /// http://tizen.org/feature/speech.recognition
1336         /// http://tizen.org/feature/microphone
1337         /// </feature>
1338         /// <exception cref="InvalidOperationException">
1339         /// This exception can be due to the following reasons:
1340         /// 1. Invalid State
1341         /// 2. Operation Failed
1342         /// 3. Recorder Busy
1343         /// 4. Progress to recording is not finished
1344         /// </exception>
1345         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1346         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1347         /// <exception cref="ArgumentException">This exception can be due to an invalid language.</exception>
1348         /// <pre>
1349         /// The state should be ready.
1350         /// </pre>
1351         /// <post>
1352         /// It will invoke the StateChanged event, if registered.
1353         /// If this function succeeds, the STT state will be recording.
1354         /// If you call this function again before the state changes, you will receive ErrorINProgressToRecording.
1355         /// </post>
1356         public void Start(string language, RecognitionType type)
1357         {
1358             lock (thisLock)
1359             {
1360                 string recType = "stt.recognition.type.FREE";
1361                 switch (type)
1362                 {
1363                     case RecognitionType.Free:
1364                         {
1365                             recType = "stt.recognition.type.FREE";
1366                             break;
1367                         }
1368
1369                     case RecognitionType.Partial:
1370                         {
1371                             recType = "stt.recognition.type.FREE.PARTIAL";
1372                             break;
1373                         }
1374
1375                     case RecognitionType.Search:
1376                         {
1377                             recType = "stt.recognition.type.SEARCH";
1378                             break;
1379                         }
1380
1381                     case RecognitionType.WebSearch:
1382                         {
1383                             recType = "stt.recognition.type.WEB_SEARCH";
1384                             break;
1385                         }
1386
1387                     case RecognitionType.Map:
1388                         {
1389                             recType = "stt.recognition.type.MAP";
1390                             break;
1391                         }
1392                 }
1393
1394                 SttError error = SttStart(_handle, language, recType);
1395                 if (error != SttError.None)
1396                 {
1397                     Log.Error(LogTag, "Start Failed with error " + error);
1398                     throw ExceptionFactory.CreateException(error);
1399                 }
1400             }
1401         }
1402
1403         /// <summary>
1404         /// Finishes the recording and starts recognition processing in the engine asynchronously.
1405         /// </summary>
1406         /// <since_tizen> 3 </since_tizen>
1407         /// <privilege>
1408         /// http://tizen.org/privilege/recorder
1409         /// </privilege>
1410         /// <feature>
1411         /// http://tizen.org/feature/speech.recognition
1412         /// http://tizen.org/feature/microphone
1413         /// </feature>
1414         /// <exception cref="InvalidOperationException">
1415         /// This exception can be due to the following reasons:
1416         /// 1. Invalid State
1417         /// 2. Operation Failed
1418         /// 3. Progress to ready is not finished
1419         /// 4. Progress to recording is not finished
1420         /// 5. Progress to processing is not finished
1421         /// </exception>
1422         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1423         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1424         /// <pre>
1425         /// The state should be Recording.
1426         /// </pre>
1427         /// <post>
1428         /// It will invoke the StateChanged Event, if registered.
1429         /// If this function succeeds, the STT state will be processing.
1430         /// If you call this function again before the state changes, you will receive ErrorINProgressToProcessing.
1431         /// After processing of engine, the RecognitionResult event is invoked.
1432         /// </post>
1433         public void Stop()
1434         {
1435             lock (thisLock)
1436             {
1437                 SttError error = SttStop(_handle);
1438                 if (error != SttError.None)
1439                 {
1440                     Log.Error(LogTag, "Stop Failed with error " + error);
1441                     throw ExceptionFactory.CreateException(error);
1442                 }
1443             }
1444         }
1445
1446         /// <summary>
1447         /// Cancels processing the recognition and recording asynchronously.
1448         /// This function cancels recording and the engine cancels recognition processing.
1449         /// After successful cancellation, the StateChanged event is invoked, otherwise if an error is occurs, the ErrorOccurred event is invoked.
1450         /// </summary>
1451         /// <since_tizen> 3 </since_tizen>
1452         /// <privilege>
1453         /// http://tizen.org/privilege/recorder
1454         /// </privilege>
1455         /// <feature>
1456         /// http://tizen.org/feature/speech.recognition
1457         /// http://tizen.org/feature/microphone
1458         /// </feature>
1459         /// <exception cref="InvalidOperationException">
1460         /// This exception can be due to the following reasons:
1461         /// 1. Invalid State
1462         /// 2. Operation Failed
1463         /// 3. Progress to ready is not finished
1464         /// 4. Progress to recording is not finished
1465         /// 5. Progress to processing is not finished
1466         /// </exception>
1467         /// <exception cref="NotSupportedException">This exception can be due to STT not supported.</exception>
1468         /// <exception cref="UnauthorizedAccessException">This exception can be due to permission denied.</exception>
1469         /// <pre>
1470         /// The state should be Recording or Processing.
1471         /// </pre>
1472         /// <post>
1473         /// It will invoke the StateChanged event, if registered.
1474         /// If this function succeeds, the STT state will be ready.
1475         /// If you call this function again before the state changes, you will receive ErrorINProgressToReady.
1476         /// </post>
1477         public void Cancel()
1478         {
1479             lock (thisLock)
1480             {
1481                 SttError error = SttCancel(_handle);
1482                 if (error != SttError.None)
1483                 {
1484                     Log.Error(LogTag, "Cancel Failed with error " + error);
1485                     throw ExceptionFactory.CreateException(error);
1486                 }
1487             }
1488         }
1489
1490         /// <summary>
1491         /// Method to release resources.
1492         /// </summary>
1493         /// <since_tizen> 3 </since_tizen>
1494         public void Dispose()
1495         {
1496             Dispose(true);
1497         }
1498
1499         /// <summary>
1500         /// Method to release resources.
1501         /// </summary>
1502         /// <since_tizen> 3 </since_tizen>
1503         /// <param name="disposing">
1504         /// The boolean value for destoying stt handle.
1505         /// </param>
1506         protected virtual void Dispose(bool disposing)
1507         {
1508             if (!disposedValue)
1509             {
1510                 if (disposing)
1511                 {
1512                     lock (thisLock)
1513                     {
1514                         SttError error = SttDestroy(_handle);
1515                         if (error != SttError.None)
1516                         {
1517                             Log.Error(LogTag, "Destroy Failed with error " + error);
1518                         }
1519                     }
1520                 }
1521
1522                 disposedValue = true;
1523             }
1524         }
1525     }
1526 }