homescreenpluginsrv/hspsmanager/tools/hspsthemeinstallercons.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:54:17 +0200
changeset 0 79c6a41cd166
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2004,2008 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:
*
*/


#include "hspsthemeinstallercons.h"
#include <e32svr.h>
#include <flogger.h>
#include <f32file.h>
#include "hspsthememanagement.h"
#include <e32base.h>
#include <bacline.h>
#include <bautils.h>

#include "hspsodt.h"
#include "hspsclient.h"

_LIT(KDATFileExtension,".dat");
_LIT(KLogFile,"hspsthemeinstallercons.log");
_LIT(KLogFolder,"hspsthemeinstallercons");
_LIT(KLogFilePath,"c:\\logs\\hspsthemeinstallercons\\hspsthemeinstallercons.log");
_LIT(KThemeSourcePath,"c:\\data\\installs\\test\\");
_LIT(KDefaultInput, "install.dat");

#define _WRITELOG(aDescription) RFileLogger::Write( KLogFolder,KLogFile,EFileLoggingModeOverwrite,	aDescription );   
#define _WRITE_ERRORLOG(aErrCode) WriteErrorLog(aErrCode);   



class CThemeInstaller:public CBase, public MhspsThemeManagementServiceObserver
    {
    public:
    	~CThemeInstaller();
        static CThemeInstaller* NewL(TInt aAppUid);
        static CThemeInstaller* NewLC(TInt aAppUid);
        void StartL();
	
	private:
    	void InstallThemeL(const TDesC& aManifestFileName);
    	void InstallFilesL(CDesCArraySeg& aManifestFile);
    	void GetFilesL(RFs& aFs, CDesCArraySeg& aFileList, const TDesC& aDirectory);
        void DeleteDirL(RFs& aFs, const TDesC& aDir);
    	void HandlehspsClientMessage(ThspsServiceCompletedMessage aMessage);
        void ConstructL(TInt aAppUid);
        void GetDirectoriesL(
        		RFs& aFs,
        		TPtrC aPath,
        		TPtrC aPluginsFile,
        		CDesCArrayFlat& aDirectoryList );
        void InstallFilesFromL( 
        		RFs& aFs,        		
        		TPtrC aDirectory );
    private:
        TBuf8<KMaxHeaderDataLength8> iHeaderData;
        TRequestStatus iStatus;
        ChspsClient *ihspsClient;
        ChspsResult* iResult;
        TInt iConvertedResourceCount;
        ChspsODT* iHeader;
        TInt iListCount;
        CDesCArraySeg* iThemeList;
        TInt iAppUid;
    };

CThemeInstaller* themeinstaller;
CActiveScheduler* scheduler;





// -----------------------------------------------------------------------------
// E32Main
// -----------------------------------------------------------------------------
//
GLDEF_C TInt E32Main() // main function called by E32
    {
	CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
	TRAPD( error, startupL() ); // more initialization, then do example
	
	delete scheduler;
	delete themeinstaller;
	delete cleanup; // destroy clean-up stack
			
	// Forward errors to be catched with ERRORLEVEL method in batch files
	return error; // and return
    }
    
// -----------------------------------------------------------------------------
// WriteErrorLog
// 
// Writes error to log
// -----------------------------------------------------------------------------
//
void WriteErrorLog(TInt error)
    {
    if (error == ENoFilesNotFound)
        {
         _WRITELOG( _L("ERROR::Theme files not found") ); 
        }
    else if (error == EErrorDeletingDir)
        {
         _WRITELOG( _L("ERROR::Could not delete themes") ); 
        }
    else if (error == EErrorDirNotExists)
        {
         _WRITELOG( _L("ERROR::Source directory does not exist") ); 
        }
    else
        {
         _WRITELOG( _L("ERROR::Unknown error") ); 
        }
    }
 
 
