/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using static Interop.VoiceControl; using static Interop.VoiceControlCommand; namespace Tizen.Uix.VoiceControl { /// /// Enum for Error values that can occur /// /// 3 public enum Error { /// /// Successful, No error /// None, /// /// Out of Memory /// OutOfMemory, /// /// I/O error /// IoError, /// /// Invalid parameter /// InvalidParameter, /// /// No answer from the STT service /// TimedOut, /// /// Device or resource busy /// RecorderBusy, /// /// Permission denied /// PermissionDenied, /// /// VC NOT supported /// NotSupported, /// /// Invalid state /// InvalidState, /// /// Invalid language /// InvalidLanguage, /// /// No available engine /// EngineNotFound, /// /// Operation failed /// OperationFailed, /// /// Operation Rejected /// OperationRejected, /// /// List reached end /// IterationEnd, /// /// List Empty /// Empty, /// /// Service reset /// ServiceReset, /// /// Progress to ready is not finished /// InProgressToReady, /// /// Progress to recording is not finished /// InProgressToRecording, /// /// Progress to processing is not finished /// InProgressToProcessing }; /// /// Enumeration for the client state. /// /// 3 public enum State { /// /// 'None' state /// None = 0, /// /// 'Initialized' state /// Initialized = 1, /// /// 'Ready' state /// Ready = 2, /// /// state cannot be determined /// Unavailable }; /// /// Enumerations of service state. /// /// 3 public enum ServiceState { /// /// 'None' state /// None = 0, /// /// 'Ready' state /// Ready = 1, /// /// 'Recording' state /// Recording = 2, /// /// 'Processing' state /// Processing = 3, /// /// state cannot be determined /// Unavailable }; /// /// Enumerations of result event. /// /// 3 public enum ResultEvent { /// /// Normal result /// Success = 0, /// /// Rejected result /// Rejected = 1 }; /// /// Enumerations of command type. /// /// 3 public enum CommandType { /// /// Foreground command by client /// Foreground = 1, /// /// Background command by client /// Background = 2, /// /// Undefined command /// Undefined = -1 }; /// /// A main function of Voice Control API register command and gets notification for recognition result. /// Applications can add their own commands and be provided result when their command is recognized by user voice input. /// /// 3 public static class VoiceControlClient { /// /// Called when client gets the recognition result. /// /// 3 /// /// If the duplicated commands are recognized, the event(e.g. Result.Rejected) of command may be rejected /// for selecting command as priority.If you set similar or same commands or the recognized results are multi-results, cmdList has the multi commands. /// /// The ResultEvent /// Command List /// Result private static event EventHandler _recognitionResult; private static event EventHandler _stateChanged; private static event EventHandler _serviceStateChanged; private static event EventHandler _errorOccured; private static event EventHandler _currentLanguageChanged; private static VcResultCb s_resultDelegate; private static VcStateChangedCb s_stateDelegate; private static VcServiceStateChangedCb s_serviceStateDelegate; private static VcErrorCb s_errorDelegate; private static VcCurrentLanguageChangedCb s_languageDelegate; private static List s_supportedLanguages; private static VcSupportedLanguageCb s_supportedLanguagesCb; private static VcResultCb s_resultCb; private static RecognitionResult s_recognitionResult; /// /// Gets current language. /// A language is specified as an ISO 3166 alpha-2 two letter country-code /// followed by ISO 639-1 for the two-letter language code. /// For example, "ko_KR" for Korean, "en_US" for American English. /// Empty string is returned incase of some internal error /// /// 3 /// /// Current language in voice control. /// /// /// http://tizen.org/privilege/recorder /// ///
        /// The State must be Initialized or Ready.
        /// 
public static string CurrentLanguage { get { string currentLanguage; ErrorCode error = VcGetCurrentLanguage(out currentLanguage); if (error != ErrorCode.None) { Log.Error(LogTag, "CurrentLanguage Failed with error " + error); return ""; } return currentLanguage; } } /// /// Gets current state of voice control client. /// /// 3 /// /// Current state of voice control client. /// /// /// http://tizen.org/privilege/recorder /// ///
        /// The State must be Initialized or Ready.
        /// 
public static State State { get { State state; ErrorCode error = VcGetState(out state); if (error != ErrorCode.None) { Log.Error(LogTag, "State Failed with error " + error); return State.Unavailable; } return state; } } /// /// Gets current state of voice control service. /// /// 3 /// /// Current state of voice control service. /// /// /// http://tizen.org/privilege/recorder /// ///
        /// The State must be Ready.
        /// 
public static ServiceState ServiceState { get { ServiceState state; ErrorCode error = VcGetServiceState(out state); if (error != ErrorCode.None) { Log.Error(LogTag, "ServiceState Failed with error " + error); return ServiceState.Unavailable; } return state; } } /// /// Sets the invocation name. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// /// Invocation name is used to activate background commands. The invocation name can be the same as the application name or any other phrase. /// For example, an application "Tizen Sample" has a background command, "Play music", and the invocation name of the application is set to "Tizen Sample". /// In order to activate the background command, users can say "Tizen Sample, Play music". The invocation name is dependent on the current language. /// For example, if the current language is "en_US"(English), the invocation name is also "en_US". /// If the current language is "ja_JP"(Japanese) and the invocation name is "en_US", the invocation name will not be recognized. /// This function should be called before SetCommandList(). /// /// Invocation name that an application wants to be invoked by /// This Exception can be due to Invalid State. /// This Exception can be due to Invalid Parameter. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State must be Ready.
        /// 
public static void SetInvocationName(string name) { ErrorCode error = VcSetInvocationName(name); if (error != ErrorCode.None) { Log.Error(LogTag, "SetInvocationName Failed with error " + error); throw ExceptionFactory.CreateException(error); } } /// /// Initializes voice control. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// This Exception can be due to Operation Failed. /// This Exception can be due to Out Of Memory. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. /// /// The State will be Initialized. /// public static void Initialize() { ErrorCode error = VcInitialize(); if (error != ErrorCode.None) { Log.Error(LogTag, "Initialize Failed with error " + error); throw ExceptionFactory.CreateException(error); } } /// /// Deinitializes voice control. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// This Exception can be due to Invalid State. /// This Exception can be due to Operation Failed. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. public static void Deinitialize() { ErrorCode error = VcDeinitialize(); if (error != ErrorCode.None) { Log.Error(LogTag, "Deinitialize Failed with error " + error); throw ExceptionFactory.CreateException(error); } } /// /// Connects the voice control service. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// This Exception can be due to Invalid State. /// This Exception can be due to Operation Failed. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Initialized
        /// 
/// /// The State will be Ready /// public static void Prepare() { ErrorCode error = VcPrepare(); if (error != ErrorCode.None) { Log.Error(LogTag, "Prepare Failed with error " + error); throw ExceptionFactory.CreateException(error); } } /// /// Disconnects the voice control service. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// This Exception can be due to Invalid State. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Ready
        /// 
/// /// The State should be Initialized /// public static void Unprepare() { ErrorCode error = VcUnprepare(); if (error != ErrorCode.None) { Log.Error(LogTag, "Unprepare Failed with error " + error); throw ExceptionFactory.CreateException(error); } } /// /// Retrieves all supported languages. /// A language is specified as an ISO 3166 alpha-2 two letter country-code /// followed by ISO 639-1 for the two-letter language code. /// For example, "ko_KR" for Korean, "en_US" for American English. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// This Exception can be due to Invalid State. /// This Exception can be due to Operation Failed. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Ready or Initialized
        /// 
public static IEnumerable GetSupportedLanguages() { s_supportedLanguages = new List(); s_supportedLanguagesCb = (IntPtr language, IntPtr userData) => { string languageStr = Marshal.PtrToStringAnsi(language); s_supportedLanguages.Add(languageStr); return true; }; ErrorCode error = VcForeachSupportedLanguages(s_supportedLanguagesCb, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "GetSupportedLanguages Failed with error " + error); throw ExceptionFactory.CreateException(error); } return s_supportedLanguages; } /// /// Gets the system command list. /// /// 3 /// /// The Command List else null in case of no System Commands /// /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// /// In the system command list, there are system commands predefined by product manufacturers. /// Those commands have the highest priority. Therefore, the user can not set any commands same with the system commands. /// /// This Exception can be due to Invalid State. /// This Exception can be due to Operation Failed. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Ready
        /// 
