--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/brandingserver/bsserver/cbsinstallhandler.cpp Wed Nov 03 09:32:20 2010 +0530
@@ -0,0 +1,564 @@
+/*
+* 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: CBSInstallhandler.cpp
+*
+*/
+
+
+// INCLUDE FILES
+#include <apgcli.h>
+#include <apacmdln.h>
+#include <eikenv.h>
+#include <bautils.h>
+#include <utf.h>
+#include <e32property.h>
+
+#include "cbsinstallhandler.h"
+#include "debugtrace.h"
+#include "bsimportconstants.h"
+#include "cbsstoragemanager.h"
+
+
+// CONSTANTS
+// branding installer application
+_LIT( KInstallerApp, "bsinstall.exe" );
+
+
+// wildcard for finding installed brand files
+_LIT( KBrandWild, "*" );
+
+// Line feed separates uninstalled brands from each other
+_LIT( KLineFeed, "\n" );
+
+
+// Pub&Sub Key for uninstalled brands
+const TUint KUninstallKey = 0x01;
+
+
+// METHODS
+
+// Two-phased constructor.
+CBSInstallHandler* CBSInstallHandler::NewL( )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::NewL begin") );
+ CBSInstallHandler* self = new ( ELeave ) CBSInstallHandler() ;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ TRACE( T_LIT( "CBSInstallHandler::NewL end") );
+ return self;
+ }
+
+// Symbian OS default constructor can leave.
+void CBSInstallHandler::ConstructL()
+ {
+ User::LeaveIfError( iFs.Connect() );
+ CActiveScheduler::Add( this );
+ }
+
+// Destructor
+CBSInstallHandler::~CBSInstallHandler()
+ {
+ Cancel();
+ iFs.Close();
+ }
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CBSInstallHandler::CBSInstallHandler() :
+ CActive( EPriorityIdle )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::InstallNewFilesL()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::InstallNewFilesL()
+ {
+ TRACE( T_LIT( "CBSInstallHandler::InstallNewFilesL begin") );
+ TInt needInstaller = 0;
+
+
+ TRAP_IGNORE( needInstaller += CheckForDiscardedBrandsL( KBSDataStore ) );
+
+ // uninstall removed brands
+ needInstaller +=
+ SyncFilesL( KInstallPath, KInstallObservePath, EInstallDeleteFromSrc );
+
+ // install new brands
+ needInstaller +=
+ SyncFilesL( KInstallObservePath, KInstallPath, EInstallCopyNewToDest );
+
+ if( needInstaller )
+ {
+ // something new was installed
+ LaunchInstallerAppL();
+ }
+ TRACE( T_LIT( "CBSInstallHandler::InstallNewFilesL end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::StartObservingL()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::StartObservingL()
+ {
+ TRACE( T_LIT( "CBSInstallHandler::StartObservingL begin") );
+ if( IsActive() )
+ {
+ __ASSERT_DEBUG( EFalse, User::Leave( KErrAlreadyExists ) );
+ return;
+ }
+
+ // observe path: (drive:)[private](/import/install)
+ TPath path( KNullDesC );
+ GetPrivateFolder( path, KInstallObservePath );
+
+ iFs.NotifyChange( ENotifyEntry, iStatus, path );
+ SetActive();
+ TRACE( T_LIT( "CBSInstallHandler::StartObservingL end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::StopObserving()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::StopObserving()
+ {
+ TRACE( T_LIT( "CBSInstallHandler::StopObserving begin") );
+ Cancel();
+ TRACE( T_LIT( "CBSInstallHandler::StopObserving end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::DoCancel()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::DoCancel()
+ {
+ iFs.NotifyChangeCancel();
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::RunL()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::RunL()
+ {
+ TRACE( T_LIT( "CBSInstallHandler::RunL start") );
+ if( iStatus == KErrNone )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::RunL installing...") );
+ TRAP_IGNORE( InstallNewFilesL() );
+ StartObservingL();
+ }
+ else
+ {
+ TRACE( T_LIT( "CBSInstallHandler::RunL observing stopped") );
+ }
+ TRACE( T_LIT( "CBSInstallHandler::RunL end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::LaunchInstallerAppL()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::LaunchInstallerAppL()
+ {
+ TRACE( T_LIT( "CBSInstallHandler::LaunchInstallerAppL start") );
+ // initialize RApaLsSession
+ RApaLsSession apas;
+ User::LeaveIfError( apas.Connect() );
+ CleanupClosePushL( apas );
+ apas.GetAllApps();
+
+ // start installer
+ CApaCommandLine* command = CApaCommandLine::NewLC();
+ command->SetExecutableNameL( KInstallerApp );
+ User::LeaveIfError( apas.StartApp( *command ) );
+ TRACE( T_LIT( "CBSInstallHandler::LaunchInstallerAppL bsinstall.exe launched OK") );
+
+ CleanupStack::PopAndDestroy( 2 ); // apas, command
+ TRACE( T_LIT( "CBSInstallHandler::LaunchInstallerAppL end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::SyncFilesL()
+// -----------------------------------------------------------------------------
+//
+TBool CBSInstallHandler::SyncFilesL( const TDesC& aSrcDir, const TDesC& aDestDir,
+ TInstallOperation aOperation )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::SyncFilesL start") );
+
+ // Check new install folder
+ HBufC* fileBuf = HBufC::NewLC( KMaxFileName );
+ TPtr file( fileBuf->Des() );
+ GetPrivateFolder( file, aSrcDir );
+
+ TBool ret = BaflUtils::PathExists( iFs, file );
+ if( !ret )
+ {
+ // install folder doesn't exist.
+ TRACE( T_LIT(
+ "CBSInstallHandler::SyncFilesL no src folder!") );
+ CleanupStack::PopAndDestroy( fileBuf );
+ return EFalse;
+ }
+
+ // Apply extension filter
+ file.Append( KBrandWild ); //
+ file.Append( KBrandInstallExt ); // *.install
+
+ // Get list of src dir files
+ CDir* dir = NULL;
+ User::LeaveIfError( iFs.GetDir( file,
+ KEntryAttNormal, ESortNone, dir ) );
+ CleanupStack::PushL( dir );
+
+ // Create destination directory
+ GetPrivateFolder( file, aDestDir );
+ BaflUtils::EnsurePathExistsL( iFs, file );
+
+ // Compare source dir to destination
+ TBool OperationExecuted = EFalse;
+ TInt count = dir->Count();
+
+ for( TInt i = 0; i < count; i++ )
+ {
+ GetPrivateFolder( file, aDestDir );
+ file.Append( (*dir)[i].iName );
+ if( !BaflUtils::FileExists( iFs, file ) )
+ {
+ // file does not exist in destionation dir
+ // => react according to operation
+ HBufC* fileSrcBuf = HBufC::NewLC( KMaxFileName );
+ TPtr fileSrc( fileSrcBuf->Des() );
+ GetPrivateFolder( fileSrc, aSrcDir );
+ fileSrc.Append( (*dir)[i].iName );
+
+ switch( aOperation )
+ {
+ case EInstallCopyNewToDest:
+ {
+ // copy new files from src to destination
+ TRACE( T_LIT( "CBSInstallHandler::SyncFilesL copy") );
+ OperationNotifyL( aOperation, file );
+ User::LeaveIfError( BaflUtils::CopyFile(
+ iFs, fileSrc, file ) );
+ break;
+ }
+ case EInstallDeleteFromSrc:
+ {
+ // delete files from src if they are not found from dest
+ TRACE( T_LIT( "CBSInstallHandler::SyncFilesL del") );
+ OperationNotifyL( aOperation, fileSrc );
+ User::LeaveIfError( BaflUtils::DeleteFile( iFs, fileSrc ) );
+ break;
+ }
+ default:
+ {
+ // Every operation should have a case!
+ __ASSERT_DEBUG( EFalse,
+ User::LeaveIfError( KErrArgument ) );
+ }
+ }
+
+ OperationExecuted = ETrue;
+ CleanupStack::PopAndDestroy( fileSrcBuf );
+ }
+ }
+ CleanupStack::PopAndDestroy( 2 ); // fileBuf, dir
+ TRACE( T_LIT( "CBSInstallHandler::SyncFilesL end") );
+ return OperationExecuted;
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::OperationNotifyL()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::OperationNotifyL( TInstallOperation aOperation,
+ const TDesC& aSrcFile )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::OperationNotifyL start") );
+ if( aOperation == EInstallDeleteFromSrc )
+ {
+ // parse brand id and application id from filename
+ TParse parse;
+ parse.Set( aSrcFile, NULL, NULL );
+
+ // find ids from filename
+ TInt firstSepar = parse.Name().Find( KInstallFileDataSeparator );
+ TInt secondSepar = parse.Name().
+ Mid( firstSepar + 1 ).Find( KInstallFileDataSeparator );
+ TInt cutlen = 0;
+ secondSepar == KErrNotFound ? cutlen = parse.Name().Length() :
+ cutlen = firstSepar + secondSepar + 1;
+
+ // brandString: [brandId]$[appId]
+ TPtrC brandString ( parse.Name().Left( cutlen ) );
+ if( IsBrandInstalled( brandString ) )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::OperationNotifyL %S exists in import\\install =>RProperty NOT UPDATED!"),&aSrcFile );
+ // brand still exists, so no need to uninstall.
+ return;
+ }
+
+ // Create discardedbrand.txt file in the /appid/brandid path
+ CreateFlagFile( aSrcFile );
+
+ UpdateRPropertyL( brandString );
+
+ TRACE( T_LIT( "CBSInstallHandler::OperationNotifyL uninstall string to pub&sub updated OK") );
+ }
+ TRACE( T_LIT( "CBSInstallHandler::OperationNotifyL end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::IsBrandInstalled()
+// -----------------------------------------------------------------------------
+//
+TBool CBSInstallHandler::IsBrandInstalled( const TDesC& aBrand )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::IsBrandInstalled start") );
+ TFileName file;
+ GetPrivateFolder( file, KInstallObservePath );
+ file.Append( aBrand );
+ file.Append( KBrandInstallExt );
+
+ // check file directly:
+ // aaa$bbb -> aaa$bbb.install
+ CDir* dir = NULL;
+ iFs.GetDir( file, KEntryAttNormal, ESortNone, dir );
+ if( dir && dir->Count() > 0 )
+ {
+ // brand is installed
+ delete dir;
+ TRACE( T_LIT( "CBSInstallHandler::IsBrandInstalled true") );
+ return ETrue;
+ }
+ delete dir;
+ dir = NULL;
+
+ GetPrivateFolder( file, KInstallObservePath );
+ file.Append( aBrand );
+ file.Append( KInstallFileDataSeparator );
+ file.Append( KBrandWild );
+ file.Append( KBrandInstallExt );
+
+ // check file with different versions:
+ // aaa$bbb -> aaa$bbb$*.install
+ iFs.GetDir( file, KEntryAttNormal, ESortNone, dir );
+ if( dir && dir->Count() > 0 )
+ {
+ // brand is installed
+ delete dir;
+ TRACE( T_LIT( "CBSInstallHandler::IsBrandInstalled true") );
+ return ETrue;
+ }
+ delete dir;
+
+ // brand is not installed
+ TRACE( T_LIT( "CBSInstallHandler::IsBrandInstalled false") );
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::GetPrivateFolder()
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::GetPrivateFolder( TDes& aPath, const TDesC& aAppend )
+ {
+ iFs.PrivatePath( aPath );
+ aPath.Insert( 0, KInstallDrive );
+ aPath.Append( aAppend );
+ }
+
+void CBSInstallHandler::CreateFlagFile(const TDesC& aSrcFile)
+ {
+ TRACE( T_LIT( "CBSInstallHandler::CreateFlagFile begin") );
+ // parse brand id and application id from aSrcFile
+ TParse parse;
+ parse.Set( aSrcFile, NULL, NULL );
+
+ // find ids from filename
+ TInt firstSepar = parse.Name().Find( KInstallFileDataSeparator );
+
+ // Get the brand Id
+ HBufC* brandId = (parse.Name().Left(firstSepar)).AllocL();
+
+ // to get application id
+ TInt secondSepar = parse.Name().
+ Mid( firstSepar + 1 ).Find( KInstallFileDataSeparator );
+
+ TInt cutlen = 0;
+ secondSepar == KErrNotFound ? cutlen = parse.Name().Length() :
+ cutlen = firstSepar + secondSepar + 1;
+
+
+ TParse parseAgain;
+ parseAgain.Set(parse.Name().Left( cutlen ), NULL, NULL );
+ HBufC* applicationId = (parseAgain.Name().Right( cutlen - firstSepar - 1)).AllocL();
+
+
+ HBufC *fileName = CBSStorageManager::ConstructDiscardBrandFileNameL(*applicationId, *brandId) ;
+ CleanupStack::PushL(fileName);
+ HBufC *fullPath = CBSStorageManager::FullDiscardBrandFileNameLC( *fileName ) ;
+
+ // crate a flag file
+ RFile file;
+ file.Create(iFs, *fullPath, EFileWrite);
+ file.Close() ;
+
+ delete brandId ;
+ delete applicationId ;
+
+ CleanupStack::PopAndDestroy(fullPath) ;
+ CleanupStack::PopAndDestroy(fileName) ;
+ TRACE( T_LIT( "CBSInstallHandler::CreateFlagFile end") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::CheckForDiscardedBrandsL()
+// -----------------------------------------------------------------------------
+//
+TBool CBSInstallHandler::CheckForDiscardedBrandsL( const TDesC& aDir )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::CheckForDiscardedBrandsL begin") );
+ TBool discardedBrandExists( EFalse );
+
+ CDir* appDir = NULL; // will contain all application folders
+
+ TPath path;
+ iFs.PrivatePath( path );
+ path.Insert( 0, KInstallDrive );
+ path.Append( aDir );
+ path.Append( KDirSeparator ); // "C:\\private\\102828dd\\data\\"
+
+ User::LeaveIfError(
+ iFs.GetDir( path, KEntryAttDir, ESortNone, appDir ) );
+ CleanupStack::PushL( appDir );
+
+ /*TFileName find( path );
+ find.Append( KInstallFiles );*/
+
+ // create array of files (as text)
+ TInt count = appDir->Count();
+ //for each application do...
+ for( TInt i = 0; i < count; i++ )
+ {
+ TFileName file( path );
+ file.Append( (*appDir)[i].iName );
+ file.Append( KDirSeparator ); // "C:\\private\\102828dd\\data\\xsp\\"
+
+ TRACE( T_LIT( "CBSInstallHandler::CheckForDiscardedBrandsL AppDir='%S'"),&file );
+ CDir* brandDir = NULL; // will contain all brand folder for each application
+ User::LeaveIfError(
+ iFs.GetDir( file, KEntryAttDir, ESortNone, brandDir ) );
+ CleanupStack::PushL( brandDir );
+
+ TInt countBrands = brandDir->Count();
+ //for each brand of a certain application do...
+ for( TInt j(0) ; j < countBrands ; j++ )
+ {
+ TFileName discardedFile( file );
+ discardedFile.Append( (*brandDir)[j].iName );
+ discardedFile.Append( KDirSeparator );
+ discardedFile.Append( KDiscardBrandFileName ); // "C:\\private\\102828dd\\data\\xsp\\branda\\discarded.txt"
+
+ TRACE( T_LIT( "CBSInstallHandler::CheckForDiscardedBrandsL BrandDir='%S'"),&file );
+
+ // check for the existance of the 'discarded.txt' file
+ if ( BaflUtils::FileExists( iFs, discardedFile ) )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::CheckForDiscardedBrandsL '%S' found!=>brand is discarded."),&discardedFile );
+ discardedBrandExists = ETrue;
+
+ //set RProperty for this brand
+
+ //the string written to RProperty:
+ //"[brandId]$[applicationId]"(e.g."branda$xsp")
+ HBufC* writeBuf = HBufC::NewLC( RProperty::KMaxPropertySize );
+ TPtr writeData( writeBuf->Des() );
+ writeData.Append( (*brandDir)[j].iName );
+ writeData.Append( KInstallFileDataSeparator );
+ writeData.Append( (*appDir)[i].iName );
+ TRACE( T_LIT( "CBSInstallHandler::CheckForDiscardedBrandsL uninstallstring='%S'"),writeBuf );
+
+ //UpdateProperty here!!!
+ UpdateRPropertyL( writeData );
+
+ CleanupStack::PopAndDestroy( writeBuf );
+ }
+ }
+ CleanupStack::PopAndDestroy( brandDir );
+ }
+
+ CleanupStack::PopAndDestroy( appDir );
+ TRACE( T_LIT( "CBSInstallHandler::CheckForDiscardedBrandsL end") );
+ return discardedBrandExists;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBSInstallHandler::UpdateRPropertyL
+// -----------------------------------------------------------------------------
+//
+void CBSInstallHandler::UpdateRPropertyL( const TDesC& aUninstallationString )
+ {
+ HBufC* dataBuf = HBufC::NewLC( RProperty::KMaxPropertySize );
+ TPtr data( dataBuf->Des() );
+
+ // Update uninstall string to pub&sub (only if the RProperty does not
+ // contain the unistallation string yet)
+ RProcess me;
+ TUid uid = me.Identity();
+ TInt ret = RProperty::Define( uid, KUninstallKey, RProperty::EText);
+ if( ret != KErrAlreadyExists )
+ {
+ TRACE( T_LIT( "CBSInstallHandler::UpdateRPropertyL RProperty does not exist") );
+ User::LeaveIfError( ret );
+ }
+ TRACE( T_LIT( "CBSInstallHandler::UpdateRPropertyL RProperty created/exists OK") );
+ User::LeaveIfError( RProperty::Get( uid, KUninstallKey, data ) );
+
+ // don't append the uninstall string in case it already exists
+ // in the RProperty
+ if( KErrNotFound == data.Find( aUninstallationString ) )
+ {
+ if( data.Length() > 0 )
+ {
+ data.Append( KLineFeed );
+ TRACE( T_LIT( "CBSInstallHandler::UpdateRPropertyL lineFeed appended to RProperty uninstallstring") );
+ }
+ data.Append( aUninstallationString );
+ TRACE( T_LIT( "CBSInstallHandler::UpdateRPropertyL '%S' appended to RProperty uninstallstring"), &aUninstallationString );
+ if( data.Length() <= RProperty::KMaxPropertySize )
+ {
+ User::LeaveIfError( RProperty::Set( uid, KUninstallKey, data ) );
+ TRACE( T_LIT( "CBSInstallHandler::UpdateRPropertyL RProperty::Set OK") );
+ }
+ }
+ else
+ {
+ TRACE( T_LIT( "CBSInstallHandler::UpdateRPropertyL '%S' already exists in RProperty"), &aUninstallationString );
+ }
+
+ CleanupStack::PopAndDestroy( dataBuf );
+
+ }
+
+// END OF FILE