// -----------------------------------------------------------------------------
// startup
// 
// 
// -----------------------------------------------------------------------------
//
void startupL()
    {    
    TInt errorCode = KErrNone;   
     
    // Start active scheduler
    scheduler = new ( ELeave ) CActiveScheduler;
    CleanupStack::PushL( scheduler );
    CActiveScheduler::Install( scheduler );

    TUid appuid = KUidhspsThemeInstallerCons;
    themeinstaller = CThemeInstaller::NewL( appuid.iUid );
    CleanupStack::PushL( themeinstaller );
     
    TRAP( errorCode, themeinstaller->StartL() );
    
    _WRITELOG( _L("") );
    
    if( errorCode )
        {
	    _WRITE_ERRORLOG( errorCode );
	    _WRITELOG( _L("Failed to start an installation!") );    
	    }

		_WRITELOG( _L("Installer done") );
    
    CleanupStack::Pop( themeinstaller );
    CleanupStack::Pop( scheduler );
     
    User::LeaveIfError( errorCode );     
    }
    
// -----------------------------------------------------------------------------
// CThemeInstaller::NewL()
// 
// 
// -----------------------------------------------------------------------------
//
CThemeInstaller* CThemeInstaller::NewL( TInt aAppUid )
    {    
    CThemeInstaller* self = NewLC( aAppUid );
    CleanupStack::Pop( self );
    return( self );    
    }

// -----------------------------------------------------------------------------
// CThemeInstaller::NewLC()
// 
// 
// -----------------------------------------------------------------------------
//
CThemeInstaller* CThemeInstaller::NewLC( TInt aAppUid )
    {    
    CThemeInstaller* self = new ( ELeave ) CThemeInstaller();
    CleanupStack::PushL( self );
    self->ConstructL( aAppUid );
    return self;    
    }

// -----------------------------------------------------------------------------
// CThemeInstaller::ConstructL()
// 
// 
// -----------------------------------------------------------------------------
//
void CThemeInstaller::ConstructL( TInt aAppUid )
    {
    iResult = ChspsResult::NewL();
  	ihspsClient = ChspsClient::NewL( *this );
  	iHeader = NULL;
  	iListCount = 0;
  	iConvertedResourceCount = 0;
  	iAppUid = aAppUid;
  	iThemeList = NULL;  	
    }
   
// -----------------------------------------------------------------------------
// CThemeInstaller::~CThemeInstaller()
// 
// 
// -----------------------------------------------------------------------------
//
CThemeInstaller:: ~CThemeInstaller()
    {    
    delete ihspsClient;
    delete iResult;
    delete iHeader;
    delete iThemeList;   
    }
     
// -----------------------------------------------------------------------------
// Gets program arguments and starts the installer
// -----------------------------------------------------------------------------
//
void CThemeInstaller::StartL()
    {    
    // Init
    RFs fs;           
    User::LeaveIfError( fs.Connect() );
    CleanupClosePushL( fs );
    
    // Set logging
    fs.MkDirAll( KLogFilePath );
    _WRITELOG(_L("Starting installer"));
                       
    // Check arguments
    CCommandLineArguments* args = CCommandLineArguments::NewLC();
    TInt argsCount = args->Count();
    TPtrC inputFile;    
    const TInt firstArgIndex = 2;
    if ( argsCount < firstArgIndex )
        {
        _WRITELOG(_L("Missing an argument!"));
//        User::LeaveIfError( KErrArgument );        
        inputFile.Set( KDefaultInput );
        }
    else
        {
        inputFile.Set( args->Arg(1) );        
        }
    
    // Setup an array for directory names
    const TInt KGranularity = 10;
    CDesCArrayFlat* directoryList = new ( ELeave ) CDesCArrayFlat( KGranularity );
    CleanupStack::PushL( directoryList );
            
    // Get directory names
    GetDirectoriesL( fs, KThemeSourcePath().Ptr(), inputFile, *directoryList );        
        
    // Install manifest files from the directories
	TInt count = directoryList->MdcaCount();
	for( TInt i=0; i<count; i++ )
		{				
		TPtrC dirPtr( directoryList->MdcaPoint(i) );		
		InstallFilesFromL( fs, dirPtr );
		}
	    
    CleanupStack::PopAndDestroy( 3, &fs ); // directoryList, args, Fs   
    }