public static VoiceCommandList GetSystemCommandList() { IntPtr handle = IntPtr.Zero; ErrorCode error = VcGetSystemCommandList(out handle); if (error != ErrorCode.None) { Log.Error(LogTag, "GetSystemCommandList Failed with error " + error); throw ExceptionFactory.CreateException(error); } if (handle == IntPtr.Zero) { Log.Error(LogTag, "GetSystemCommandList handle is null"); return null; } SafeCommandListHandle list = new SafeCommandListHandle(handle); return new VoiceCommandList(list); } /// /// Requests to start the dialogue. /// Using this function, the developer can request starting the dialogue to the framework. /// 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. /// 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. /// Also, the developer can set whether the dialogue starts automatically or not, using autoStart. /// If the developer sets autoStart as true, the framework will start to record next speech and continue the dialogue. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// /// If autoStart is true, the recognition will start again. In this case, it can be restarted up to 4 times. /// /// Text to be displayed on the screen/// /// Text to be spoken /// A variable for setting whether the dialog session will be restarted automatically or not /// This Exception can be due to Invalid State. /// This Exception can be due to Invalid Parameter. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Ready
        /// 
public static void RequestDialog(string dispText, string uttText, bool autoStart) { ErrorCode error = VcRequestDialog(dispText, uttText, autoStart); if (error != ErrorCode.None) { Log.Error(LogTag, "RequestDialog Failed with error " + error); throw ExceptionFactory.CreateException(error); } } /// /// Sets command list. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// /// The command type is valid for CommandType 'Foreground' or 'Background'. /// The matched commands of command list should be set and they should include type and command text at least. /// /// Command list /// Command type /// This Exception can be due to Invalid State. /// This Exception can be due to Invalid Parameter. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Ready
        /// 
