srsf/vcommandmanager/src/vcommandmanager.cpp
branchRCL_3
changeset 23 e36f3802f733
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srsf/vcommandmanager/src/vcommandmanager.cpp	Wed Sep 01 12:29:17 2010 +0100
@@ -0,0 +1,413 @@
+/*
+* Copyright (c) 2005-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:  VCommandManager application which is started during boot. 
+*
+*/
+
+
+// INCLUDE FILES
+#include "rubydebug.h"
+
+#include <centralrepository.h>
+
+#include "srsfprivatecrkeys.h"
+#include <menu2internalcrkeys.h>
+#include <f32file.h>
+#include "vcommandmanager.h"
+#include "vcxmlparser.h"
+#include "vcommandmerger.h"
+
+// CONSTANTS
+_LIT( KPrivateSubDirectory, "import\\" );
+_LIT( KFileFilter, "*.xml" );
+
+//static const TInt KUndefinedLanguage = -1;
+
+
+// -----------------------------------------------------------------------------
+// CVCommandManager::CVCommandManager
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CVCommandManager::CVCommandManager( TBool aForceRetrain )
+ : iCommands(), iMatchingIndices(), iLanguageChanged( aForceRetrain )
+    {
+    // Nothing
+    }
+
+// -----------------------------------------------------------------------------
+// CVCommandManager::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CVCommandManager::ConstructL()
+    {
+    User::LeaveIfError( iRFs.Connect() );
+    
+    iParser = CVcXmlParser::NewL( iRFs, *this );
+    
+    // Create service object
+    CVCommandHandler* service = CVCommandHandler::NewL();
+    CleanupStack::PushL( service );
+    
+    ParseAllFilesL();
+    
+    // Get all existing commands from VCommandHandler
+    iCommandArray = service->ListCommandsL();
+
+    CVCommandMerger* merger = CVCommandMerger::NewLC();
+    CVCommandArray* deduction = merger->ProduceDeductionByRunnablesLC( *iCommandArray, iCommands );
+    CVCommandArray* addition = merger->ProduceAdditionByRunnablesLC( *iCommandArray, iCommands );
+    
+    service->RemoveCommandsL( deduction->PointerArray(), ETrue );
+    service->AddCommandsL( addition->PointerArray(), ETrue );
+    
+    CleanupStack::PopAndDestroy( addition );
+    CleanupStack::PopAndDestroy( deduction );
+    CleanupStack::PopAndDestroy( merger );
+    CleanupStack::PopAndDestroy( service );
+    }
+
+// -----------------------------------------------------------------------------
+// CVCommandManager::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CVCommandManager* CVCommandManager::NewL( TBool aForceRetrain )
+    {
+    CVCommandManager* self = new ( ELeave ) CVCommandManager( aForceRetrain );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CVCommandManager::ParseAllFilesL
+// Goes through directories and parses all xml files.
+// -----------------------------------------------------------------------------
+//
+void CVCommandManager::ParseAllFilesL()
+    {
+    RUBY_DEBUG_BLOCK( "CVCommandManager::ParseAllFilesL" );
+        
+    TDriveList drivelist;
+    User::LeaveIfError( iRFs.DriveList( drivelist ) ); 
+
+    for ( TInt drive( EDriveA ); drive <= EDriveZ; drive++ )
+        {
+        if ( drivelist[drive] ) 
+            {
+            TChar driveLetter; 
+			User::LeaveIfError( iRFs.DriveToChar( drive, driveLetter ) );
+
+            TFileName directory;
+            iRFs.PrivatePath( directory );
+            directory.Insert( 0, _L(" :"));
+            directory[0] = driveLetter; // replace " " with a drive letter
+            
+            // parse files from private directory
+            ParseAllFilesFromDirectoryL( directory );
+            
+            // parse filer from import directory
+            directory.Append( KPrivateSubDirectory );
+            ParseAllFilesFromDirectoryL( directory );    
+            
+            }
+        }
+    }
+    
+
+    
+// -----------------------------------------------------------------------------
+// CVCommandManager::ParseAllFilesFromDirectoryL
+// Goes through directory and parses all xml files.
+// -----------------------------------------------------------------------------
+//
+void CVCommandManager::ParseAllFilesFromDirectoryL( const TDesC& aDirectory )
+    {
+    RUBY_DEBUG_BLOCK( "CVCommandManager::ParseAllFilesFromDirectoryL" );
+    
+    CDir* dirContents = NULL;
+
+    TFileName searchPath( aDirectory );
+    searchPath.Append( KFileFilter );
+    
+    RUBY_DEBUG1( "CVCommandManager::ParseAllFilesFromDirectoryL - Search path: [%S]", &searchPath );
+    
+    TInt error = iRFs.GetDir( searchPath, KEntryAttMatchMask, ESortNone, dirContents );   
+    if ( error == KErrNone )
+        {        
+        CleanupStack::PushL( dirContents );
+        
+        RUBY_DEBUG1( "CVCommandManager::ParseAllFilesFromDirectoryL - Found %d xml-file(s)", dirContents->Count() );
+
+        // Go through all found xml files
+        for ( TInt iCounter = 0; iCounter < dirContents->Count(); iCounter++ )
+            {
+            TEntry entry = (*dirContents)[iCounter];
+            if ( !entry.IsDir() )
+                {
+                TFileName filename( aDirectory );
+                filename.Append( entry.iName );                
+                
+                TRAPD( error, iParser->ParseFileL( filename ) );
+                if ( error )
+                    {
+                    // Reset parser if an error occurs
+                    delete iParser;
+                    iParser = NULL;
+                    
+                    iParser = CVcXmlParser::NewL( iRFs, *this );
+                    }
+                }
+            }
+         
+        CleanupStack::PopAndDestroy( dirContents );    
+        }
+    else
+        {
+        RUBY_DEBUG1( "CVCommandManager::ParseAllFilesFromDirectoryL - GetDir returns [%d]", error );
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CVCommandManager::CompareCommands
+// Compares if two commands are equal
+// -----------------------------------------------------------------------------
+//  
+TBool CVCommandManager::CompareCommands( const CVCommand* aFirst, const CVCommand* aSecond )
+    {
+    TBool result = EFalse;
+        
+    if ( aFirst && aSecond )
+        {
+        result = aFirst->Runnable() == aSecond->Runnable();
+        }
+    
+    return result;
+    }
+    
+// -----------------------------------------------------------------------------
+// CVCommandManager::~CVCommandManager
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CVCommandManager::~CVCommandManager()
+    {
+    delete iParser;
+//    delete iClient;
+    delete iCommandArray;
+    
+    iCommands.ResetAndDestroy();
+    iMatchingIndices.Close();
+    
+    iRFs.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CVCommandManager::VCMThreadFunction
+// Static main function for Voice Command Manager thread
+// -----------------------------------------------------------------------------
+//    
+TInt CVCommandManager::VCMThreadFunction( TAny* /*aParams*/ )
+    {
+    __UHEAP_MARK;
+    
+    // CleanupStack creation
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+
+    CActiveScheduler* scheduler = NULL;
+    
+    TInt error = KErrNone;
+    
+    TRAP( error, 
+
+        // ActiveScheduler creation
+        scheduler = new ( ELeave ) CActiveScheduler();
+        
+        CleanupStack::PushL( scheduler );
+
+        CActiveScheduler::Install( scheduler );
+        
+        TSecureId sid = RThread().SecureId();
+        RUBY_DEBUG1( "VCommandManager secure id [%x]", sid.iId );
+        
+        // Create VCommandManager
+        CVCommandManager* vcmanager = CVCommandManager::NewL( EFalse );
+        delete vcmanager;
+
+        CleanupStack::PopAndDestroy( scheduler ); 
+    ); // TRAP
+    
+    delete cleanupStack;
+    
+    __UHEAP_MARKEND;
+    
+    RUBY_DEBUG0( "CVCommandManager::VCMThreadFunction finished ok" );
+    
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// CVCommandManager::ConstructCommandL
+// Constructs new command with given data
+// -----------------------------------------------------------------------------
+//      
+void CVCommandManager::ConstructCommandL( const TDesC& aWrittenText,
+                                          const TDesC& aSpokenText,
+                                          const TDesC& aTooltipText,
+                                          const TDesC& aFolder,
+                                          const TDesC& aFolderTitle,
+                                          const TDesC& aParameters, 
+                                          TUid aIcon,
+                                          TUid aAppId,
+                                          const TDesC& aAppName,
+                                          TBool aStartImmediately,
+                                          TBool aUserCanModify,
+                                          const TDesC& aFolderIconFile,
+                                      	  TInt aFolderIconIndex
+                                           )
+    {
+    const TInt KCenRepBufferSize = 255;
+
+    RUBY_DEBUG_BLOCKL( "CVCommandManager::ConstructCommandL" );
+    
+    RUBY_DEBUG1( "CVCommandManager::ConstructCommandL - Creating command: [%S]", &aWrittenText );    
+    
+    // First check that if the application is hidden so voice command is not created then
+    if ( aAppId != KNullUid )
+    	{
+    	
+	    TBuf<KCenRepBufferSize> buf;
+	    CRepository* cenRepSession = CRepository::NewLC( KCRUidMenu );
+	    cenRepSession->Get( KMenuHideApplication, buf );
+	    CleanupStack::PopAndDestroy( cenRepSession );
+
+		buf.LowerCase();
+	    TBuf<8> textUidHex;
+	    textUidHex.AppendNumFixedWidth( aAppId.iUid, EHex, 8 );    
+	    if ( buf.Find( textUidHex ) != KErrNotFound )
+	    	{
+	    	// hidden application: no voice tag needed
+	    	RUBY_DEBUG1( "%S hidden application", &aWrittenText );  
+	    	return;
+	    	}
+        }
+        	    
+	HBufC8* arguments = HBufC8::NewL( aParameters.Length() );
+	CleanupStack::PushL( arguments );
+	TPtr8 argumentsPtr = arguments->Des();
+	argumentsPtr.Copy( aParameters );        
+
+            
+    // Create runnable object
+    CVCRunnable* runnable = NULL;        
+    if ( aAppId != KNullUid )
+        {
+        runnable = CVCRunnable::NewL( aAppId, argumentsPtr );
+        }
+    else
+        {
+        runnable = CVCRunnable::NewL( aAppName, argumentsPtr );
+        }
+    CleanupStack::PushL( runnable );
+    
+    CVCFolderInfo* folderInfo = CVCFolderInfo::NewL( aFolderTitle, aFolder, 0, 
+    												 aFolderIconIndex, aFolderIconFile );
+    CleanupStack::PushL( folderInfo );
+    // Create commandUi object
+    CVCCommandUi* commandUi = CVCCommandUi::NewL( aWrittenText,
+                                                  *folderInfo,
+                                                  aUserCanModify,
+                                                  aTooltipText,
+                                                  aIcon,
+                                                  KNullDesC,
+                                                  !aStartImmediately );
+    CleanupStack::PopAndDestroy( folderInfo );
+    CleanupStack::PushL( commandUi );
+       
+    // Create command object
+    CVCommand* command = CVCommand::NewL( aSpokenText, *runnable, *commandUi );
+        
+    TBool found = EFalse;
+      
+    // Check that identical command has not already been found from some xml-file
+    for ( int i = 0; i < iCommands.Count(); ++i )
+        {
+        if ( CompareCommands( iCommands[ i ], command ) )
+            {
+            found = ETrue;
+            break;
+            }            
+        }
+        
+    // Add command if not found already
+    if ( !found )
+        {
+        iCommands.Append( command );
+        iMatchingIndices.Append( KErrNotFound );
+        }
+    else
+        {
+        delete command;
+        }
+        
+    CleanupStack::PopAndDestroy( commandUi ); 
+    CleanupStack::PopAndDestroy( runnable ); 
+    CleanupStack::PopAndDestroy( arguments );    
+    }
+    
+// -----------------------------------------------------------------------------
+// CVCommandManager::MvcxpoVoiceCommandFound
+// Callback from VC XML parser
+// -----------------------------------------------------------------------------
+//        
+void CVCommandManager::MvcxpoVoiceCommandFound( const TDesC& aWrittenText,
+                                                const TDesC& aSpokenText,
+                                                const TDesC& aTooltipText,
+                                                const TDesC& aFolder,
+                                                const TDesC& aFolderTitle,
+                                                const TDesC& aParameters, 
+                                                TUid aIcon,
+                                                TUid aAppId,
+                                                const TDesC& aAppName,
+                                                TBool aStartImmediately,
+                                                TBool aUserCanModify,
+                                                const TDesC& aFolderIconFile,
+		                                        TInt aFolderIconIndex
+                                                 )
+    {
+    RUBY_DEBUG0( "CVCommandManager::MvcxpoVoiceCommandFound START" );
+    
+    TRAP_IGNORE( ConstructCommandL( aWrittenText,
+                                    aSpokenText,
+                                    aTooltipText,
+                                    aFolder,
+                                    aFolderTitle,
+                                    aParameters,
+                                    aIcon,
+                                    aAppId,
+                                    aAppName,
+                                    aStartImmediately,
+                                    aUserCanModify,
+                                    aFolderIconFile,
+                                    aFolderIconIndex ) );
+      
+    RUBY_DEBUG0( "CVCommandManager::MvcxpoVoiceCommandFound EXIT" );
+    }
+                                      
+// End of File
+