speechsrv_plat/vas_vcommand_api/inc/vcommandapi.h
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:29:17 +0100
branchRCL_3
changeset 23 e36f3802f733
parent 0 bf1d17376201
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Voice command service interfaces
*
*/



#ifndef VCOMMANDAPI_H
#define VCOMMANDAPI_H

#include <e32def.h>
#include <e32cmn.h>
#include <s32strm.h>
#include <nssvasmrrd.h>  // For KNssVASMAXRRDTextLength only

/** 
* Maximal length of the exe arguments string
* @todo If longer arguments needed, reengineer the storage scheme. 
*       Currently argument string has to fit into the VAS DB rrdtext column
*       @see CTagCommandConverter
*/
const TInt KMaxVCArgumentLength = KNssVASMAXRRDTextLength;

class MNssPlayEventHandler;
class CStoredVCommand;
class MVCService;
class CVCommandHandler;
class CGulIcon;

/**
 * Container for the voice command folder information. Note that every command can
 * have its own folder information
 */
class CVCFolderInfo : public CBase
    {
    public:
        /**
         * This object does not take an ownership of the passed descriptors, 
         * but makes own copies. 
         * 
         * @param aTitle Folder title. It is shown at the top of the screen,
         *        when the folder is opened in the VCommand application
         * @param aListedName Version of a title shown when the folder is
         *        is displayed in the list of VCommands in the VCommand app
         * @param aHelpTopicId Topic to open when help is requested for the 
         *        given folder
         * @param aIconIndex Zero based index of the folder icon in the folder icons mbm file
         *        each index correspods to two images - the actual icon and its mask
         * @param aIconFile Mbm file where the icons are obtained from. If KNullDesC, 
         * 		  the default icon file is used
         * 
         */
        IMPORT_C static CVCFolderInfo* NewL( const TDesC& aTitle,
                const TDesC& aListedName, TUint32 aHelpTopicId, TUint aIconIndex,
                const TDesC& aIconFile = KNullDesC );
                
        /**
         * Constructs the folder information from stream
         * @leave KErrNotSupported if the stream data format is unsupported
         */
        IMPORT_C static CVCFolderInfo* NewL( RReadStream& aStream );
        
        /**
         * Cloning constructor
         */
        IMPORT_C static CVCFolderInfo* NewL( const CVCFolderInfo& aOriginal );
        
        IMPORT_C ~CVCFolderInfo();
        
        /** 
        * Saves the folder information to stream.
        * Descriptor components are saved as <length><descriptor> pairs, where 
        * <length> is TInt32 and <descriptor> is the default descriptor represetation
        */
        IMPORT_C void ExternalizeL( RWriteStream &aStream ) const;
        
        /**
         * Returns folder title. It is shown at the top of the screen,
         *        when the folder is opened in the VCommand application
         */
        IMPORT_C const TDesC& Title() const;
        
        /**
         * Version of a title shown when the folder is
         * is displayed in the list of VCommands in the VCommand app
         */
        IMPORT_C const TDesC& ListedName() const;
        
        IMPORT_C TUint32 HelpTopicId() const;
        
	/**
        * Creates an icon to represent this folder. Works only if CEikonEnv is available
	* @return Icon for the folder
	*/
	IMPORT_C CGulIcon* IconLC() const;
        
        IMPORT_C TBool operator==( const CVCFolderInfo& aFolderInfo ) const;
    
    protected:
        CVCFolderInfo( TUint32 aHelpTopicId, TUint aIconIndex );
        // unhiding inherited parameterless constructor
        CVCFolderInfo() {}
        
        /**
         * Zero based index of the folder icon in the icon file
         * @see IconFile
         */
        TUint IconIndex() const;
        
        /**
         * Full file name of the file name, where the folder icon is obtained from
         * Is always no longer, than KMaxFileName
         * If KNullDesC is returned, the default icon file is used
         */
        TDesC& IconFile() const;

    private:
        /** @see NewL */
        void ConstructL( const TDesC& aTitle, 
                         const TDesC& aListedName,
                         const TDesC& aIconFile );
                
        void ConstructL( RReadStream& aStream );
        
    private:
        HBufC* iTitle;
        
        HBufC* iListedName;
        
        HBufC* iIconFile;
        
        TUint32 iHelpTopicId;
        
        TUint iIconIndex;
        
    };