public static void SetCommandList(VoiceCommandList list, CommandType type) { if ((type == CommandType.Foreground) || (type == CommandType.Background)) { ErrorCode error = VcSetCommandList(list._handle, (VoiceCommandType)type); if (error != ErrorCode.None) { Log.Error(LogTag, "SetCommandList Failed with error " + error); throw ExceptionFactory.CreateException(error); } } else { throw ExceptionFactory.CreateException(ErrorCode.InvalidParameter); } } /// /// Unsets command list. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// Command type /// This Exception can be due to Invalid State. /// This Exception can be due to Invalid Parameter. /// This Exception can be due to Not Supported. /// This Exception can be due to Permission Denied. ///
        /// The State should be Ready
        /// 
public static void UnsetCommandList(CommandType type) { if ((type == CommandType.Foreground) || (type == CommandType.Background)) { VoiceCommandType commandType = VoiceCommandType.Foreground; if (type == CommandType.Background) commandType = VoiceCommandType.BackGround; ErrorCode error = VcUnsetCommandList(commandType); if (error != ErrorCode.None) { Log.Error(LogTag, "UnsetCommandList Failed with error " + error); throw ExceptionFactory.CreateException(error); } } else { throw ExceptionFactory.CreateException(ErrorCode.InvalidParameter); } } /// /// Gets the recognition result. /// /// 3 /// /// http://tizen.org/privilege/recorder /// /// /// public /// /// /// http://tizen.org/feature/speech.control /// http://tizen.org/feature/microphone /// /// This Exception can be due to Invalid State. /// This Exception can be due to Invalid Parameter. /// This Exception can be due to Not Supported. /// The Recognition Result if possible else a null object ///
        /// The State should be Ready
        /// 
public static RecognitionResult GetResult() { s_recognitionResult = null; s_resultCb = (ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData) => { s_recognitionResult = new RecognitionResult(evt, cmdList, result); }; ErrorCode error = VcGetResult(s_resultCb, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "GetResult Failed with error " + error); throw ExceptionFactory.CreateException(error); } return s_recognitionResult; } /// /// Event to be invoked when the recognition is done. /// /// 3 ///
        /// The State should be Initialized
        /// 