// -----------------------------------------------------------------------------
// Installs a new configuration from the provided manifest file.
// -----------------------------------------------------------------------------
//
void CThemeInstaller::InstallFilesFromL( 
		RFs& aFs,
		TPtrC aDirectory )
	{
	TInt errorCode = EErrorDirNotExists;
	
    // Check if the dir exists
    BaflUtils baf;
    if( baf.PathExists( aFs, aDirectory ) )
        {
        errorCode = KErrNone;
        
        // Setup an array for manifests (member variable)
        if ( iThemeList )
        	{
        	delete iThemeList;
        	iThemeList = NULL;
        	}
        iThemeList = new( ELeave ) CDesCArraySeg( KArrGranularity );        
                
        // Get manifests located at the directory
        GetFilesL( aFs, *iThemeList, aDirectory );
        if( iThemeList->Count() > 0 )
            {
            // Install first manifest
       	    InstallThemeL( iThemeList->MdcaPoint( 0 ) );       	           	    
       	 
       	    // Handle asynch messages
       	    scheduler->Start();       	    
            }
        else
            {
            errorCode = ENoFilesNotFound;
            }                   
        }
                 
    User::LeaveIfError( errorCode );
    }
     
// -----------------------------------------------------------------------------
// Reads directory names from the input file and appends names into the provided array
// -----------------------------------------------------------------------------
//
void CThemeInstaller::GetDirectoriesL(
		RFs& aFs,
		TPtrC aPath,
		TPtrC aPluginsFile,
		CDesCArrayFlat& aDirectoryList )
	{			
	TFileName directoryFile;
	directoryFile.Copy( aPath );        
	directoryFile.Append( aPluginsFile );
	
	// Convert into a 8-bit descriptor
	_LIT8(KLogPrefix, "Reading directory names from the " );
	_LIT8(KLogSuffix, " file.." );
	const TInt lineLength = KLogPrefix().Length() + directoryFile.Length() + KLogSuffix().Length();
	HBufC8* line = HBufC8::NewLC(lineLength );
	TPtr8 linePtr( line->Des() );	
	linePtr.Append( KLogPrefix ); 	
	linePtr.Append( directoryFile );
	linePtr.Append( KLogSuffix );	
	_WRITELOG( linePtr );
	CleanupStack::PopAndDestroy( line );
	line = NULL;
	
	// Check if the f exists
    BaflUtils baf;
    if( !baf.FileExists( aFs, directoryFile ) )
    	{
    	_WRITELOG(_L("File not found!"));
    	User::LeaveIfError( KErrNotFound );
    	}
		
	// Open a file handle
	RFile file;
	User::LeaveIfError( file.Open(aFs, directoryFile, EFileRead|EFileShareReadersOnly) );
	CleanupClosePushL(file);
	
	// Get size of the file
    TInt fileSize;
    User::LeaveIfError( file.Size(fileSize) );
        
    // Get file content
    HBufC8* buf8 = HBufC8::NewLC( fileSize );    
    TPtr8 ptr8( buf8->Des() );
    User::LeaveIfError( file.Read(ptr8) );
    
    // Convert from a 8bit to 16bit descriptor
    HBufC16* buf16 = HBufC16::NewLC( ptr8.MaxLength() );
    TPtr16 ptr16 = buf16->Des();
    ptr16.Copy( ptr8 );
           
    // Parse directories from the string    
    TInt offset = 0;
    _LIT(KLineSeperator, "\r\n");
    _LIT(KDirectorySuffix, "\\");
    do     
    	{
    	offset = ptr16.Find( KLineSeperator );
    	TPtrC ptr;
    	if ( offset < 1 )
    		{
    		ptr.Set( ptr16 );
    		}
    	else
    		{
    		ptr.Set( ptr16.Left( offset ) );
    		}    	
    	if ( ptr.Length() )
    		{
	    	HBufC* nameBuf = HBufC::NewLC( aPath.Length() + ptr.Length() + KDirectorySuffix().Length() );
	    	TPtr fullPtr( nameBuf->Des() );
	    	fullPtr.Copy( aPath );
	    	fullPtr.Append( ptr );
	    	fullPtr.Append( KDirectorySuffix );
	    	aDirectoryList.AppendL( fullPtr );
	    	CleanupStack::PopAndDestroy( nameBuf );
    		}
    	if ( offset > 0 )
    		{
    		ptr16 = ptr16.Mid( offset + KLineSeperator().Length() );
    		}
    	}
    while ( offset > 0 );    
           
    // Cleanup
    CleanupStack::PopAndDestroy( buf16 ); 
    CleanupStack::PopAndDestroy( buf8 );
    CleanupStack::PopAndDestroy( ); // file              
	}