/** 
* Container for VC app specific "human-visible" parts of the voice command:
* tooltip, displayable text, folder, icon, etc
*/ 
class CVCCommandUi : public CBase
    {
    public:
        /**
        * This object does not take an ownership of the passed descriptors, 
        * but makes own copies. 
        * 
        * @param aWrittenText Text to display
        * @param aTooltip Second line of the text if ant
        * @param aFolderInfo Folder-related details
        * @param aModifiable If user can modify the command
        * @param aConfirmationNeeded If EFalse, when the command is recognized,
        *        it is immediately executed
        *        If ETrue, when the command is recognized, it is played back and
        *        user is asked to confirm the recognition results
        * @see
        * @todo Add "see" reference to the recognition-side function that uses the
        *       "confirmation needed information"
        * @todo aModifiable param is "hanging in the air" and never actually used
        *       Clarify its existence and responsibilities
        * @param aUserText Optional user-specified shortcut for the command
        */
        IMPORT_C static CVCCommandUi* NewL( const TDesC& aWrittenText, 
                const CVCFolderInfo& aFolderInfo, TBool aModifiable, 
                const TDesC& aTooltip, const TUid& aIconUid, 
                const TDesC& aUserText = KNullDesC,
                TBool aConfirmationNeeded = ETrue );
                
        /**
        * Factory function that constructs a CVCCommandUi from the stream
        * @leave KErrNotSupported if the stream data format is unsupported
        *        e.g. if it has been written by newer implementation
        */
        IMPORT_C static CVCCommandUi* NewL( RReadStream& aStream );
        
        /**
        * Copy the existing CVCCommandUi
        */
        IMPORT_C static CVCCommandUi* NewL( const CVCCommandUi& aOriginal );
                
        /** Destructor */
        IMPORT_C ~CVCCommandUi();

        /** 
		* Saves the command to stream.
		* Descriptor components are saved as <length><descriptor> pairs, where 
		* <length> is TInt32 and <descriptor> is the default descriptor represetation
		* TBools are saved as TInt32 either
		*/
		IMPORT_C void ExternalizeL( RWriteStream &aStream ) const;

        // Accessor methods
        
        /**
        * @return Unmodifiable written text
        */
        IMPORT_C const TDesC& WrittenText() const;
        
        /**
        * @return Unmodifiable user-specified shortcut for the command
        *         KNullDesC if none
        */
        IMPORT_C const TDesC& UserText() const;
        
        /**
        * @return Unmodifiable folder name
        */
        IMPORT_C const CVCFolderInfo& FolderInfo() const;
        
        /**
        * @return ETrue if the command is modifiable by user
        *         EFalse otherwise
        */
        IMPORT_C TBool Modifiable() const;
        
        /**
        * @return EFalse, if when the command is recognized,
        *         it is immediately executed
        *         ETrue, if when the command is recognized, it is played back and
        *         user is asked to confirm the recognition results
        * @see
        * @todo Add "see" reference to the recognition-side function that uses the
        *       "confirmation needed information"
        **/
        IMPORT_C TBool ConfirmationNeeded() const;
        
        /**
        * @return Unmodifiable extra text
        */
        IMPORT_C const TDesC& Tooltip() const;
        

        /**
        * @return global icon id
        * @todo AVKON-global? What kind of global?
        */ 
        IMPORT_C const TUid& IconUid() const;

	    /**
        * Creates the command icon. Takes into account the skin-specifics
	    * Works only if CEikonEnv is available
        * @return The command icon pushed to the cleanup stack
        */
	    IMPORT_C CGulIcon* IconLC() const;
        
        IMPORT_C TBool operator==( const CVCCommandUi& aCommandUi ) const;
        
        /**
         * Tells if all non user-changeable parts of aCommandUi are equal to this object's
         * @return ETrue if equal, EFalse otherwise
         */
        IMPORT_C TBool EqualNonUserChangeableData( const CVCCommandUi& aCommandUi ) const;
        
        
    private:
        /** 
        * Second-phase constructor 
        * @see NewL for guard conditions
        */
        void ConstructL( const TDesC& aWrittenText, 
                const CVCFolderInfo& aFolderInfo, TBool aModifiable, 
                const TDesC& aTooltip, const TUid& aIconUid, 
                const TDesC& aUserText, TBool aConfirmationNeeded );
                
        void ConstructL( RReadStream& aStream );
                
    private: // Data

        // Text shown on screen
        HBufC* iWrittenText;
        
        // User-specified alternative command text
        HBufC* iUserText;

        // Text shown on screen
        HBufC* iTooltip;

        // Folder-related details
        CVCFolderInfo* iFolderInfo;

        // Tells if this command is user modifiable
        TBool iUserCanModify;
        
        // Ask user to confirm the recognition result
        TBool iConfirmationNeeded;
        
        // global icon id
        /** @todo AVKON-global? What kind of global? */
        TUid iIconUid;
    };

