Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Uix.VoiceControl / Tizen.Uix.VoiceControl / VoiceControlClient.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 static Interop.VoiceControl;
21 using static Interop.VoiceControlCommand;
22
23 namespace Tizen.Uix.VoiceControl
24 {
25     /// <summary>
26     /// Enum for Error values that can occur
27     /// </summary>
28     /// <since_tizen> 3 </since_tizen>
29     public enum Error
30     {
31         /// <summary>
32         /// Successful, No error
33         /// </summary>
34         None,
35         /// <summary>
36         /// Out of Memory
37         /// </summary>
38         OutOfMemory,
39         /// <summary>
40         /// I/O error
41         /// </summary>
42         IoError,
43         /// <summary>
44         /// Invalid parameter
45         /// </summary>
46         InvalidParameter,
47         /// <summary>
48         /// No answer from the STT service
49         /// </summary>
50         TimedOut,
51         /// <summary>
52         /// Device or resource busy
53         /// </summary>
54         RecorderBusy,
55         /// <summary>
56         /// Permission denied
57         /// </summary>
58         PermissionDenied,
59         /// <summary>
60         /// VC NOT supported
61         /// </summary>
62         NotSupported,
63         /// <summary>
64         /// Invalid state
65         /// </summary>
66         InvalidState,
67         /// <summary>
68         /// Invalid language
69         /// </summary>
70         InvalidLanguage,
71         /// <summary>
72         /// No available engine
73         /// </summary>
74         EngineNotFound,
75         /// <summary>
76         /// Operation failed
77         /// </summary>
78         OperationFailed,
79         /// <summary>
80         /// Operation Rejected
81         /// </summary>
82         OperationRejected,
83         /// <summary>
84         /// List reached end
85         /// </summary>
86         IterationEnd,
87         /// <summary>
88         /// List Empty
89         /// </summary>
90         Empty,
91         /// <summary>
92         /// Service reset
93         /// </summary>
94         ServiceReset,
95         /// <summary>
96         /// Progress to ready is not finished
97         /// </summary>
98         InProgressToReady,
99         /// <summary>
100         /// Progress to recording is not finished
101         /// </summary>
102         InProgressToRecording,
103         /// <summary>
104         /// Progress to processing is not finished
105         /// </summary>
106         InProgressToProcessing
107     };
108
109     /// <summary>
110     /// Enumeration for the client state.
111     /// </summary>
112     /// <since_tizen> 3 </since_tizen>
113     public enum State
114     {
115         /// <summary>
116         /// 'None' state
117         /// </summary>
118         None = 0,
119         /// <summary>
120         /// 'Initialized' state
121         /// </summary>
122         Initialized = 1,
123         /// <summary>
124         /// 'Ready' state
125         /// </summary>
126         Ready = 2,
127         /// <summary>
128         /// state cannot be determined
129         /// </summary>
130         Unavailable
131     };
132
133     /// <summary>
134     /// Enumerations of service state.
135     /// </summary>
136     /// <since_tizen> 3 </since_tizen>
137     public enum ServiceState
138     {
139         /// <summary>
140         /// 'None' state
141         /// </summary>
142         None = 0,
143         /// <summary>
144         /// 'Ready' state
145         /// </summary>
146         Ready = 1,
147         /// <summary>
148         /// 'Recording' state
149         /// </summary>
150         Recording = 2,
151         /// <summary>
152         /// 'Processing' state
153         /// </summary>
154         Processing = 3,
155         /// <summary>
156         /// state cannot be determined
157         /// </summary>
158         Unavailable
159     };
160
161     /// <summary>
162     /// Enumerations of result event.
163     /// </summary>
164     /// <since_tizen> 3 </since_tizen>
165     public enum ResultEvent
166     {
167         /// <summary>
168         /// Normal result
169         /// </summary>
170         Success = 0,
171         /// <summary>
172         /// Rejected result
173         /// </summary>
174         Rejected = 1
175     };
176
177     /// <summary>
178     /// Enumerations of command type.
179     /// </summary>
180     /// <since_tizen> 3 </since_tizen>
181     public enum CommandType
182     {
183         /// <summary>
184         /// Foreground command by client
185         /// </summary>
186         Foreground = 1,
187         /// <summary>
188         /// Background command by client
189         /// </summary>
190         Background = 2,
191         /// <summary>
192         /// Undefined command
193         /// </summary>
194         Undefined = -1
195     };
196
197     /// <summary>
198     /// A main function of Voice Control API register command and gets notification for recognition result. 
199     /// Applications can add their own commands and be provided result when their command is recognized by user voice input.
200     /// </summary>
201     /// <since_tizen> 3 </since_tizen>
202     public static class VoiceControlClient
203     {
204         /// <summary>
205         /// Called when client gets the recognition result.
206         /// </summary>
207         /// <since_tizen> 3 </since_tizen>
208         /// <remarks>
209         /// If the duplicated commands are recognized, the event(e.g. Result.Rejected) of command may be rejected
210         /// for selecting command as priority.If you set similar or same commands or the recognized results are multi-results, cmdList has the multi commands.
211         /// </remarks>
212         /// <param name="evt">The ResultEvent</param>
213         /// <param name="cmdList">Command List</param>
214         /// <param name="result">Result</param>
215
216         private static event EventHandler<RecognitionResultEventArgs> _recognitionResult;
217         private static event EventHandler<StateChangedEventArgs> _stateChanged;
218         private static event EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
219         private static event EventHandler<ErrorOccuredEventArgs> _errorOccured;
220         private static event EventHandler<CurrentLanguageChangedEventArgs> _currentLanguageChanged;
221         private static VcResultCb s_resultDelegate;
222         private static VcStateChangedCb s_stateDelegate;
223         private static VcServiceStateChangedCb s_serviceStateDelegate;
224         private static VcErrorCb s_errorDelegate;
225         private static VcCurrentLanguageChangedCb s_languageDelegate;
226         private static List<string> s_supportedLanguages;
227         private static VcSupportedLanguageCb s_supportedLanguagesCb;
228         private static VcResultCb s_resultCb;
229         private static RecognitionResult s_recognitionResult;
230
231         /// <summary>
232         /// Gets current language.
233         /// A language is specified as an ISO 3166 alpha-2 two letter country-code
234         /// followed by ISO 639-1 for the two-letter language code.
235         /// For example, "ko_KR" for Korean, "en_US" for American English.
236         /// Empty string is returned incase of some internal error
237         /// </summary>
238         /// <since_tizen> 3 </since_tizen>
239         /// <value>
240         /// Current language in voice control.
241         /// </value>
242         /// <privilege>
243         /// http://tizen.org/privilege/recorder
244         /// </privilege>
245         /// <pre>
246         /// The State must be Initialized or Ready.
247         /// </pre>
248         public static string CurrentLanguage
249         {
250             get
251             {
252                 string currentLanguage;
253
254                 ErrorCode error = VcGetCurrentLanguage(out currentLanguage);
255                 if (error != ErrorCode.None)
256                 {
257                     Log.Error(LogTag, "CurrentLanguage Failed with error " + error);
258                     return "";
259                 }
260
261                 return currentLanguage;
262             }
263         }
264
265         /// <summary>
266         /// Gets current state of voice control client.
267         /// </summary>
268         /// <since_tizen> 3 </since_tizen>
269         /// <value>
270         /// Current state of voice control client.
271         /// </value>
272         /// <privilege>
273         /// http://tizen.org/privilege/recorder
274         /// </privilege>
275         /// <pre>
276         /// The State must be Initialized or Ready.
277         /// </pre>
278         public static State State
279         {
280             get
281             {
282                 State state;
283
284                 ErrorCode error = VcGetState(out state);
285                 if (error != ErrorCode.None)
286                 {
287                     Log.Error(LogTag, "State Failed with error " + error);
288                     return State.Unavailable;
289                 }
290
291                 return state;
292             }
293         }
294
295         /// <summary>
296         /// Gets current state of voice control service.
297         /// </summary>
298         /// <since_tizen> 3 </since_tizen>
299         /// <value>
300         /// Current state of voice control service.
301         /// </value>
302         /// <privilege>
303         /// http://tizen.org/privilege/recorder
304         /// </privilege>
305         /// <pre>
306         /// The State must be Ready.
307         /// </pre>
308         public static ServiceState ServiceState
309         {
310             get
311             {
312                 ServiceState state;
313
314                 ErrorCode error = VcGetServiceState(out state);
315                 if (error != ErrorCode.None)
316                 {
317                     Log.Error(LogTag, "ServiceState Failed with error " + error);
318                     return ServiceState.Unavailable;
319                 }
320
321                 return state;
322             }
323         }
324
325         /// <summary>
326         /// Sets the invocation name.
327         /// </summary>
328         /// <since_tizen> 3 </since_tizen>
329         /// <privilege>
330         /// http://tizen.org/privilege/recorder
331         /// </privilege>
332         /// <privlevel>
333         /// public
334         /// </privlevel>
335         /// <feature>
336         /// http://tizen.org/feature/speech.control
337         /// http://tizen.org/feature/microphone
338         /// </feature>
339         /// <remarks>
340         /// Invocation name is used to activate background commands. The invocation name can be the same as the application name or any other phrase.
341         /// For example, an application "Tizen Sample" has a background command, "Play music", and the invocation name of the application is set to "Tizen Sample".
342         /// In order to activate the background command, users can say "Tizen Sample, Play music". The invocation name is dependent on the current language.
343         /// For example, if the current language is "en_US"(English), the invocation name is also "en_US".
344         /// If the current language is "ja_JP"(Japanese) and the invocation name is "en_US", the invocation name will not be recognized.
345         /// This function should be called before SetCommandList().
346         /// </remarks>
347         /// <param name="name">Invocation name that an application wants to be invoked by</param>
348         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
349         /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
350         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
351         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
352         /// <pre>
353         /// The State must be Ready.
354         /// </pre>
355         public static void SetInvocationName(string name)
356         {
357             ErrorCode error = VcSetInvocationName(name);
358             if (error != ErrorCode.None)
359             {
360                 Log.Error(LogTag, "SetInvocationName Failed with error " + error);
361                 throw ExceptionFactory.CreateException(error);
362             }
363         }
364
365         /// <summary>
366         /// Initializes voice control.
367         /// </summary>
368         /// <since_tizen> 3 </since_tizen>
369         /// <privilege>
370         /// http://tizen.org/privilege/recorder
371         /// </privilege>
372         /// <privlevel>
373         /// public
374         /// </privlevel>
375         /// <feature>
376         /// http://tizen.org/feature/speech.control
377         /// http://tizen.org/feature/microphone
378         /// </feature>
379         /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
380         /// <exception cref="OutOfMemoryException"> This Exception can be due to Out Of Memory. </exception>
381         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
382         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
383         /// <post>
384         /// The State will be Initialized.
385         /// </post>
386         public static void Initialize()
387         {
388             ErrorCode error = VcInitialize();
389             if (error != ErrorCode.None)
390             {
391                 Log.Error(LogTag, "Initialize Failed with error " + error);
392                 throw ExceptionFactory.CreateException(error);
393             }
394         }
395
396         /// <summary>
397         /// Deinitializes voice control.
398         /// </summary>
399         /// <since_tizen> 3 </since_tizen>
400         /// <privilege>
401         /// http://tizen.org/privilege/recorder
402         /// </privilege>
403         /// <privlevel>
404         /// public
405         /// </privlevel>
406         /// <feature>
407         /// http://tizen.org/feature/speech.control
408         /// http://tizen.org/feature/microphone
409         /// </feature>
410         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
411         /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
412         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
413         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
414         public static void Deinitialize()
415         {
416             ErrorCode error = VcDeinitialize();
417             if (error != ErrorCode.None)
418             {
419                 Log.Error(LogTag, "Deinitialize Failed with error " + error);
420                 throw ExceptionFactory.CreateException(error);
421             }
422         }
423
424         /// <summary>
425         /// Connects the voice control service.
426         /// </summary>
427         /// <since_tizen> 3 </since_tizen>
428         /// <privilege>
429         /// http://tizen.org/privilege/recorder
430         /// </privilege>
431         /// <privlevel>
432         /// public
433         /// </privlevel>
434         /// <feature>
435         /// http://tizen.org/feature/speech.control
436         /// http://tizen.org/feature/microphone
437         /// </feature>
438         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
439         /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
440         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
441         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
442         /// <pre>
443         /// The State should be Initialized
444         /// </pre>
445         /// <post>
446         /// The State will be Ready
447         /// </post>
448         public static void Prepare()
449         {
450             ErrorCode error = VcPrepare();
451             if (error != ErrorCode.None)
452             {
453                 Log.Error(LogTag, "Prepare Failed with error " + error);
454                 throw ExceptionFactory.CreateException(error);
455             }
456         }
457
458         /// <summary>
459         /// Disconnects the voice control service.
460         /// </summary>
461         /// <since_tizen> 3 </since_tizen>
462         /// <privilege>
463         /// http://tizen.org/privilege/recorder
464         /// </privilege>
465         /// <privlevel>
466         /// public
467         /// </privlevel>
468         /// <feature>
469         /// http://tizen.org/feature/speech.control
470         /// http://tizen.org/feature/microphone
471         /// </feature>
472         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
473         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
474         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
475         /// <pre>
476         /// The State should be Ready
477         /// </pre>
478         /// <post>
479         /// The State should be Initialized
480         /// </post>
481         public static void Unprepare()
482         {
483             ErrorCode error = VcUnprepare();
484             if (error != ErrorCode.None)
485             {
486                 Log.Error(LogTag, "Unprepare Failed with error " + error);
487                 throw ExceptionFactory.CreateException(error);
488             }
489         }
490
491         /// <summary>
492         /// Retrieves all supported languages.
493         /// A language is specified as an ISO 3166 alpha-2 two letter country-code
494         /// followed by ISO 639-1 for the two-letter language code.
495         /// For example, "ko_KR" for Korean, "en_US" for American English.
496         /// </summary>
497         /// <since_tizen> 3 </since_tizen>
498         /// <privilege>
499         /// http://tizen.org/privilege/recorder
500         /// </privilege>
501         /// <privlevel>
502         /// public
503         /// </privlevel>
504         /// <feature>
505         /// http://tizen.org/feature/speech.control
506         /// http://tizen.org/feature/microphone
507         /// </feature>
508         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
509         /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
510         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
511         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
512         /// <pre>
513         /// The State should be Ready or Initialized
514         /// </pre>
515         public static IEnumerable<string> GetSupportedLanguages()
516         {
517             s_supportedLanguages = new List<string>();
518             s_supportedLanguagesCb = (IntPtr language, IntPtr userData) =>
519             {
520                 string languageStr = Marshal.PtrToStringAnsi(language);
521                 s_supportedLanguages.Add(languageStr);
522                 return true;
523             };
524             ErrorCode error = VcForeachSupportedLanguages(s_supportedLanguagesCb, IntPtr.Zero);
525             if (error != ErrorCode.None)
526             {
527                 Log.Error(LogTag, "GetSupportedLanguages Failed with error " + error);
528                 throw ExceptionFactory.CreateException(error);
529             }
530
531             return s_supportedLanguages;
532         }
533
534         /// <summary>
535         /// Gets the system command list.
536         /// </summary>
537         /// <since_tizen> 3 </since_tizen>
538         /// <returns>
539         /// The Command List else null in case of no System Commands
540         /// </returns>
541         /// <privilege>
542         /// http://tizen.org/privilege/recorder
543         /// </privilege>
544         /// <privlevel>
545         /// public
546         /// </privlevel>
547         /// <feature>
548         /// http://tizen.org/feature/speech.control
549         /// http://tizen.org/feature/microphone
550         /// </feature>
551         /// <remarks>
552         /// In the system command list, there are system commands predefined by product manufacturers.
553         /// Those commands have the highest priority. Therefore, the user can not set any commands same with the system commands.
554         /// </remarks>
555         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
556         /// <exception cref="InvalidOperationException"> This Exception can be due to Operation Failed. </exception>
557         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
558         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
559         /// <pre>
560         /// The State should be Ready
561         /// </pre>
562         public static VoiceCommandList GetSystemCommandList()
563         {
564             IntPtr handle = IntPtr.Zero;
565             ErrorCode error = VcGetSystemCommandList(out handle);
566             if (error != ErrorCode.None)
567             {
568                 Log.Error(LogTag, "GetSystemCommandList Failed with error " + error);
569                 throw ExceptionFactory.CreateException(error);
570             }
571
572             if (handle == IntPtr.Zero)
573             {
574                 Log.Error(LogTag, "GetSystemCommandList handle is null");
575                 return null;
576             }
577
578             SafeCommandListHandle list = new SafeCommandListHandle(handle);
579             return new VoiceCommandList(list);
580         }
581
582         /// <summary>
583         /// Requests to start the dialogue.
584         /// Using this function, the developer can request starting the dialogue to the framework.
585         /// When the developer requests the dialogue, two types of texts, dispText and uttText, can be sent by this function.dispText is a text for displaying, and uttText is that for uttering.
586         /// For example, if dispText is "October 10th" and uttText is "Today is October 10th.", "October 10th" will be displayed on the screen and "Today is October 10th." will be spoken.
587         /// Also, the developer can set whether the dialogue starts automatically or not, using autoStart.
588         /// If the developer sets autoStart as true, the framework will start to record next speech and continue the dialogue.
589         /// </summary>
590         /// <since_tizen> 3 </since_tizen>
591         /// <privilege>
592         /// http://tizen.org/privilege/recorder
593         /// </privilege>
594         /// <privlevel>
595         /// public
596         /// </privlevel>
597         /// <feature>
598         /// http://tizen.org/feature/speech.control
599         /// http://tizen.org/feature/microphone
600         /// </feature>
601         /// <remarks>
602         /// If autoStart is true, the recognition will start again. In this case, it can be restarted up to 4 times.
603         /// </remarks>
604         /// <param name="dispText"> Text to be displayed on the screen/// </param>
605         /// <param name="uttText">Text to be spoken</param>
606         /// <param name="autoStart">A variable for setting whether the dialog session will be restarted automatically or not</param>
607         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
608         /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
609         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
610         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
611         /// <pre>
612         /// The State should be Ready
613         /// </pre>
614         public static void RequestDialog(string dispText, string uttText, bool autoStart)
615         {
616             ErrorCode error = VcRequestDialog(dispText, uttText, autoStart);
617             if (error != ErrorCode.None)
618             {
619                 Log.Error(LogTag, "RequestDialog Failed with error " + error);
620                 throw ExceptionFactory.CreateException(error);
621             }
622         }
623
624         /// <summary>
625         /// Sets command list.
626         /// </summary>
627         /// <since_tizen> 3 </since_tizen>
628         /// <privilege>
629         /// http://tizen.org/privilege/recorder
630         /// </privilege>
631         /// <privlevel>
632         /// public
633         /// </privlevel>
634         /// <feature>
635         /// http://tizen.org/feature/speech.control
636         /// http://tizen.org/feature/microphone
637         /// </feature>
638         /// <remarks>
639         /// The command type is valid for CommandType 'Foreground' or 'Background'.
640         /// The matched commands of command list should be set and they should include type and command text at least.
641         /// </remarks>
642         /// <param name="list">Command list</param>
643         /// <param name="type">Command type</param>
644         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
645         /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
646         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
647         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
648         /// <pre>
649         /// The State should be Ready
650         /// </pre>
651         public static void SetCommandList(VoiceCommandList list, CommandType type)
652         {
653             if ((type == CommandType.Foreground) || (type == CommandType.Background))
654             {
655                 ErrorCode error = VcSetCommandList(list._handle, (VoiceCommandType)type);
656                 if (error != ErrorCode.None)
657                 {
658                     Log.Error(LogTag, "SetCommandList Failed with error " + error);
659                     throw ExceptionFactory.CreateException(error);
660                 }
661             }
662
663             else
664             {
665                 throw ExceptionFactory.CreateException(ErrorCode.InvalidParameter);
666             }
667         }
668
669         /// <summary>
670         /// Unsets command list.
671         /// </summary>
672         /// <since_tizen> 3 </since_tizen>
673         /// <privilege>
674         /// http://tizen.org/privilege/recorder
675         /// </privilege>
676         /// <privlevel>
677         /// public
678         /// </privlevel>
679         /// <feature>
680         /// http://tizen.org/feature/speech.control
681         /// http://tizen.org/feature/microphone
682         /// </feature>
683         /// <param name="type">Command type</param>
684         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
685         /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
686         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
687         /// <exception cref="UnauthorizedAccessException"> This Exception can be due to Permission Denied. </exception>
688         /// <pre>
689         /// The State should be Ready
690         /// </pre>
691         public static void UnsetCommandList(CommandType type)
692         {
693             if ((type == CommandType.Foreground) || (type == CommandType.Background))
694             {
695                 VoiceCommandType commandType = VoiceCommandType.Foreground;
696                 if (type == CommandType.Background)
697                     commandType = VoiceCommandType.BackGround;
698                 ErrorCode error = VcUnsetCommandList(commandType);
699                 if (error != ErrorCode.None)
700                 {
701                     Log.Error(LogTag, "UnsetCommandList Failed with error " + error);
702                     throw ExceptionFactory.CreateException(error);
703                 }
704             }
705
706             else
707             {
708                 throw ExceptionFactory.CreateException(ErrorCode.InvalidParameter);
709             }
710         }
711
712         /// <summary>
713         /// Gets the recognition result.
714         /// </summary>
715         /// <since_tizen> 3 </since_tizen>
716         /// <privilege>
717         /// http://tizen.org/privilege/recorder
718         /// </privilege>
719         /// <privlevel>
720         /// public
721         /// </privlevel>
722         /// <feature>
723         /// http://tizen.org/feature/speech.control
724         /// http://tizen.org/feature/microphone
725         /// </feature>
726         /// <exception cref="InvalidOperationException"> This Exception can be due to Invalid State. </exception>
727         /// <exception cref="ArgumentException"> This Exception can be due to Invalid Parameter. </exception>
728         /// <exception cref="NotSupportedException"> This Exception can be due to Not Supported. </exception>
729         /// <returns>The Recognition Result if possible else a null object</returns>
730         /// <pre>
731         /// The State should be Ready
732         /// </pre>
733         public static RecognitionResult GetResult()
734         {
735             s_recognitionResult = null;
736             s_resultCb = (ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData) =>
737             {
738                 s_recognitionResult = new RecognitionResult(evt, cmdList, result);
739             };
740             ErrorCode error = VcGetResult(s_resultCb, IntPtr.Zero);
741             if (error != ErrorCode.None)
742             {
743                 Log.Error(LogTag, "GetResult Failed with error " + error);
744                 throw ExceptionFactory.CreateException(error);
745             }
746
747             return s_recognitionResult;
748         }
749
750         /// <summary>
751         /// Event to be invoked when the recognition is done.
752         /// </summary>
753         /// <since_tizen> 3 </since_tizen>
754         /// <pre>
755         /// The State should be Initialized
756         /// </pre>
757         public static event EventHandler<RecognitionResultEventArgs> RecognitionResult
758         {
759             add
760             {
761                 s_resultDelegate = (ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData) =>
762                 {
763                     Log.Info(LogTag, "Recognition Result Event Triggered");
764                     if ((cmdList != null) && (result != null))
765                     {
766                         RecognitionResultEventArgs args = new RecognitionResultEventArgs(new RecognitionResult( evt, cmdList, result));
767                         _recognitionResult?.Invoke(null, args);
768                     }
769                     else
770                     {
771                         Log.Info(LogTag, "Recognition Result Event null received");
772                     }
773                 };
774                 ErrorCode error = VcSetResultCb(s_resultDelegate, IntPtr.Zero);
775                 if (error != ErrorCode.None)
776                 {
777                     Log.Error(LogTag, "Add RecognitionResult Failed with error " + error);
778                 }
779                 else
780                 {
781                     _recognitionResult += value;
782                 }
783             }
784
785             remove
786             {
787                 ErrorCode error = VcUnsetResultCb();
788                 if (error != ErrorCode.None)
789                 {
790                     Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error);
791                 }
792
793                 _recognitionResult -= value;
794             }
795         }
796
797         /// <summary>
798         /// Event to be invoked when VoiceControl service state changes.
799         /// </summary>
800         /// <since_tizen> 3 </since_tizen>
801         /// <pre>
802         /// The State should be Initialized
803         /// </pre>
804         public static event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
805         {
806             add
807             {
808                 s_serviceStateDelegate = (ServiceState previous, ServiceState current, IntPtr userData) =>
809                 {
810                     ServiceStateChangedEventArgs args = new ServiceStateChangedEventArgs(previous, current);
811                     _serviceStateChanged?.Invoke(null, args);
812                 };
813                 ErrorCode error = VcSetServiceStateChangedCb(s_serviceStateDelegate, IntPtr.Zero);
814                 if (error != ErrorCode.None)
815                 {
816                     Log.Error(LogTag, "Add ServiceStateChanged Failed with error " + error);
817                 }
818                 else
819                 {
820                     _serviceStateChanged += value;
821                 }
822             }
823
824             remove
825             {
826                 ErrorCode error = VcUnsetServiceStateChangedCb();
827                 if (error != ErrorCode.None)
828                 {
829                     Log.Error(LogTag, "Remove ServiceStateChanged Failed with error " + error);
830                 }
831
832                 _serviceStateChanged -= value;
833             }
834         }
835
836         /// <summary>
837         /// Event to be invoked when VoiceControl client state changes.
838         /// </summary>
839         /// <since_tizen> 3 </since_tizen>
840         /// <pre>
841         /// The State should be Initialized
842         /// </pre>
843         public static event EventHandler<StateChangedEventArgs> StateChanged
844         {
845             add
846             {
847                 s_stateDelegate = (State previous, State current, IntPtr userData) =>
848                 {
849                     StateChangedEventArgs args = new StateChangedEventArgs(previous, current);
850                     _stateChanged?.Invoke(null, args);
851                 };
852                 ErrorCode error = VcSetStateChangedCb(s_stateDelegate, IntPtr.Zero);
853                 if (error != ErrorCode.None)
854                 {
855                     Log.Error(LogTag, "Add StateChanged Failed with error " + error);
856                 }
857                 else
858                 {
859                     _stateChanged += value;
860                 }
861             }
862
863             remove
864             {
865                 ErrorCode error = VcUnsetStateChangedCb();
866                 if (error != ErrorCode.None)
867                 {
868                     Log.Error(LogTag, "Remove StateChanged Failed with error " + error);
869                 }
870
871                 _stateChanged -= value;
872             }
873         }
874
875         /// <summary>
876         /// Event to be invoked when an error occurs.
877         /// </summary>
878         /// <since_tizen> 3 </since_tizen>
879         /// <pre>
880         /// The State should be Initialized
881         /// </pre>
882         public static event EventHandler<ErrorOccuredEventArgs> ErrorOccured
883         {
884             add
885             {
886                 s_errorDelegate = (ErrorCode reason, IntPtr userData) =>
887             {
888                 ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(reason);
889                 _errorOccured?.Invoke(null, args);
890             };
891                 ErrorCode error = VcSetErrorCb(s_errorDelegate, IntPtr.Zero);
892                 if (error != ErrorCode.None)
893                 {
894                     Log.Error(LogTag, "Add ErrorOccured Failed with error " + error);
895                 }
896
897                 else
898                 {
899                     _errorOccured += value;
900                 }
901             }
902
903
904             remove
905             {
906                 ErrorCode error = VcUnsetErrorCb();
907                 if (error != ErrorCode.None)
908                 {
909                     Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error);
910                 }
911
912                 _errorOccured -= value;
913             }
914         }
915
916         /// <summary>
917         /// Event to be invoked when default laungage change.
918         /// </summary>
919         /// <since_tizen> 3 </since_tizen>
920         /// <pre>
921         /// The State should be Initialized
922         /// </pre>
923         public static event EventHandler<CurrentLanguageChangedEventArgs> CurrentLanguageChanged
924         {
925             add
926             {
927                 s_languageDelegate = (IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) =>
928             {
929                 string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage);
930                 string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage);
931                 CurrentLanguageChangedEventArgs args = new CurrentLanguageChangedEventArgs(previousLanguageString, currentLanguageString);
932                 _currentLanguageChanged?.Invoke(null, args);
933             };
934                 ErrorCode error = VcSetCurrentLanguageChangedCb(s_languageDelegate, IntPtr.Zero);
935                 if (error != ErrorCode.None)
936                 {
937                     Log.Error(LogTag, "Add CurrentLanguageChanged Failed with error " + error);
938                 }
939
940                 else
941                 {
942                     _currentLanguageChanged += value;
943                 }
944             }
945
946             remove
947             {
948                 ErrorCode error = VcUnsetCurrentLanguageChangedCb();
949                 if (error != ErrorCode.None)
950                 {
951                     Log.Error(LogTag, "Remove CurrentLanguageChanged Failed with error " + error);
952                 }
953
954                 _currentLanguageChanged -= value;
955             }
956         }
957     }
958 }