// -----------------------------------------------------------------------------
// Deletes theme installation path
// -----------------------------------------------------------------------------
//
void CThemeInstaller::DeleteDirL( RFs& aFs, const TDesC& aDir )
    {    
    _WRITELOG( _L("Deleting existing themes") );
    
    HBufC* path = HBufC::NewLC( KMaxFileName );
    TPtr pathPtr = path->Des();
    pathPtr.Append( aDir );
    
    CFileMan* fileMan = CFileMan::NewL( aFs );
    CleanupStack::PushL( fileMan );
    TInt err = fileMan->RmDir( pathPtr );
    
    CleanupStack::PopAndDestroy( fileMan );
    CleanupStack::PopAndDestroy( path );
    
    if( err )
        {
        _WRITE_ERRORLOG( EErrorDeletingDir );  
        }  
    }

// -----------------------------------------------------------------------------
// Searches for theme files from path and adds them to list
// -----------------------------------------------------------------------------
//
void CThemeInstaller::GetFilesL( RFs& aFs, CDesCArraySeg& aFileList, const TDesC& aDirectory )
    {
    CDir* dirList;
    User::LeaveIfError( aFs.GetDir( aDirectory,
                       KEntryAttMaskSupported, ESortByDate, dirList ) );
                       
    CleanupStack::PushL( dirList );                   
                       
    for( TInt i = 0; i < dirList->Count(); i++ )
        {
        if ( !( *dirList )[i].IsDir() )
            {
            HBufC* path = HBufC::NewLC( aDirectory.Length() + ( *dirList )[i].iName.Length() );
            TPtr pathPtr = path->Des();
            pathPtr.Copy( aDirectory );
            TEntry  entry = ( *dirList )[i];
            pathPtr.Append( entry.iName );                
            TParse p;
            p.Set( pathPtr, NULL, NULL );
            
            if ( p.Ext().CompareF( KDATFileExtension ) == 0 )
              	{
                aFileList.AppendL( pathPtr );
        	    }
            
            CleanupStack::PopAndDestroy( path );  
            }
        }
    
    CleanupStack::PopAndDestroy( dirList );
    }
    