/**
* Container for the information on how the command should be executed:
* 1) app uid OR exe filename; 2) optional command line arguments
*/    
class CVCRunnable : public CBase
    {
    public:
        /**
        * Factory function
        * @param aAppUid UID of the application to start. Cannot be KNullUidValue
        * @param aArguments Command line to pass to the application. This object makes
        *        a copy of the passed string
        * @leave KErrOverflow if aArguments is longer, than KMaxVCArgumentLength
        * @leave KErrArgument if aAppUid is KNullUidValue
        */
        IMPORT_C static CVCRunnable* NewL( TUid aAppUid, const TDesC8& aArguments = KNullDesC8 );
        
        /**
        * Factory function
        * @param aExeName Exe-file to start. Can be full or partical name according to 
        *        the RProcess::Create rules. Cannot be KNullDesC
        * @param aArguments Command line to pass to the application. This object makes
        *        a copy of the passed string
        * @leave KErrOverflow if aArguments is longer, than KMaxVCArgumentLength or 
        *		 aExeName is longer, than KMaxFileName
        * @leave KErrUndeflow if aExeName is empty
        */
        IMPORT_C static CVCRunnable* NewL( const TDesC& aExeName, 
        								   const TDesC8& aArguments = KNullDesC8 );
        
        /** 
        * Internalizes the object from stream 
        * @leave KErrNotSupported if the stream data format is unsupported
        *        e.g. if it has been written by newer implementation of CVCommandUi
        */
        IMPORT_C static CVCRunnable* NewL( RReadStream &aStream );
        
        /**
        * Copy the existing CVRunnable
        */
        IMPORT_C static CVCRunnable* NewL( const CVCRunnable& aOriginal );
        
        
        /** Destructor */
        IMPORT_C ~CVCRunnable();
        
        /** 
        * Run the command. In case of aAppUid specified during the construction
        * application is started via the RApaLsSession::StartApp, otherwise
        * via the RProcess::Create
        * @leave System-wide error code. In particular KErrNotFound if there is
        *        no such app in the system
        */
        IMPORT_C void ExecuteL() const;
        
        /** Saves the object to stream */
        IMPORT_C void ExternalizeL( RWriteStream &aStream ) const;

        /**
        * @return The uid of the application to be started. KNullUid if there is none
        */
        IMPORT_C const TUid Uid() const;
        
        /**
        * @return The filename of the application to be started. KNullDesC if there is none
        */
        IMPORT_C const TDesC& ExeName() const;
        
        /**
        * The arguments to be passed to the application. This object keeps
        * the ownership of the returned value
        */
        IMPORT_C const TDesC8& Arguments() const;
        
        IMPORT_C TBool operator==( const CVCRunnable& aRunnable ) const;
        
    private:
        void ConstructL( TUid aAppUid, const TDesC8& aArguments );
        void ConstructL( const TDesC& aExeName, const TDesC8& aArguments );
        void ConstructL( RReadStream& aStream );
        
    private:
        // UID of the application to be run, when the vcommand is recognized
        // KNullUidValue if none specified
        TUid iExeUid;
        
        // Filename to pass to RProcess::Create or NULL
        HBufC* iExeName;
        
        // Arguments string
        HBufC8* iArguments;
    };