public static event EventHandler RecognitionResult { add { s_resultDelegate = (ResultEvent evt, IntPtr cmdList, IntPtr result, IntPtr userData) => { Log.Info(LogTag, "Recognition Result Event Triggered"); if ((cmdList != null) && (result != null)) { RecognitionResultEventArgs args = new RecognitionResultEventArgs(new RecognitionResult( evt, cmdList, result)); _recognitionResult?.Invoke(null, args); } else { Log.Info(LogTag, "Recognition Result Event null received"); } }; ErrorCode error = VcSetResultCb(s_resultDelegate, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "Add RecognitionResult Failed with error " + error); } else { _recognitionResult += value; } } remove { ErrorCode error = VcUnsetResultCb(); if (error != ErrorCode.None) { Log.Error(LogTag, "Remove RecognitionResult Failed with error " + error); } _recognitionResult -= value; } } /// /// Event to be invoked when VoiceControl service state changes. /// /// 3 ///
        /// The State should be Initialized
        /// 
public static event EventHandler ServiceStateChanged { add { s_serviceStateDelegate = (ServiceState previous, ServiceState current, IntPtr userData) => { ServiceStateChangedEventArgs args = new ServiceStateChangedEventArgs(previous, current); _serviceStateChanged?.Invoke(null, args); }; ErrorCode error = VcSetServiceStateChangedCb(s_serviceStateDelegate, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "Add ServiceStateChanged Failed with error " + error); } else { _serviceStateChanged += value; } } remove { ErrorCode error = VcUnsetServiceStateChangedCb(); if (error != ErrorCode.None) { Log.Error(LogTag, "Remove ServiceStateChanged Failed with error " + error); } _serviceStateChanged -= value; } } /// /// Event to be invoked when VoiceControl client state changes. /// /// 3 ///
        /// The State should be Initialized
        /// 
public static event EventHandler StateChanged { add { s_stateDelegate = (State previous, State current, IntPtr userData) => { StateChangedEventArgs args = new StateChangedEventArgs(previous, current); _stateChanged?.Invoke(null, args); }; ErrorCode error = VcSetStateChangedCb(s_stateDelegate, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "Add StateChanged Failed with error " + error); } else { _stateChanged += value; } } remove { ErrorCode error = VcUnsetStateChangedCb(); if (error != ErrorCode.None) { Log.Error(LogTag, "Remove StateChanged Failed with error " + error); } _stateChanged -= value; } } /// /// Event to be invoked when an error occurs. /// /// 3 ///
        /// The State should be Initialized
        /// 
public static event EventHandler ErrorOccured { add { s_errorDelegate = (ErrorCode reason, IntPtr userData) => { ErrorOccuredEventArgs args = new ErrorOccuredEventArgs(reason); _errorOccured?.Invoke(null, args); }; ErrorCode error = VcSetErrorCb(s_errorDelegate, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "Add ErrorOccured Failed with error " + error); } else { _errorOccured += value; } } remove { ErrorCode error = VcUnsetErrorCb(); if (error != ErrorCode.None) { Log.Error(LogTag, "Remove ErrorOccured Failed with error " + error); } _errorOccured -= value; } } /// /// Event to be invoked when default laungage change. /// /// 3 ///
        /// The State should be Initialized
        /// 
public static event EventHandler CurrentLanguageChanged { add { s_languageDelegate = (IntPtr previousLanguage, IntPtr currentLanguage, IntPtr userData) => { string previousLanguageString = Marshal.PtrToStringAnsi(previousLanguage); string currentLanguageString = Marshal.PtrToStringAnsi(currentLanguage); CurrentLanguageChangedEventArgs args = new CurrentLanguageChangedEventArgs(previousLanguageString, currentLanguageString); _currentLanguageChanged?.Invoke(null, args); }; ErrorCode error = VcSetCurrentLanguageChangedCb(s_languageDelegate, IntPtr.Zero); if (error != ErrorCode.None) { Log.Error(LogTag, "Add CurrentLanguageChanged Failed with error " + error); } else { _currentLanguageChanged += value; } } remove { ErrorCode error = VcUnsetCurrentLanguageChangedCb(); if (error != ErrorCode.None) { Log.Error(LogTag, "Remove CurrentLanguageChanged Failed with error " + error); } _currentLanguageChanged -= value; } } } }