// -----------------------------------------------------------------------------
// Initiates installing of a confgiruation from the provided manifest file
// -----------------------------------------------------------------------------
//
void CThemeInstaller::InstallThemeL( const TDesC& aManifestFileName )
    {      	
    
    TBuf<KMaxHeaderDataLength8> tmp;
    _WRITELOG(_L(""));
    tmp.Format( _L("Manifest: %S"), &aManifestFileName );
	_WRITELOG(tmp);
    
	if ( iHeader )
		{
		delete iHeader;
		iHeader = NULL;
		}			
	iHeader = ChspsODT::NewL();
    
	TParse p;
    p.Set( aManifestFileName, NULL, NULL );
    TPtrC ptr = p.NameAndExt();
    
	ThspsServiceCompletedMessage ret = ihspsClient->hspsInstallTheme( aManifestFileName, *iHeader );
	
	if( ret == EhspsInstallThemeSuccess )
		{
		ihspsClient->GethspsResult( *iResult );
 		}
	else if( ret == EhspsInstallPhaseSuccess )
		{
		ihspsClient->GethspsResult( *iResult );
		iConvertedResourceCount = 0;
	
  		tmp.Format( _L("Installing ..") );
  		_WRITELOG(tmp);
		ihspsClient->hspsInstallNextPhaseL( *iHeader );
		}
	else if( ret == EhspsInstallThemeFailed )
    	{
    	ihspsClient->GethspsResult(*iResult);
    	TBuf<KMaxHeaderDataLength8> tmp2; 
    	TInt syserr = iResult->iSystemError;
    	TInt hspserr = iResult->iXuikonError;
    	tmp.Format(_L("Installation of \'%S\' failed. System error: %d, HSPS error: %d."), &ptr, syserr, hspserr );
    	_WRITELOG(tmp);    	    	
    	User::Leave( KErrGeneral );
    	}
    else if( ret == EhspsServiceNotSupported )
    	{
    	_WRITELOG(_L("EhspsServiceNotSupported"));
    	}
    else if( ret == EhspsServiceRequestError )
    	{
    	_WRITELOG(_L("EhspsServiceRequestError"));
    	}
    else if( ret == EhspsServiceRequestCanceled )
    	{
    	_WRITELOG(_L("EhspsServiceRequestCanceled"));
    	}
    else
    	{
    	tmp.Format(_L("Undefined response: %d"), ret); 
    	_WRITELOG(tmp);
    	}         
    } 

// -----------------------------------------------------------------------------
// CThemeInstaller::HandlehspsClientMessage()
// 
// Handles events received from themeserver via hspsClient
// -----------------------------------------------------------------------------

void CThemeInstaller::HandlehspsClientMessage(ThspsServiceCompletedMessage aEvent)
	{
    TInt errorCode = KErrNone;
	
	TBuf<KMaxHeaderDataLength8> tmp;
	ihspsClient->GethspsResult(*iResult);
    
    if( aEvent == EhspsInstallThemeSuccess )
		{
   		iListCount++;

   		if ( iListCount < iThemeList->MdcaCount() )
			{
			TRAP( errorCode, InstallThemeL( iThemeList->MdcaPoint( iListCount ) ) );

			if( errorCode )
				{
				tmp.Format( _L("InstallThemeL() failed...") );
				_WRITELOG( tmp );
				}
			}
		else
		    {
            scheduler->Stop();
		    }
   		}   
	else if( aEvent == EhspsInstallPhaseSuccess )
	    {
	    
		TBuf<KMaxHeaderDataLength8> tmp;
		
		if( iResult->iIntValue1 == EhspsPhaseCleanup )
			{
			tmp.Format(_L("Removing previous configuration .."));
			}
		else if( iResult->iIntValue1 == EhspsPhaseInstallSkeleton )
			{
			tmp.Format(_L("Installing a new configuration .."));
			}		
		else
			{
			tmp.Format(_L("Processing phase %d .."), iResult->iIntValue1 );
			}
			
		_WRITELOG(tmp);
 		
 		} 
 	else if( aEvent == EhspsInstallThemeFailed )
		{

    	TBuf<KMaxHeaderDataLength8> tmp2; 
    	TInt syserr = iResult->iSystemError;
    	TInt hspserr = iResult->iXuikonError;
    	TInt defengerr = iResult->iIntValue1;
    	TInt subcomperr = iResult->iIntValue2;
 		  tmp.Format(_L("Installation of /'%S/' failed. Sys.err: %d, hsps.err: %d, Def.eng.err: %d, subcomp.err: %d."), 
 		              &iHeader->ThemeFullName(), syserr, hspserr, defengerr, subcomperr );
 		  _WRITELOG(tmp); 		   
      scheduler->Stop();          	
   		}
  else
    	{      
      tmp.Format(_L("Unknown event received: %d"), aEvent );
	     _WRITELOG(tmp);
	    }
	}