/**
* The packaged VCommand storable/retriavable to/from VAS
*/
class CVCommand : public CBase
    {
    public:
        /**
        * Factory function. Create a const snapshop of exe-ui-vastext collection
        * @param aText Text to be trained by VAS. Can be of any length, however
        *        only first KNssVasDbTagName characters will be trained by VAS
        * @see KNssVasDbTagName in nssvasdbkonsts.h
        * @param aRunnable Executable to be fired when the command is recognized. 
        *        VCommand takes the ownership on the aRunnable
        * @param aUi visible strings to be displayed in VC App. VCommand takes 
        *        the ownership on the aUi
        */
        IMPORT_C static CVCommand* NewL( const TDesC& aText, const CVCRunnable& aRunnable, 
                                         const CVCCommandUi& aUi );
        
		/** 
        * Internalizes the command from stream 
        * @leave KErrNotSupported if the stream data format is unsupported
        *        e.g. if it has been written by newer implementation
        */
        IMPORT_C static CVCommand* NewL( RReadStream &aStream );
        
        /**
        * Copy the existing CVCommand
        */
        IMPORT_C static CVCommand* NewL( const CVCommand& aOriginal );
        
        /** Destructor */
        IMPORT_C ~CVCommand();
        
        /**
		* Saves the command to stream 
		* Format: <protocol version: int32><SpokenTextLength: int32><SpokenText descriptor>
		*         <runnable><commandui>
		*/
        IMPORT_C void ExternalizeL( RWriteStream &aStream ) const;
        
        /**
        * @return the Runnable component of the command
        */
        IMPORT_C const CVCRunnable& Runnable() const;

        /**
        * @return the UI-related component of the command
        */
        IMPORT_C const CVCCommandUi& CommandUi() const;
        
        /**
        * @return the text, that user is expected to pronounce
        *         It is different from the CVCommandUi::WrittenText
        */
        IMPORT_C const TDesC& SpokenText() const;
        
        /**
        * @return the user specified text, that user can pronounce to
        *         recognize the command. Is always identical to the 
        *         CVCommandUi::UserText()
        *         Can be KNullDesC
        *
        * @todo Responsibilities of SpokenText, AlternativeSpokenText,
        *       WrittenText and UserText are mixed. The source of problems
        *       is the fact that WrittenText can really be different from the
        *       default spoken text while User supplied text is always what's
        *       expected to be [alternatively] recognized
        *       A better structuring would be very welcome
        */
        IMPORT_C const TDesC& AlternativeSpokenText() const;
        
        /**
        * Asynchronous
        * Attempts to play back the text expected to be recognized. 
        * To be playable command has to be added to CVCommandHandler AND
        * then retrieved back
        *
        * @param aHandler CVCommandHandler where the command is stored
        * @todo Consider storing link to CVCommandHandler within the CVCommand (CStoredVCommand)
        *       Pros: No clumsy aHandler argument for the playback
        *       Pros: No need to remember in which handler the command is stored
        *             and why specifying storage is needed during the playback
        *       Cons: In case of internal link the linked handler should still
        *             exist. It cannot be e.g. destroyed and recreated later even
        *             if the latter one is using the same VAS
        *
        * @param aPlayEventHandler Entity that handles the playback callbacks
        * @see NssVasMPlayEventHandler.h
        *
        * @leave KErrBadHandle if the current command has not been retrieved 
        *        from CVCommandHandler (i.e. was not trained for recognition)
        * @leave KErrNotFound if this command cannot be found in aHandler
        * @leave KErrNotReady @see nssvasmspeechitem.h MNssSpeechItem::TNssSpeechItemResult 
        *                                              EVasUnexpectedRequest
        * @leave KErrInUse @see nssvasmspeechitem.h MNssSpeechItem::TNssSpeechItemResult 
        *                                              EVasInUse
        * @leave KErrArgument @see nssvasmspeechitem.h MNssSpeechItem::TNssSpeechItemResult 
        *                                              EVasInvalidParameter
        * @leave KErrGeneral @see nssvasmspeechitem.h MNssSpeechItem::TNssSpeechItemResult 
        *                                             EVasPlayFailed
        */
        IMPORT_C virtual void PlaySpokenTextL( const CVCommandHandler& aHandler, 
                                   MNssPlayEventHandler& aPlayEventHandler ) const;
        
        /**
        * Asynchronous
        * Plays back the user-specified alternative spoken text. 
        * Otherwise is identical to PlaySpokenTextL
        * @see PlaySpokenTextL
        * @leave KErrNotFound if this command cannot be found in aHandler of if 
        *        it doesn't have a user-specified text
        */ 
        IMPORT_C virtual void PlayAlternativeSpokenTextL( const CVCommandHandler& aHandler, 
                                   MNssPlayEventHandler& aPlayEventHandler ) const;
        
        /**
        * Cancels playback of a spoken or alternative spoken text
        * To be playable command has to be added to CVCommandHandler AND
        * then retrieved back. After this function neither HandlePlayStarted,
        * nor HandlePlayComplete will be called
        *
        * @param aHandler CVCommandHandler where the command is stored
        *
        * @leave KErrBadHandle if the current command has not been retrieved 
        *        from CVCommandHandler (i.e. was not trained for recognition)
        * @leave KErrNotReady if playback has never been started
        *
        */                                   
        IMPORT_C virtual void CancelPlaybackL( const CVCommandHandler& aHandler ) const;
        
        IMPORT_C TBool operator==( const CVCommand& aCommand ) const;
        
        /**
         * Tells if all non user-changeable parts of aCommand are equal to this command
         * @return ETrue if equal, EFalse otherwise
         */
        IMPORT_C TBool EqualNonUserChangeableData( const CVCommand& aCommand ) const;
        
    protected:
    	/**
    	* @leave KErrOverflow if aText is longer, than KMaxVCTextLength
    	*/ 
        void ConstructL( const TDesC& aText, const CVCRunnable& aRunnable, 
                         const CVCCommandUi& aUi );
        /**
        * @see NewL( RReadStream& aStream )
        */
        void ConstructL( RReadStream& aStream );
        
        /**
        * Clone itself
        * Is used for copying via NewL( CVCommand& aOriginal )
        * To be overridden by descendants
        */
        virtual CVCommand* CloneL() const; 

    private:
    	// Text to be recognized
        HBufC* iSpokenText;
        CVCRunnable* iRunnable;
        CVCCommandUi* iCommandUi;
        
    };
    
/** Array of pointers to CVCommands */
typedef RPointerArray<CVCommand> RVCommandArray;

/**
* Non-modifiable list of VCommands
*/
class CVCommandArray : public CBase
	{
	public:
		/** 
		* Constructs the non-modifiable CVCommandArray
		* @param aSource Commands to store. CVCommandArray makes
		*        copies of them
		*/
		IMPORT_C static CVCommandArray* NewL( const RVCommandArray& aSource );
		
		/**
		* Destructor
		*/
		IMPORT_C ~CVCommandArray();
		
		/**
		* Returns the reference to the command stored in this
		* CVCommandArray
		* @param aIndex Zero-based index of the command. If aIndex is out of
		*               bounds, this method will panic with USER 130
		* @return Unmodifiable reference to CVCommand
		*/
		IMPORT_C const CVCommand& At( TInt aIndex ) const;
		
		/**
		* Equivalent to the operator At
		* @see At()
		*/
		IMPORT_C const CVCommand& operator[]( TInt aIndex ) const;

		/** 
		* Returns the number of commands
		*/
		IMPORT_C TInt Count() const;
		
		/**
		* For the compatibility with routines, requiring RVCommandArray
		* @return Unmodifiable array of pointers to VCommands
		*/
		IMPORT_C const RVCommandArray& PointerArray() const;
        
        /**
         * Figures out which commands have to untrained (removed from the system)
         * if this command set is merged with aUpdates.
         * Merging is performed on the basis of comapring the commands' Runnable component
         * If runnables are equal, the commands are considered being equal.
         * It is useful e.g. when figuring out what to (un)train after the language change
         * 
         * @param aUpdates Set of commands to merge in. 
         * @return Set of commands to be removed from the system if the merging takes place
         * @see ProduceTrainSetByRunnables
         */
        IMPORT_C CVCommandArray* ProduceUntrainSetByRunnablesLC( 
                                    const RVCommandArray& aUpdates ) const;
        
        /**
         * Figures out which commands have to trained (removed added to the system)
         * if this command set is merged with aUpdates.
         * Merging is performed on the basis of comapring the commands' Runnable component
         * If runnables are equal, the commands are considered being equal.
         * It is useful e.g. when figuring out what to (un)train after the language change
         * 
         * @param aUpdates Set of commands to merge in. 
         * @return Set of commands to be added to the system if the merging takes place
         * @see ProduceUntrainSetByRunnables
         */
        IMPORT_C CVCommandArray* ProduceTrainSetByRunnablesLC( 
                                    const RVCommandArray& aUpdates ) const;
		
	private:
		void ConstructL( const RVCommandArray& aSource );

	private:
		RVCommandArray iCommands;
	};

/**
 * Allows the CVCommandHandler clients be notified about the vcommand set
 * changes by another instances of the CVCommandHandler
 */
class MVCommandHandlerObserver 
	{
	public:
		/**
		* Is called whenever the VCommand set is changed
    	* by *another* instance of CVCommandHandler. I.e. lets the client know if
    	* his understanding of the VCommand set is up to date
    	*/
		virtual void CommandSetChanged() = 0;
	};

/**
* Provider of the voice command services
*/
class CVCommandHandler : public CBase
    {
    public:
    	/** 
    	* Factory function
    	* @param aObserver Listener to be notified whenever the VCommand set is changed
    	* 		 by *another* instance of CVCommandHandler. I.e. lets the client know if
    	* 		 his understanding of the VCommand set is up to date
    	*/ 
    	IMPORT_C static CVCommandHandler* NewL(  MVCommandHandlerObserver* aObserver = NULL );
    	
        IMPORT_C virtual ~CVCommandHandler();

        /**
        * Synchronous. Service doesn't take the ownership, but makes an own copy
        * Duplicates can be added
        * @todo should we check for duplicates and leave with KErrAlreadyExists?
        */
        IMPORT_C virtual void AddCommandL( const CVCommand& aCommand );
        
        /**
        * Synchronous. Service doesn't take the ownership, but makes an own copies
        * Duplicates can be added
        * @todo should we check for duplicates and leave with KErrAlreadyExists?
        * @param aCommands Commands to add
        * @param aIgnoreErrors If ETrue, even if some commands fail to be trained,
        *        handler adds all that are trainable
        */
        IMPORT_C virtual void AddCommandsL( const RVCommandArray& aCommands, 
                                            TBool aIgnoreErrors = EFalse );
        
        /**
        * Synchronous. Removes the command from the system
        * @param aCommand Reference to the command to be removed. Existing commands are
        *		 compared against aCommand. All the matches are removed from VAS
        * @leave KErrNotFound No such command
        */
        IMPORT_C virtual void RemoveCommandL( const CVCommand& aCommand );

        /**
        * Synchronous. 
        * @param aCommands Reference to the list of commands to be removed. Existing commands are
        *		 compared against aCommands items. All the matches are removed from VAS
        * @param aIgnoreErrors If ETrue, even if some commands fail to be removed,
        *        handler will remove as many as possible
        */
        IMPORT_C virtual void RemoveCommandsL( const RVCommandArray& aCommands, 
				      TBool aIgnoreErrors = EFalse );

        
        /**
        * Synchronous
        * @return an array of the commands in the system
        *         Ownership of the array is transfered to the client
        *         The returned CVCommandArray contains copies of all the 
        *         commands currently stored in this handler
        */
        IMPORT_C virtual CVCommandArray* ListCommandsL();
        
        /**
        * Not intented to be called directly.
        * @see CVCommand::PlaySpokenTextL
        */
        virtual void PlaySpokenTextL( const CStoredVCommand& aCommand, 
                                   MNssPlayEventHandler& aPlayEventHandler ) const;
        
        /**
        * Not intented to be called directly.
        * @see CVCommand::PlayAlternativeSpokenTextL
        */                                   
        virtual void PlayAlternativeSpokenTextL( const CStoredVCommand& aCommand, 
                                   MNssPlayEventHandler& aPlayEventHandler ) const;
                                   
        /**
        * Not intented to be called directly.
        * @see CVCommand::CancelPlaybackL
        */                                   
        virtual void CancelPlaybackL( const CStoredVCommand& aCommand ) const;
        
    private:
    	void ConstructL( MVCommandHandlerObserver* aObserver );
    	// Implementation of the VCommand API
    	MVCService* iImpl;
    };
    
#endif // VCOMMANDAPI_H