diff -r 000000000000 -r 79c6a41cd166 homescreenpluginsrv/hspsmanager/src/hspsinstallationhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/homescreenpluginsrv/hspsmanager/src/hspsinstallationhandler.cpp Thu Dec 17 08:54:17 2009 +0200 @@ -0,0 +1,2636 @@ +/* +* Copyright (c) 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: Implementaion of HSPS MhspsInstallationService interface defined +* in hspsThemeManagement.h. For details, see the header file. +* +*/ + + +#include +#include +#include + +#include "hsps_builds_cfg.hrh" +#include "hspsthememanagement.h" +#include "hspsdefinitionrepository.h" +#include "hspsodt.h" +#include "hspsdefinitionengineinterface.h" +#include "hspsdomdocument.h" +#include "hspsresource.h" +#include "hspsresult.h" +#include "hspsthemeserver.h" +#include "hspsinstallationhandler.h" +#include "hspssecurityenforcer.h" +#include "hspsuimanagererrorcodes.h" +#include "hspsdomattribute.h" +#include "hspsdomlist.h" +#include "hspsdomdepthiterator.h" +#include "hspsdomnode.h" +#include "hspsconfiguration.h" +#include "hspsmanifest.h" +#include "hspsserverutil.h" +#include "hspsfamilylistener.h" + +#ifdef HSPS_LOG_ACTIVE +#include +#include +#endif + +#ifdef _hsps_PERFORMANCE_TEST_ +#include "hspstimemon.h" +#endif + +_LIT8(KUnknownMimeType, "unknown"); + +_LIT8(KhspsDefinitionEngine, "hspsdefinitionengine"); + +_LIT(KPathDelim, "\\"); +_LIT(KHsps, "\\hsps\\" ); +_LIT(KXuikon, "xuikon\\" ); + +const TInt KMaxMediaTypeLength = 100; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// Callback function for removing repository lock if error occurs while repository is locked +// ----------------------------------------------------------------------------- +// +LOCAL_C void UnlockRepository( TAny* aObject ) + { + ChspsDefinitionRepository* DefRep = reinterpret_cast( aObject ); + + if (DefRep->Locked()) + { + DefRep->Unlock(); + } + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ChspsInstallationHandler() +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +ChspsInstallationHandler::ChspsInstallationHandler( ChspsThemeServer& aThemeServer ) + : iThemeServer( aThemeServer ), + iDefinitionRepository( aThemeServer.DefinitionRepository() ), + iSecurityEnforcer( aThemeServer.SecurityEnforcer() ), + iCentralRepository( aThemeServer.CentralRepository() ), + iHeaderListCache( aThemeServer.HeaderListCache() ) + { + iPackageVerSupported = EFalse; + iInstallationPhase = EhspsPhaseIdle; + iConfigurationType = EhspsAppConfiguration; + iThemeStatus = EhspsThemeStatusNone; + iFileNotFound = EFalse; + iLocalized = EFalse; + iDefaultSpecificationSet = EFalse; + iDefaultSpecification = ELangNone; + iInstallationMode = EServiceHandler; + iRomInstallation = EFalse; + iInstallationType = EInstallationTypeNew; + iFamilyMask = 0; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +ChspsInstallationHandler* ChspsInstallationHandler::NewL( ChspsThemeServer& aThemeServer ) + { + ChspsInstallationHandler* h = ChspsInstallationHandler::NewLC( aThemeServer ); + CleanupStack::Pop( h ); + return ( h ); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +ChspsInstallationHandler* ChspsInstallationHandler::NewLC( ChspsThemeServer& aThemeServer ) + { + ChspsInstallationHandler* h = new (ELeave) ChspsInstallationHandler( aThemeServer ); + CleanupStack::PushL( h ); + h->ConstructL(); + return ( h ); + } + + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +// +ChspsInstallationHandler::~ChspsInstallationHandler() + { + iFsSession.Close(); + delete iXmlParser; + delete iOdt; + delete iDtdFile; + delete iHeaderData; + delete iThemeFullName; + delete iThemeShortName; + delete iThemeVersion; + delete iThemeDesc; + delete iResourceTag; + delete iPackageVersion; + if ( iTempLocalizedResourceList ) + { + iTempLocalizedResourceList->ResetAndDestroy(); + delete iTempLocalizedResourceList; + } + if( iResourceList ) + { + iResourceList->Reset(); // ODT has an ownership of the items + delete iResourceList; + } + delete iContent; + delete iXmlFile; + delete iMediaType; + delete iResource; + delete iResult; + + if ( iDefEngine ) + { + delete iDefEngine; + } + + REComSession::FinalClose(); + + } + + + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ConstructL() + { + _LIT8(KMimeType, "text/xml"); + MContentHandler* contentHandler = this; + iXmlParser = Xml::CParser::NewL( KMimeType, *contentHandler ); + + iDefEngine = ChspsDefinitionEngineInterface::NewL(KhspsDefinitionEngine); + + iOdt = ChspsODT::NewL(); + iResourceList = new( ELeave ) CArrayPtrSeg( KPathListGranularity ); + iTempLocalizedResourceList = new( ELeave ) CArrayPtrSeg( KPathListGranularity ); + User::LeaveIfError( iFsSession.Connect() ); + iResult = ChspsResult::NewL(); + + iMultiInstanceFound = EFalse; + + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ServiceInstallThemeL +// Starts the actual installation in ChspsInstallationHandler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ServiceInstallThemeL( const RMessage2& aMessage ) + { + // incoming arguments: TIpcArgs: &iResultData, &aManifestFileName, &aHeader + iMessagePtr = aMessage; + TBuf8 headerdata; + + iInstallationPhase = EhspsPhaseIdle; + ThspsServiceCompletedMessage ret = EhspsInstallThemeFailed; + + if ( !iDefinitionRepository.Locked() ) + { + // read name of the manifest file + TBuf manifestfilename; + iMessagePtr.ReadL( 1, manifestfilename, 0 ); + +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::ServiceInstallThemeL() - Manifest file '%S'" ), + &manifestfilename ); + } +#endif + + // install the manifest file + ret = hspsInstallTheme( manifestfilename, headerdata ); + + // now there will be the time for query validity check + if ( ret == EhspsInstallThemeSuccess ) + { + ret = EhspsInstallPhaseSuccess; + } + } + else + { + iResult->ResetData(); + iResult->iSystemError = KErrInUse; + } + + CompleteRequestL(ret, headerdata); + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ServiceInstallNextPhaseL +// Starts subsequent installation phases. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ServiceInstallNextPhaseL( const RMessage2& aMessage ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::ServiceInstallNextPhaseL():" ) ); + } +#endif + + TBuf8 headerdata; + iResult->ResetData(); + iInstallationMode = EServiceHandler; + ThspsServiceCompletedMessage ret = EhspsInstallThemeFailed; + // incoming arguments: TIpcArgs: &iResultData, &KNullDesC, &aHeaderData + iMessagePtr = aMessage; + + // calling installation of next phase + ret = hspsInstallNextPhaseL( headerdata ); + CompleteRequestL( ret, headerdata ); + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::InstallNextPhase() +// Must be completed by EhspsInstallThemeSuccess, EhspsInstallPhaseSuccess or EhspsInstallThemeFailed +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::hspsInstallNextPhaseL( + TDes8& aHeaderData, + TRequestStatus& aRequestStatus ) + { + ThspsServiceCompletedMessage ret = EhspsServiceNotSupported; + iInstallationMode = EAsynchronousObject; + iRequestStatus = &aRequestStatus; + *iRequestStatus = KRequestPending; + ret = hspsInstallNextPhaseL( aHeaderData ); + CompleteRequestL( ret ); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ResetL() +// ----------------------------------------------------------------------------- +void ChspsInstallationHandler::ResetL() + { + iFamilyMask = 0; + iInstallationPhase = EhspsPhaseInitialise; + iThemeStatus = EhspsThemeStatusNone; + iFileNotFound = EFalse; + delete iMediaType; + iMediaType = NULL; + delete iThemeDesc; + iThemeDesc = NULL; + delete iResourceTag; + iResourceTag = NULL; + iLocalized = EFalse; + iDefaultSpecificationSet = EFalse; + iDefaultSpecification = ELangNone; + if ( iOdt ) + { + delete iOdt; + iOdt = NULL; + iOdt = ChspsODT::NewL(); + } + + delete iDtdFile; + iDtdFile = NULL; + + delete iHeaderData; + iHeaderData = NULL; + if ( iDefEngine ) + { + delete iDefEngine; + iDefEngine = NULL; + iDefEngine = ChspsDefinitionEngineInterface::NewL(KhspsDefinitionEngine); + } + if ( iResourceList ) + { + iResourceList->Reset(); // ODT has an ownership of the items + delete iResourceList; + iResourceList = NULL; + iResourceList = new( ELeave ) CArrayPtrSeg( KPathListGranularity ); + } + if ( iTempLocalizedResourceList ) + { + iTempLocalizedResourceList->ResetAndDestroy(); + delete iTempLocalizedResourceList; + iTempLocalizedResourceList = NULL; + iTempLocalizedResourceList = new( ELeave ) CArrayPtrSeg( KPathListGranularity ); + } + iInstallationType = EInstallationTypeNew; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::hspsInstallTheme() +// From MhspsInstallationService +// Must be completed by EhspsInstallThemeSuccess, EhspsInstallPhaseSuccess or EhspsInstallThemeFailed +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +ThspsServiceCompletedMessage ChspsInstallationHandler::hspsInstallTheme( + const TDesC& aManifestFileName, + TDes8& aHeaderData) + { + // Assume that the installation fails + ThspsServiceCompletedMessage ret = EhspsInstallThemeFailed; + iResult->iXuikonError = KErrManifestFileCorrupted; + + // Reset memeber variables + TInt errorCode = KErrNone; + TRAP( errorCode, ResetL() ); + if ( !errorCode ) + { + // Get manifest file path + iThemeFilePath.Set( TParsePtrC( aManifestFileName ).DriveAndPath() ); + // Check if ROM installation is requested + iRomInstallation = EFalse; + TParse driveParser; + driveParser.Set( iThemeFilePath, NULL, NULL ); + TInt driveNumber; + if ( RFs::CharToDrive( driveParser.Drive()[0], driveNumber ) == KErrNone ) + { + if ( driveNumber == EDriveZ ) + { + iRomInstallation = ETrue; + } + } + +#ifdef HSPS_LOG_ACTIVE + if ( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::hspsInstallTheme() - *** Parsing a manifest file:" ) ); + } +#endif + if( BaflUtils::FileExists( iFsSession, aManifestFileName ) ) + { + // Parse XML from the manifest file + TRAP( errorCode, Xml::ParseL( *iXmlParser, iFsSession, aManifestFileName )); + } + else + { +#ifdef HSPS_LOG_ACTIVE + if ( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::hspsInstallTheme() - Manifest was not found!" ) ); + } +#endif + iFileNotFound = ETrue; + errorCode = KErrNotFound; + } + } + + if ( !errorCode && !iFileNotFound ) + { + // The manifest file has been read at this point and following callbacks have been executed: + // (unless the manifest was invalid): OnContent, OnStartElement, OnEndElement + + // Detect installation type. + // Performance optimization: do not check if installing from rom. + if( !iRomInstallation ) + { + // Check type of installation + TBool instancesFound = EFalse; + TRAP( errorCode, instancesFound = IsPluginUsedInAppConfsL() ); + if( iThemeServer.PluginInHeaderCache( TUid::Uid( iThemeUid ) ) && instancesFound ) + { + // Plugin should be found from cache, update notifications are + // sent only when plugins are used by one/more app configurations + iInstallationType = EInstallationTypeUpdate; + } + else + { + iInstallationType = EInstallationTypeNew; + } + } + if ( !errorCode ) + { + // Check the manifest + TRAP( errorCode, ValidateL() ); + } + if ( !errorCode ) + { + // correct headerdata is in iHeaderData set by CheckHeaderL() + aHeaderData = iHeaderData->Des(); + + ret = EhspsInstallThemeSuccess; + + // Set next phase + iInstallationPhase = EhspsPhaseCleanup; + + // number of all resources to iResult + iResult->iIntValue2 = 0; + } + } + + if ( errorCode ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::hspsInstallTheme(): - Installation failed with error code %d" ), + errorCode ); + } +#endif + } + + iResult->iSystemError = errorCode; + return ret; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::GetInterfacePath() +// ----------------------------------------------------------------------------- +// +TFileName ChspsInstallationHandler::GetInterfacePath() + { + TFileName path; + + TParse pathParser; + pathParser.Set( iThemeFilePath, NULL, NULL ); + pathParser.PopDir(); // pop locale specific folder + + TPtrC parentFolder = pathParser.FullName().Mid( pathParser.FullName().Length() - KHsps().Length() ); + if ( parentFolder.CompareF(KHsps) == 0 ) + { + pathParser.PopDir(); // pop "hsps" folder + path.Copy( pathParser.FullName() ); + path.Append( KXuikon ); + } + return path; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ValidateL() +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ValidateL() + { + TFileName interfacePath( GetInterfacePath() ); + if ( interfacePath.Length() ) + { + // If name of the DTD file was specified in the manifest + if ( iDtdFile ) + { + TParse pathParser; + pathParser.Set( iThemeFilePath, NULL, NULL ); + pathParser.PopDir(); // pop locale specific folder + + // Find locale specific DTD file + AddHspsLocalesV2L( pathParser.FullName() ); + } + + // Find Xuikon resources of each locale + AddInterfaceResourcesV2L( interfacePath ); + } + else + { + // Find DTD files and locale specific resources from subdirectories under the installation path + AddLocalesL( iThemeFilePath ); + } + + // Validate input from the manifest + CheckHeaderL(); + + if ( iSecurityEnforcer.CheckThemeLockingL( *iOdt ) ) + { + iResult->iXuikonError = KErrThemeStatusLocked; +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::ValidateL(): - CheckThemeLockingL" ) ); + } +#endif + User::Leave( KErrAccessDenied ); + } + +#ifdef HSPS_LOG_ACTIVE + // printing some debug-info + TPtrC xmlfile = iXmlFile->Des(); + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::ValidateL(): - iXmlFile = '%S'" ), + &xmlfile ); + + iLogBus->LogText( _L( "ChspsInstallationHandler::ValidateL(): - resources included = %d" ), + iResourceList->Count() ); + } +#endif + } + + +// ----------------------------------------------------------------------------- +// Execution of specific installation phases and transitions in between. +// Must be completed by EhspsInstallThemeSuccess, EhspsInstallPhaseSuccess or EhspsInstallThemeFailed +// ----------------------------------------------------------------------------- +// +ThspsServiceCompletedMessage ChspsInstallationHandler::hspsInstallNextPhaseL( TDes8& aHeaderData ) + { + // Defaults + ThspsServiceCompletedMessage ret = EhspsInstallPhaseSuccess; + TInt errorCode = KErrNone; + + if ( !iDefinitionRepository.Locked() ) + { + iDefinitionRepository.Lock(); + } + + //For unlocking repository in error cases + CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) ); + + switch ( iInstallationPhase ) + { + case EhspsPhaseIdle: + { + ret = EhspsServiceRequestError; + } + break; + + case EhspsPhaseCleanup: + { + if ( iOdt ) + { + // Remove existing/old files from the Plug-in Repository + TRAP( errorCode, CleanupL( *iOdt ) ); + } + if ( errorCode ) + { + iResult->iSystemError = errorCode; + iResult->iXuikonError = errorCode; + CleanupStack::Pop(&iDefinitionRepository); + return EhspsInstallThemeFailed; + } + else + { + iInstallationPhase = EhspsPhaseInstallSkeleton; + } + } + break; + + case EhspsPhaseInstallSkeleton: + { + // Parses and stores DOM into the ODT being installed + iResult->iIntValue2 = 0; + TRAP( errorCode, InstallSkeletonL( ret ) ); + if ( errorCode ) + { + ret = EhspsInstallThemeFailed; + } + else + { + iResult->iIntValue2 = 0; + + // Success - installation finished + ret = EhspsInstallThemeSuccess; + iInstallationPhase = EhspsPhaseIdle; + } + } + break; + + default: + { + iResult->iSystemError = KErrNotReady; + ret = EhspsServiceRequestError; + } + break; + } // switch + + if ( iHeaderData ) + { + aHeaderData = iHeaderData->Des(); + } + else + { + aHeaderData = KNullDesC8; + } + + CleanupStack::Pop(&iDefinitionRepository); + return ret; + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::hspsCancelInstallTheme() +// Cancels the theme installation +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +ThspsServiceCompletedMessage ChspsInstallationHandler::hspsCancelInstallTheme() + { + TRAP_IGNORE( CompleteRequestL( EhspsServiceRequestCanceled )); + return EhspsServiceRequestCanceled; + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::CheckAutoInstallationValidityL() +// Returns EFalse if the user tries to install Licensee default theme +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool ChspsInstallationHandler::CheckAutoInstallationValidityL() + { + if ( iOdt->Flags() & EhspsThemeStatusLicenceeDefault ) + { + iResult->iXuikonError = KErrIllegalInstallation; + return EFalse; + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::SetLogBus() +// ----------------------------------------------------------------------------- +// +#ifdef HSPS_LOG_ACTIVE +void ChspsInstallationHandler::SetLogBus( ChspsLogBus* aLogBus ) + { + iLogBus = aLogBus; + } +#endif + + +// ChspsInstallationHandler::InstallOdtL() +// Installs DOM-document ODT and processes resource list +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::InstallSkeletonL( ThspsServiceCompletedMessage& /*aReturnMsg*/ ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "hspsInstallationHandler::InstallSkeletonL(): - installing and localizing configuration" ) ); + } +#endif + + iOdt->SetOdtLanguage( ELangNone ); + + // Parse DOM + ParseDocumentL( *iOdt ); + + // Save ODT itself as a resource + SetODTAsResourceL( *iOdt ); + + // Add resources parsed from the manifest file into the new ODT instance, generate + // target paths and update the iResourcesList array with the new paths + User::LeaveIfError( iDefinitionRepository.SetResourceListL( *iOdt, *iResourceList ) ); + + // Update DOM's configuration node with attributes from the manifest + hspsServerUtil::GenerateConfigurationAttributesL( *iOdt ); + + TBuf8<10> uid; + _LIT8( KFormat8, "%X" ); + _LIT8( KHexPrefix, "0x" ); + uid.Append( KHexPrefix ); + uid.AppendFormat( KFormat8, iOdt->ThemeUid() ); + + // Update configuration max child count + if ( hspsServerUtil::FindNodeByTagL( + KPluginsElement, + *( iOdt->DomDocument().RootNode() ) ) ) + { + TPtrC8 maxChildCnt; + // Plugins node found - Configuration can include child configurations + TRAPD( err, hspsServerUtil::GetAttributeValueL( + *iOdt, + KConfigurationElement, + KConfigurationAttrUid, + uid, + KConfigurationAttrMaxChild, + maxChildCnt) ); + if ( err ) + { + // Set default max child configuration count + hspsServerUtil::SetAttributeValueL( + *iOdt, + KConfigurationElement, + KConfigurationAttrUid, + uid, + KConfigurationAttrMaxChild, + _L8( "6" ) ); + } + } + else + { + // Configuration cannot indluce child configurations + hspsServerUtil::SetAttributeValueL( + *iOdt, + KConfigurationElement, + KConfigurationAttrUid, + uid, + KConfigurationAttrMaxChild, + _L8( "0" ) ); + } + + if ( iRomInstallation ) + { + // Update configuration state to KConfStateConfirmed + hspsServerUtil::SetAttributeValueL( + *iOdt, + KConfigurationElement, + KConfigurationAttrUid, + uid, + KConfigurationAttrState, + KConfStateConfirmed + ); + } + + iOdt->SetOdtLanguage( ELangTest ); + + // Add a resouces node and its objects from the manifest into the DOM + hspsServerUtil::GenerateObjectAttributesL( *iOdt ); + + + + + // Make localizations according to the active device language + iThemeServer.LocalizeL( + *iDefEngine, + *iOdt ); + + // Store the ODT instance into the file system + iDefinitionRepository.SetOdtL( *iOdt ); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::CheckHeaderL() +// Checks the installed theme's header correctness +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::CheckHeaderL() + { + // Check whether the manifest is supported by the installer + if ( !iPackageVerSupported ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CheckHeaderL(): - package version is not supported by the server!" ) ); + iLogBus->LogText( _L( "ChspsInstallationHandler::CheckHeaderL(): - Update plug-in configurations and try again" ) ); + } +#endif + + User::Leave( KErrNotSupported ); + } + else + { + // Store package version + iOdt->SetPackageVersionL( *iPackageVersion ); + } + + // Set the resolution family + iOdt->SetFamily( iFamilyMask ); + + // Store root, provider and theme uid + if ( iRootUid && iProviderUid && iThemeUid ) + { + iOdt->SetRootUid( iRootUid ); + iOdt->SetProviderUid( iProviderUid ); + iOdt->SetThemeUid( iThemeUid ); + } + else + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CheckHeaderL(): - Manifest file error, no UIDs" ) ); + } +#endif + + // If the content is empty, the file is supposedly wrong + if( !iContent ) + { + iResult->iXuikonError = KErrWrongManifestFile; + User::Leave( KErrNotFound ); + } + // something goes wrong... + if( !iRootUid && !iProviderUid && !iThemeUid && + !iThemeFullName && !iThemeShortName && !iThemeVersion ) + { + iResult->iXuikonError = KErrOtherXuikonError; + User::Leave( KErrNotFound ); + } + if( !iRootUid ) + { + iResult->iXuikonError = KErrAppUidDefinitionMissing; + User::Leave( KErrNotFound ); + } + if( !iProviderUid ) + { + iResult->iXuikonError = KErrProviderUidDefinitionMissing; + User::Leave( KErrNotFound ); + } + if( !iThemeUid ) + { + iResult->iXuikonError = KErrThemeUidDefinitionMissing; + User::Leave( KErrNotFound ); + } + User::Leave(KErrNotFound); + } + + // Store name, short name and version + HBufC* themeFullName = NULL; + HBufC* themeShortName = NULL; + HBufC* themeVersion = NULL; + if ( iThemeFullName && iThemeShortName && iThemeVersion ) + { + themeFullName = HBufC::NewLC( iThemeFullName->Length() ); + themeFullName->Des().Copy( *iThemeFullName ); + themeShortName = HBufC::NewLC( iThemeShortName->Length() ); + themeShortName->Des().Copy( *iThemeShortName ); + themeVersion = HBufC::NewLC( iThemeVersion->Length() ); + themeVersion->Des().Copy( *iThemeVersion ); + } + else + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CheckHeaderL(): - Manifest file error, no names" ) ); + } +#endif + + if( !iThemeFullName ) + { + iResult->iXuikonError = KErrThemeFullNameDefinitionMissing; + User::Leave( KErrNotFound ); + } + if( !iThemeShortName ) + { + iResult->iXuikonError = KErrThemeShortDefinitionNameMissing; + User::Leave( KErrNotFound ); + } + if( !iThemeVersion ) + { + iResult->iXuikonError = KErrThemeVersionDefinitionMissing; + User::Leave( KErrNotFound ); + } + User::Leave(KErrNotFound); + } + iOdt->SetThemeFullNameL( themeFullName->Des() ); + iOdt->SetThemeShortNameL( themeShortName->Des() ); + iOdt->SetThemeVersionL( themeVersion->Des() ); + if ( iThemeDesc ) + { + HBufC* buf = HBufC::NewLC( iThemeDesc->Length() ); + buf->Des().Copy( iThemeDesc->Des() ); + iOdt->SetDescriptionL( buf->Des() ); + CleanupStack::PopAndDestroy( buf ); + } + iOdt->SetMultiInstance( iMultiInstance ); + iMultiInstanceFound = EFalse; + + CleanupStack::PopAndDestroy( themeVersion ); + CleanupStack::PopAndDestroy( themeShortName ); + CleanupStack::PopAndDestroy( themeFullName ); + + iOdt->SetConfigurationType( iConfigurationType ); + iOdt->SetFlags( iThemeStatus ); + + // If configuration file is missing + if( !iXmlFile ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CheckHeaderL(): - XML was not declared!" ) ); + } +#endif + iResult->iXuikonError = KErrXmlFileDefinitionMissing; + User::Leave( KErrNotFound ); + } + + // If name of the DTD file has been set + if ( iDtdFile ) + { + // Expect localization for at least ELangTest (folder name "00") + if ( !iDefaultSpecificationSet || iDefaultSpecification != ELangTest ) + { + iResult->iXuikonError = KErrDtdFileNotFound; +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CheckHeaderL(): - check localization!" ) ); + } +#endif + User::Leave( KErrNotFound ); + } + } + + // all header-information is in place, now try to marshall it as a return of the service call + iHeaderData = iOdt->MarshalHeaderL(); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ParseDocumentL +// Parses the skeleton DOM with the help of Definition Engine +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ParseDocumentL( ChspsODT& aOdt ) + { + TInt deferror = KErrNone; + TInt errorCode = KErrNone; + ChspsDefinitionEngineInterface::TError t_error; + +#ifdef _hsps_PERFORMANCE_TEST_ + // service time prints + _LIT( KStartTiming, "ChspsInstallationHandler::ParseDocumentL(): - calling iDefEngine->CreateDOM().."); + TTime start_time = ChspsTimeMon::StartTiming( KStartTiming ); +#endif + + t_error = iDefEngine->CreateDOM( iFsSession, *iXmlFile, aOdt ); + + deferror = t_error.iDefEngError + t_error.iSubComponentError; + + if (!deferror) + { + // get ODT information + ChspsDomDocument& domDocument = aOdt.DomDocument(); + TInt domNodeCount = domDocument.DomNodeCount(); + // write the result + iResult->iIntValue1 = 0; + iResult->iIntValue2 = domNodeCount; + +#ifdef _hsps_PERFORMANCE_TEST_ + // calculating service time + _LIT( KStopTiming, "ChspsInstallationHandler::ParseDocumentL(): - Parsing success." ); + ChspsTimeMon::StopTiming(start_time, KStopTiming ); +#endif + } + else + { + errorCode = KErrCorrupt; + iResult->iXuikonError = errorCode; + + iResult->iIntValue1 = t_error.iDefEngError; + iResult->iIntValue2 = t_error.iSubComponentError; + +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::ParseDocumentL(): - TRAP returned %d" ), + errorCode ); + iLogBus->LogText( _L( "ChspsInstallationHandler::ParseDocumentL(): - ChspsDefinition Engine::TError.iParserError: %d" ), + t_error.iDefEngError ); + iLogBus->LogText( _L( "ChspsInstallationHandler::ParseDocumentL(): - ChspsDefinition Engine::TError.iSubComponentError: %d" ), + t_error.iSubComponentError ); + } +#endif + } + + User::LeaveIfError(errorCode); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::AddResourceL() +// Adds parsed resource into a temporary resource list, from which the resources +// are applied to an ODT instance at later phase +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::AddResourceL( + CArrayPtrSeg& aArray, + const TPtrC aFilename, + const TLanguage aLanguage, + const ThspsResourceType aResourceType, + const TPtrC8 aMimetype, + const TPtrC8 aTag ) + { + TParsePtrC parsePtr( aFilename ); + + ChspsResource* r = ChspsResource::NewL(); + CleanupStack::PushL(r); + + r->SetLockingPolicy( EhspsUnlocked ); + if ( iThemeStatus & EhspsThemeStatusLicenceeDefault ) + { + r->SetLockingPolicy( EhspsLocked ); + } + r->SetResourceIdL( parsePtr.NameAndExt() ); + + // Common resources are parsed first - thus when the iLanguageSpecification is other than ELangNone, + // then we are parsing language specific resources + r->SetConfigurationUid( iThemeUid ); + r->SetLanguage( aLanguage ); + r->SetFileNameL( aFilename ); + r->SetResourceType( aResourceType ); + if ( aMimetype.Length() ) + { + r->SetMimeTypeL( TDataType( aMimetype ) ); + } + const TInt l = aTag.Length(); + if ( l ) + { + HBufC* buf = HBufC::NewLC( l ); + buf->Des().Copy( aTag ); + r->SetTagsL( *buf ); + CleanupStack::PopAndDestroy( buf ); + } + aArray.AppendL( r ); + + CleanupStack::Pop( r ); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::CleanupL() +// Executes cleaning of the target folder prior to the installation process +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::CleanupL( const ChspsODT& aOdt ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "hspsInstallationHandler::CleanupL(): - removing previous installation" ) ); + } +#endif + + // Get ODT's relative path in Plug-in Repository without the drive information + HBufC* relativePath = HBufC::NewLC( KMaxFileName ); + TPtr ptr = relativePath->Des(); + iDefinitionRepository.GetODTPathL( aOdt, ptr ); + + // Strip file name and append path with a drive symbol + TParsePtr parser( ptr ); + parser.PopDir(); + TPtrC confPath = parser.Path(); + TPath file; + file.Format( _L("%S%S"), &KCDrive, &confPath ); + CleanupStack::PopAndDestroy( relativePath ); + + // If there was an existing configuration folder + if( BaflUtils::FileExists( iFsSession, file ) ) + { + // Remove the old configuration + CFileMan* fileMan = CFileMan::NewL( iFsSession ); + CleanupStack::PushL( fileMan ); + User::LeaveIfError( fileMan->RmDir( file ) ); + CleanupStack::PopAndDestroy( fileMan ); + } + + iThemeServer.UpdateHeaderListCache( + EhspsCacheRemoveHeader, + aOdt.RootUid(), + aOdt.ProviderUid(), + aOdt.ThemeUid() ); + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::RollBackL() +// Rolls back the installation if it fails or is cancelled. Functionality depends +// on the state where the installation was. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::RollBackL(ChspsODT& aOdt) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "hspsInstallationHandler::RollBackL(): - rolling back.." ) ); + } +#endif + + // then rolling back the installation in according to in which state it was before cancel + switch ( iInstallationPhase ) + { + case EhspsPhaseIdle: + case EhspsPhaseInitialise: + case EhspsPhaseCleanup: + break; + case EhspsPhaseInstallSkeleton: + { + iDefinitionRepository.RemoveThemeL( aOdt ); + iInstallationPhase = EhspsPhaseIdle; // roll-back is completed + } + break; + default: + break; + } + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::CompleteRequestL() +// Completes client request +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::CompleteRequestL(const ThspsServiceCompletedMessage aReturnMessage, + const TDesC8& aHeaderData ) + { + TBool wasLocked( EFalse ); + + if( iDefinitionRepository.Locked() ) + { + CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) ); + wasLocked = ETrue; + } + + // only EhspsInstallThemeSuccess and EhspsInstallPhaseSuccess quaranties valid header to be returned + TBool complete( ETrue ); + + switch( iInstallationMode ) + { + case EServiceHandler: + { + if( aReturnMessage == EhspsInstallThemeSuccess ) + { + // Activate the installed application configuration if EhspsThemeStatusMakeActive is set + if ( iThemeStatus & EhspsThemeStatusMakeActive ) + { + if ( iConfigurationType == EhspsAppConfiguration ) + { + ActivateThemeL(); + } + } + + // lets try to delete temp files. Server will delete them only + // if there are not current resource holders + iInstallationPhase = EhspsPhaseIdle; + // write the result + iResult->iIntValue1 = 0; + iResult->iIntValue2 = 0; + + iDefinitionRepository.Unlock(); + + if ( !iDisableNotifications ) + { + // Inform server that a configuration was added or replaced and that the + // header cache should be updated (specific header to be added can be obtained + // from the uids) + + if( iInstallationType == EInstallationTypeNew ) + { + ThspsRepositoryInfo info( + ThspsRepositoryEvent( EhspsODTAdded ), + 0, + 0, + 0, //=Any file + 0, + iOdt->RootUid(), + iOdt->ProviderUid(), + iOdt->ThemeUid(),0,ETrue, + iOdt->ThemeFullName(), + (TLanguage)( iOdt->OdtLanguage() ) + ); + + iDefinitionRepository.RegisterNotification( info ); + } + else if( iInstallationType == EInstallationTypeUpdate ) + { + NotifyOdtUpdatedL(); + } + } + +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CompleteRequestL(): - configuration %d was successfully installed (EServiceHandler)" ), + iOdt->ThemeUid() ); + } +#endif + } + else if ( aReturnMessage == EhspsInstallPhaseSuccess ) + { + iResult->iIntValue1 = iInstallationPhase; + } + else if ( aReturnMessage == EhspsServiceRequestSheduled ) + { + complete = EFalse; + } + else if (aReturnMessage == EhspsServiceRequestCanceled) + { + iDefinitionRepository.Unlock(); + } + else + { + // installation failed, resetting + // system error and xuikon error are writen in iResult when error was encountered + iInstallationPhase = EhspsPhaseIdle; + + if( !iMessagePtr.IsNull() ) + { + iMessagePtr.WriteL( 2, KNullDesC8, 0 ); + } + + RollBackL ( *iOdt ); + iDefinitionRepository.Unlock(); + } + + if( complete && !iMessagePtr.IsNull() ) + { + RDesWriteStream writeBuf( iResultData ); + iResult->ExternalizeL( writeBuf ); + writeBuf.Close(); + iMessagePtr.WriteL( 0, iResultData, 0 ); + iMessagePtr.WriteL( 2, aHeaderData, 0 ); + iMessagePtr.Complete( aReturnMessage ); + } + } + break; + + case EAsynchronousObject: + { + if( aReturnMessage == EhspsInstallThemeSuccess ) + { + + // Activate the installed application configuration if EhspsThemeStatusMakeActive is set + if( iThemeStatus & EhspsThemeStatusMakeActive ) + { + if ( iConfigurationType == EhspsAppConfiguration ) + { + ActivateThemeL(); + } + } + + // lets try to delete temp files. Server will delete them only if there are not + // current resource holders + iInstallationPhase = EhspsPhaseIdle; + iDefinitionRepository.Unlock(); + + if ( !iDisableNotifications ) + { + if( iInstallationType == EInstallationTypeNew ) + { + // Inform server there are files to be cleaned and cache has been updated + ThspsRepositoryInfo info( ThspsRepositoryEvent( EhspsODTAdded ), + 0, + 0, + 0, //=Any file + 0, + iOdt->RootUid(), + iOdt->ProviderUid(), + iOdt->ThemeUid(),0,ETrue, + iOdt->ThemeFullName(), + (TLanguage)( iOdt->OdtLanguage() ) ); + + iDefinitionRepository.RegisterNotification( info ); + } + else if( iInstallationType == EInstallationTypeUpdate ) + { + NotifyOdtUpdatedL(); + } + } + +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::CompleteRequestL(): - configuration %d was successfully installed (EAsynchronousObject)" ), + iOdt->ThemeUid() ); + } +#endif + } + else if( aReturnMessage == EhspsInstallPhaseSuccess ) + { + iResult->iIntValue1 = iInstallationPhase; + } + else if( aReturnMessage == EhspsServiceRequestSheduled ) + { + complete = EFalse; + } + else + { + // installation failed, resetting + // system error and xuikon error are written in iResult when error was encountered + iInstallationPhase = EhspsPhaseIdle; + RollBackL ( *iOdt ); + iDefinitionRepository.Unlock(); + } + + if ( complete ) + { + User::RequestComplete( iRequestStatus, (TInt)aReturnMessage ); + } + } + break; + default: + { + if( wasLocked ) + { + CleanupStack::Pop( &iDefinitionRepository ); + } + + User::Leave( KErrCancel ); + } + break; + } + + if( wasLocked ) + { + CleanupStack::Pop( &iDefinitionRepository ); + } + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::IsPluginUsedInAppConfsL +// ----------------------------------------------------------------------------- +// +TBool ChspsInstallationHandler::IsPluginUsedInAppConfsL() + { + TBool isUsed = EFalse; + + const TInt KArrayGranularity = 3; + CArrayPtrSeg* activeAppConfs = new ( ELeave ) CArrayPtrSeg( KArrayGranularity ); + CleanupStack::PushL( activeAppConfs ); + + // Retrieve active application configurations. These are not owned! + GetActiveAppConfsL( *activeAppConfs ); + + // Loop found headers + for( TInt i = 0; i < activeAppConfs->Count(); i++ ) + { + ChspsODT* const header = (*activeAppConfs)[i]; + if( header ) + { + // Clone header to avoid modification of original + ChspsODT* odt = header->CloneL(); + CleanupStack::PushL( odt ); + + // Get full ODT instance with DOM data + User::LeaveIfError( iDefinitionRepository.GetOdtL( *odt ) ); + + // Get all plugin instances with the configuration UID that was just installed + RArray pluginIds; + CleanupClosePushL( pluginIds ); + hspsServerUtil::GetPluginIdsByUidL( + *odt, + TUid::Uid( iThemeUid ), + pluginIds ); + isUsed = ( pluginIds.Count() > 0 ); + CleanupStack::PopAndDestroy(); + + CleanupStack::PopAndDestroy( odt ); + + if ( isUsed ) + { + break; + } + } + } + + + + CleanupStack::PopAndDestroy( activeAppConfs ); + + return isUsed; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::NotifyOdtUpdatedL +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::NotifyOdtUpdatedL() + { + // Nothing to do if notifications disabled. + if( iDisableNotifications ) + { + return; + } + + // This method should only be called when type is update. + if( iInstallationType != EInstallationTypeUpdate ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::NotifyOdtUpdatedL(): Error: Installation type is not update." ) ); + } +#endif + + return; + } + + // Sanity check. + if( !iOdt ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::NotifyOdtUpdatedL(): Error: iOdt == NULL." ) ); + } +#endif + + return; + } + + const TInt KArrayGranularity = 2; + CArrayPtrSeg* activeAppConfs = new ( ELeave ) CArrayPtrSeg( KArrayGranularity ); + CleanupStack::PushL( activeAppConfs ); + + // Retrieve active application configurations. These are not owned! + GetActiveAppConfsL( *activeAppConfs ); + + // Notification list. + RArray notifications; + CleanupClosePushL( notifications ); + + // Construct notifications for every changed plugin id + // in every active application configuration. + for( TInt i = 0; i < activeAppConfs->Count(); i++ ) + { + ChspsODT* const activeODT = (*activeAppConfs)[i]; + + // Sanity check. + if( !activeODT ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::NotifyOdtUpdatedL(): Error: active ODT list contains NULL." ) ); + } +#endif + + continue; + } + + // Clone activeOdt to avoid modification of original. + ChspsODT* fullODT = activeODT->CloneL(); + CleanupStack::PushL( fullODT ); + + User::LeaveIfError( iDefinitionRepository.GetOdtL( *fullODT ) ); + + RArray pluginIds; + CleanupClosePushL( pluginIds ); + + // Get plugin ids. + hspsServerUtil::GetPluginIdsByUidL( *fullODT, + TUid::Uid( iOdt->ThemeUid() ), + pluginIds ); + + // Construct notifications. One for each plugin instance + // that is affected by update. + for( TInt j = 0; j < pluginIds.Count(); j++ ) + { + ThspsRepositoryInfo info( + ThspsRepositoryEvent( EhspsODTUpdated ), + fullODT->RootUid(), + fullODT->ThemeUid(), + 0, //=Any file + 0, + iOdt->RootUid(), + iOdt->ProviderUid(), + iOdt->ThemeUid(), + pluginIds[j], + EFalse, + KNullDesC(), + (TLanguage)( fullODT->OdtLanguage() ) ); + + notifications.Append( info ); + } + + CleanupStack::PopAndDestroy(); // pluginIds. + CleanupStack::PopAndDestroy( fullODT ); + fullODT = NULL; + + // Send applications notifications in one group. + for( TInt k = 0; k < notifications.Count(); k++ ) + { + // If last... + if( k == notifications.Count() - 1 ) + { + // ... Modify accordingly. + notifications[ k ].iLastNotification = ETrue; + } + + // Send. + iDefinitionRepository.RegisterNotification( notifications[ k ] ); + } + + // Clean notifications list. + notifications.Reset(); + } + + CleanupStack::PopAndDestroy(); // notifications. + CleanupStack::PopAndDestroy( activeAppConfs ); + activeAppConfs = NULL; + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::GetActiveAppConfsL +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::GetActiveAppConfsL( CArrayPtrSeg& aActiveAppConfs ) + { + const TInt count = iHeaderListCache.Count(); + for( TInt i = 0; i < count; i++ ) + { + ChspsODT* header = iHeaderListCache.At( i ); + + if( header && header->ConfigurationType() == EhspsAppConfiguration ) + { + // Check if application configuration is active. + TInt tmp = 0; + if ( iCentralRepository.Get( header->RootUid(), tmp ) == KErrNone ) + { + if( tmp == header->ThemeUid() ) + { + // Active application configuration found. + aActiveAppConfs.AppendL( header ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// Saves ODT itself as an resource +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::SetODTAsResourceL( ChspsODT& aOdt ) + { + TInt errorCode = KErrNone; + + ChspsResource* res = ChspsResource::NewL(); + CleanupStack::PushL( res ); + + ThspsLockingPolicy lockingPolicy = EhspsUnlocked; + if ( aOdt.Flags() & EhspsThemeStatusLicenceeDefault ) + { + lockingPolicy = EhspsLocked; + } + + // ODT-resource is handled as a cached resource + res->SetLockingPolicy( lockingPolicy ); + res->SetResourceType( EResourceODT ); + res->SetResourceIdL( aOdt.ThemeShortName() ); + //res->SetFileNameL( filepath ); will be set by the repository + res->SetMimeTypeL(TDataType( KUnknownMimeType )); + res->SetConfigurationUid( aOdt.ThemeUid() ); + + // Creates a path for given ODT + iDefinitionRepository.MakeODTPathL( aOdt, *res ); + + aOdt.AddResourceL( res ); + + CleanupStack::Pop(res); + + User::LeaveIfError( errorCode ); + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ActivateThemeL() +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ActivateThemeL() + { + const TUint32 fullMask = 0xFFFFFFFF; + RArray res; + CleanupClosePushL( res ); + + TInt errorCode = KErrNone; + iCentralRepository.FindL( iOdt->RootUid(), fullMask, res ); + if ( res.Count() == 0 ) + { + errorCode = iCentralRepository.Create( iOdt->RootUid(), iOdt->ThemeUid() ); + } + else + { + errorCode = iCentralRepository.Set( iOdt->RootUid(), iOdt->ThemeUid() ); + } + if ( !errorCode ) + { + TUint flags = iOdt->Flags(); + iOdt->SetFlags( flags | EhspsThemeStatusActive ); + + // If not processing ROM installations + if ( !iDisableNotifications ) + { + // inform for cache update to the repository so that everyone will know + // about the change + ThspsRepositoryInfo info( EhspsODTActivated ); + iDefinitionRepository.RegisterNotification( info ); + } + } + res.Close(); + CleanupStack::PopAndDestroy(); //res + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::OnStartElementL +// Verifies that the installer is able to parse the manifest file, +// parses language specifications and resources +// ----------------------------------------------------------------------------- +// + void ChspsInstallationHandler::OnStartElementL( + const RTagInfo& aElement, + const RAttributeArray& aAttributes, + TInt /*aErrorCode*/) + { + TPtrC8 localName = aElement.LocalName().DesC(); + + if( iContent ) + { + delete iContent; + iContent = NULL; + } + + if ( localName == KPackage ) + { + // Check whether the version attribute is specified + TInt argCount = aAttributes.Count(); + if( argCount ) + { + for( TInt argIndex=0; argIndex < argCount; argIndex++ ) + { + const TDesC8& attName = aAttributes[argIndex].Attribute().LocalName().DesC(); + if ( attName.Compare(KPackageVersion) == 0 ) + { + delete iPackageVersion; + iPackageVersion = NULL; + iPackageVersion = HBufC::NewL( KMaxFileName ); + iPackageVersion->Des().Copy( aAttributes[argIndex].Value().DesC() ); + // Is manifest supported by this parser? + iPackageVerSupported = ETrue; //TODO temporarily enable till 0.3 to 1.0 changes have been integrated ( iPackageVersion->Des().Compare(KhspsSupportedManifestVersion) == 0); + break; + } + } + } + } + + else if ( localName == KLocalized ) + { + // From now on, we are parsing filenames of localized resources + iLocalized = ETrue; + } + + else if ( localName == KFileResource ) + { + if ( iMediaType ) + { + delete iMediaType; + iMediaType = NULL; + } + + // Get attributes of the resource element and store them for adding in ::OnEndElementL() + TInt attrCount( aAttributes.Count() ); + for( TInt i=0; i KMaxMediaTypeLength ) + { + length = KMaxMediaTypeLength; + +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::OnStartElementL(): - mediatype was too long!" ) ); + } +#endif + } + + iMediaType = HBufC8::NewL( length ); + iMediaType->Des().Copy( orginalPtr.Left( length ) ); + } + else if ( aAttributes[i].Attribute().LocalName().DesC() == KTag ) + { + delete iResourceTag; + iResourceTag = NULL; + if ( attValueDes8.Length() ) + { + iResourceTag = attValueDes8.Left( KMaxTagsLength ).AllocL(); + } + } + + } // for + + } + + if ( !iMultiInstanceFound ) + { + iMultiInstance = KMultiInstanceDefaultValue; + } + } + +// ----------------------------------------------------------------------------- +// Parsing of the manifest elements. +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::OnEndElementL( const RTagInfo& aElement, TInt /*aErrorCode*/ ) + { + TPtrC8 localName = aElement.LocalName().DesC(); + + if ( localName == KFamily ) + { +#if defined(WINSCW) || defined(__WINS__) + const TPtrC8 familyPtr( iContent->Des() ); + iFamilyMask |= ChspsFamilyListener::GetFamilyType( familyPtr ); +#endif // defined(WINSCW) + } + else if ( localName == KConfigurationType ) + { + // Get configuration type from the manifest + if( *iContent == KManifestTypeApp ) + { + iConfigurationType = EhspsAppConfiguration; + } + else if ( *iContent == KManifestTypeView ) + { + iConfigurationType = EhspsViewConfiguration; + } + else if ( *iContent == KManifestTypeWidget ) + { + iConfigurationType = EhspsWidgetConfiguration; + } + else if( *iContent == KManifestTypeTemplate ) + { + iConfigurationType = EhspsTemplateConfiguration; + } + else + { + User::Leave( KErrNotSupported ); + } + } + else if ( localName == KInterfaceUid ) + { + if( iContent ) + { + // Delete extra whitespaces. + iContent->Des().TrimAll(); + + // Convert to Uint. + User::LeaveIfError( hspsServerUtil::HexString2Uint( *iContent, iRootUid ) ); + ApplyUidRangeTestsL( iRootUid ); + } + } + else if ( localName == KProviderUid ) + { + if( iContent ) + { + // Delete extra whitespaces. + iContent->Des().TrimAll(); + + // Convert to Uint. + User::LeaveIfError( hspsServerUtil::HexString2Uint( *iContent, iProviderUid ) ); + ApplyUidRangeTestsL( iProviderUid ); + } + } + else if ( localName == KThemeUid ) + { + if( iContent ) + { + // Delete extra whitespaces. + iContent->Des().TrimAll(); + + // Convert to Uint. + User::LeaveIfError( hspsServerUtil::HexString2Uint( *iContent, iThemeUid ) ); + ApplyUidRangeTestsL( iThemeUid ); + } + } + else if ( localName == KThemeStatus ) + { + if( *iContent == KStatusNone ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusNone; + } + else if( *iContent == KStatusLicenceeDefault ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusLicenceeDefault; + } + else if( *iContent == KStatusLicenceeRestorable ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusLicenceeRestorable; + iThemeStatus = iThemeStatus | EhspsThemeStatusLicenceeDefault; + } + else if( *iContent == KStatusOperatorDefault ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusOperatorDefault; + } + else if( *iContent == KStatusUserDefault ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusUserDefault; + } + else if( *iContent == KStatusMakeActive ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusMakeActive; + } + else if( *iContent == KStatusLocked ) + { + iThemeStatus = iThemeStatus | EhspsThemeStatusLocked; + } + } + else if ( localName == KThemeFullName ) + { + // Store value of the parsed "fullname" element + if ( iThemeFullName ) + { + delete iThemeFullName; + iThemeFullName = NULL; + } + iThemeFullName = HBufC::NewL( KMaxFileName ); + TInt contentLength = iContent->Des().Length(); + if ( contentLength > KMaxFileName ) + { + contentLength = KMaxFileName; + } + TPtr ptr( iThemeFullName->Des() ); + ptr.Copy( iContent->Des().Left(contentLength) ); + } + else if ( localName == KThemeShortName ) + { + delete iThemeShortName; + iThemeShortName = NULL; + iThemeShortName = HBufC8::NewL( KMaxFileName ); + TPtr8 themeShortNameDes( iThemeShortName->Des() ); + themeShortNameDes = *iContent; + } + else if ( localName == KThemeVersion ) + { + delete iThemeVersion; + iThemeVersion = NULL; + iThemeVersion = HBufC8::NewL( KMaxFileName ); + TPtr8 themeVersionDes( iThemeVersion->Des() ); + themeVersionDes = *iContent; + } + else if ( localName == KThemeDesc ) + { + if ( iContent ) + { + delete iThemeDesc; + iThemeDesc = NULL; + iThemeDesc = HBufC8::NewL( KMaxDescLength ); + TPtr8 descPtr8( iThemeDesc->Des() ); + descPtr8.Copy( (*iContent).Left( KMaxDescLength ) ); + } + } + else if ( localName == KFileLogo ) + { + if ( iContent ) + { + // Get possible file references and add them to the + // resource array with a logo tag + HBufC* result = NULL; + ParseIconDeclarationL( + *iContent, + KObjectAttrTagLogo, + result ); + if ( result ) + { + // Store logo declaration + CleanupStack::PushL( result ); + iOdt->SetLogoFileL( *result ); + CleanupStack::PopAndDestroy(); + } + } + } + else if ( localName == KFilePreview ) + { + if ( iContent ) + { + // Get possible file references and add them to the + // resource array with a preview tag + HBufC* result = NULL; + ParseIconDeclarationL( + *iContent, + KObjectAttrTagPreview, + result + ); + if ( result ) + { + // Store preview declaration + CleanupStack::PushL( result ); + iOdt->SetPreviewFileL( *result ); + CleanupStack::PopAndDestroy(); + } + } + } + else if ( localName == KFileXML ) + { + delete iXmlFile; + iXmlFile = NULL; + iXmlFile = HBufC::NewL( KMaxFileName ); + TPtr fileDes( iXmlFile->Des() ); + + fileDes.Copy( iThemeFilePath ); + HBufC* data = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *iContent ); + fileDes.Append( *data ); + delete data; + + if( !BaflUtils::FileExists( iFsSession, fileDes ) ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::OnEndElementL(): - XML file does not exist '%S'" ), + &fileDes ); + } +#endif + + iFileNotFound = ETrue; + iResult->iXuikonError = KErrXmlFileNotFound; + } + } + else if ( localName == KFileDTD ) + { + // Parse name of the DTD files + if ( !iContent || iContent->Length() < 1 ) + { + User::Leave( KErrArgument ); + } + + if ( iDtdFile ) + { + delete iDtdFile; + iDtdFile = 0; + } + iDtdFile = HBufC::NewL( iContent->Length() ); + iDtdFile->Des().Copy( iContent->Des() ); + } + else if ( localName == KFileResource ) + { + // Following attributes are parsed in OnStartElement callback + TPtrC8 mediaPtr; + if ( iMediaType ) + { + mediaPtr.Set( iMediaType->Des() ); + } + TPtrC8 tagsPtr; + if ( iResourceTag ) + { + tagsPtr.Set( iResourceTag->Des() ); + } + + // Parse name of the resource file and make 8bit to 16bit conversion + HBufC* fileName = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *iContent ); + if ( !fileName || fileName->Des().Length() < 1 ) + { + User::Leave( KErrArgument ); + } + CleanupStack::PushL( fileName ); + + // If parsing localized resources + if ( iLocalized ) + { + // Add locale specific resources into temp array + AddResourceL( + *iTempLocalizedResourceList, + *fileName, + ELangNone, + EResourceOther, + mediaPtr, + tagsPtr ); + } + else + { + // If Xuikon resource + TFileName interfacePath( GetInterfacePath() ); + HBufC* resourceFile = NULL; + if( interfacePath.Length() ) + { + _LIT(KSubFolder, "00\\"); + resourceFile = HBufC::NewLC( interfacePath.Length() + KSubFolder().Length() + fileName->Length() ); + resourceFile->Des().Copy( interfacePath ); + resourceFile->Des().Append( KSubFolder ); + resourceFile->Des().Append( *fileName ); + } + else + { + resourceFile = HBufC::NewLC( iThemeFilePath.Length() + fileName->Length() ); + resourceFile->Des().Copy( iThemeFilePath ); + resourceFile->Des().Append( *fileName ); + } + + // Validate the file + if( !BaflUtils::FileExists( iFsSession, *resourceFile ) ) + { +#ifdef HSPS_LOG_ACTIVE + TBuf8 name8; + name8.Copy( *resourceFile ); + if( iLogBus ) + { + iLogBus->LogText( _L8( "ChspsInstallationHandler::OnEndElementL(): - resource file does not exist '%S'" ), + &name8 ); + } +#endif + iFileNotFound = ETrue; + iResult->iXuikonError = KErrResourceFileNotFound; + } + + // Add common resources + AddResourceL( + *iResourceList, + *resourceFile, + ELangNone, + EResourceOther, + mediaPtr, + tagsPtr ); + + CleanupStack::PopAndDestroy( resourceFile ); + } + + CleanupStack::PopAndDestroy( fileName ); + + if ( iMediaType ) + { + delete iMediaType; + iMediaType = NULL; + } + if ( iResourceTag ) + { + delete iResourceTag; + iResourceTag = NULL; + } + } + else if ( localName == KMultiInstance) + { + iMultiInstanceFound = ETrue; + if( iContent ) + { + // Delete extra whitespaces. + iContent->Des().TrimAll(); + + // Convert to int + TLex8 lex( iContent->Des() ); + TInt err = lex.Val( iMultiInstance ); + // iContent is not a number - check for strings + if ( err != KErrNone ) + { + if ( iContent->CompareF( KMultiInstanceUnlimited ) + == KErrNone ) + { + iMultiInstance = KMultiInstanceUnlimitedValue; + } + else if ( iContent->CompareF( KMultiInstanceHidden ) == + KErrNone ) + { + iMultiInstance = KMultiInstanceHiddenValue; + } + else + { + User::Leave( KErrArgument ); + } + } + // iContent is a number - check whether it is valid + else + { + if ( ( iMultiInstance < KMultiInstanceMinimumCountValue ) || + ( iMultiInstance > KMultiInstanceMaximumCountValue ) ) + { + User::Leave( KErrArgument ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// The needed memory for each element information is reserved here. +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::OnContentL(const TDesC8& aBytes, TInt aErrorCode) + { + if ( aErrorCode == KErrNone ) + { + if ( !iContent ) + { + iContent = HBufC8::NewL( aBytes.Size() ); + *iContent = aBytes; + } + else + { + iContent = iContent->ReAllocL( iContent->Size() + aBytes.Size() ); + TPtr8 c( iContent->Des() ); + c.Append( aBytes ); + } + } + + } + +// ----------------------------------------------------------------------------- +// Disables "configuration was installed" notifications +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::DisableNotifications() + { + iDisableNotifications = ETrue; + } + +// ----------------------------------------------------------------------------- +// Finds locale specific subdirectories and DTD resources and appends those +// into the resource array +// Should be executed prior to the CheckHeader method! +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::AddHspsLocalesV2L( + const TDesC& aPath ) + { + // Find all locale specific subfolders + TFindFile fileFinder( iFsSession ); + _LIT( KFilter, "*" ); + CDir* fileList( NULL ); + fileFinder.FindWildByDir( KFilter, aPath, fileList ); + if ( fileList ) + { + CleanupStack::PushL( fileList ); + TFileName localePath; + for( TInt i = 0; i < fileList->Count(); i++ ) + { + const TEntry& entry = (*fileList)[i]; + if ( entry.IsDir() ) + { + TInt languageIndex = 0; + TLex lex( entry.iName ); + TInt error = lex.Val( languageIndex ); + + // See enumarations from e32lang.h + if( !error && languageIndex >= ELangTest ) + { + // If we found the first language specification + if ( !iDefaultSpecificationSet ) + { + // Assume this is the default language shown incase + // there is no locale for the active UI language + iDefaultSpecification = (TLanguage)languageIndex; + iDefaultSpecificationSet = ETrue; + } + + // Setup a path to the subdirectory + localePath.Copy( aPath ); + localePath.Append( entry.iName ); + localePath.Append( KPathDelim ); + + // Find localized resources + AddLocalizedResourcesDTDV2L( + localePath, + (TLanguage)languageIndex ); + } + } + + } + CleanupStack::PopAndDestroy( fileList ); + fileList = NULL; + } + + // If no DTD files were found + if ( iDefaultSpecification != ELangTest || !iDefaultSpecificationSet ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L8( "ChspsInstallationHandler::AddHspsLocalesV2L(): - mandatory test locale is missing!" ) ); + } +#endif + // Halt installation, test language was not found + User::Leave( KErrNotFound ); + } + } + +// ----------------------------------------------------------------------------- +// Adds localized resources from the provided subdirectory +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::AddLocalizedResourcesDTDV2L( + const TDesC& aPath, + const TLanguage aLanguage ) + { + // Append path with the default name of DTD files + const TInt len = aPath.Length() + iDtdFile->Des().Length(); + HBufC* dtdPath = HBufC::NewLC( len ); + dtdPath->Des().Copy( aPath ); + dtdPath->Des().Append( *iDtdFile ); + + // Check whether the file exists + if( !BaflUtils::FileExists( iFsSession, *dtdPath ) ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::AddLocalizedResourcesL(): - DTD file was not found '%S'" ), + &dtdPath ); + } +#endif + iFileNotFound = ETrue; + iResult->iXuikonError = KErrDtdFileNotFound; + User::Leave( KErrNotFound ); + } + + // Store locale specific DTD files into the resource array + TPtrC8 mediaType; + TPtrC8 tags; + AddResourceL( + *iResourceList, + *dtdPath, + aLanguage, + EResourceDTD, + mediaType, + tags ); + + CleanupStack::PopAndDestroy( dtdPath ); + } + +void ChspsInstallationHandler::AddInterfaceResourcesV2L( + const TDesC& aPath ) + { + // Find all locale specific subfolders + TFindFile fileFinder( iFsSession ); + _LIT( KFilter, "*" ); + CDir* fileList( NULL ); + fileFinder.FindWildByDir( KFilter, aPath, fileList ); + if ( fileList ) + { + CleanupStack::PushL( fileList ); + TFileName localePath; + for( TInt i = 0; i < fileList->Count(); i++ ) + { + const TEntry& entry = (*fileList)[i]; + if ( entry.IsDir() ) + { + TInt languageIndex = 0; + TLex lex( entry.iName ); + TInt error = lex.Val( languageIndex ); + + // See enumarations from e32lang.h + if( !error && languageIndex >= ELangTest ) + { + // If we found the first language specification + if ( !iDefaultSpecificationSet ) + { + // Assume this is the default language shown incase + // there is no locale for the active UI language + iDefaultSpecification = (TLanguage)languageIndex; + iDefaultSpecificationSet = ETrue; + } + + // Setup a path to the subdirectory + localePath.Copy( aPath ); + localePath.Append( entry.iName ); + localePath.Append( KPathDelim ); + + // Find localized resources + AddLocalizedResourcesV2L( + localePath, + (TLanguage)languageIndex ); + } + } + + } + CleanupStack::PopAndDestroy( fileList ); + fileList = NULL; + } + + // If no DTD files were found + if ( iDefaultSpecification != ELangTest || !iDefaultSpecificationSet ) + { + // Halt installation, test language was not found + User::Leave( KErrNotFound ); + } + } + +void ChspsInstallationHandler::AddLocalizedResourcesV2L( + const TDesC& aPath, + const TLanguage aLanguage ) + { + TFindFile fileFinder( iFsSession ); + _LIT( KFilter, "*" ); + CDir* fileList( NULL ); + fileFinder.FindWildByDir( KFilter, aPath, fileList ); + if ( fileList ) + { + CleanupStack::PushL( fileList ); + + TFileName localePath; + ChspsResource* resource = NULL; + for( TInt i = 0; i < fileList->Count(); i++ ) + { + const TEntry& entry = (*fileList)[i]; + if ( !entry.IsDir() ) + { + TParsePtrC parserPtr( entry.iName ); + TFileName modName = hspsServerUtil::GetFixedOdtName( entry.iName ); + + TBool addingOk = EFalse; + for( TInt resourceIndex=0; resourceIndex < iTempLocalizedResourceList->Count(); resourceIndex++ ) + { + resource = iTempLocalizedResourceList->At( resourceIndex ); + if( modName.CompareF( resource->FileName() ) == 0 ) + { + addingOk = ETrue; + break; + } + } + if ( addingOk ) + { + HBufC* resourcePath = HBufC::NewLC( aPath.Length() + entry.iName.Length() ); + resourcePath->Des().Copy( aPath ); + resourcePath->Des().Append( entry.iName ); + + TPtrC8 mimeType; + TPtrC8 tag; + + HBufC8* tagBuf8 = NULL; + if ( resource->Tags().Length() ) + { + tagBuf8 = HBufC8::NewLC( resource->Tags().Length() ); + tagBuf8->Des().Copy( resource->Tags() ); + tag.Set( tagBuf8->Des() ); + } + + // Add localized files into the resource array + AddResourceL( + *iResourceList, + *resourcePath, + aLanguage, + EResourceOther, + mimeType, + tag ); + + if ( tagBuf8 ) + { + CleanupStack::PopAndDestroy( tagBuf8 ); + } + CleanupStack::PopAndDestroy( resourcePath ); + } + } + } + + CleanupStack::PopAndDestroy( fileList ); + fileList = NULL; + } + } + +// ----------------------------------------------------------------------------- +// Finds locale specific subdirectories and resources and appends those +// into the resource array +// Should be executed prior to the CheckHeader method! +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::AddLocalesL( + const TDesC& aPath ) + { + // Find all locale specific subfolders + TFindFile fileFinder( iFsSession ); + _LIT( KFilter, "*" ); + CDir* fileList( NULL ); + fileFinder.FindWildByDir( KFilter, aPath, fileList ); + if ( fileList ) + { + CleanupStack::PushL( fileList ); + TFileName localePath; + for( TInt i = 0; i < fileList->Count(); i++ ) + { + const TEntry& entry = (*fileList)[i]; + if ( entry.IsDir() ) + { + TInt languageIndex = 0; + TLex lex( entry.iName ); + TInt error = lex.Val( languageIndex ); + + // See enumarations from e32lang.h + if( !error && languageIndex >= ELangTest ) + { + // If we found the first language specification + if ( !iDefaultSpecificationSet ) + { + // Assume this is the default language shown incase + // there is no locale for the active UI language + iDefaultSpecification = (TLanguage)languageIndex; + iDefaultSpecificationSet = ETrue; + } + + // Setup a path to the subdirectory + localePath.Copy( aPath ); + localePath.Append( entry.iName ); + localePath.Append( KPathDelim ); + + // Find localized resources + AddLocalizedResourcesL( + localePath, + (TLanguage)languageIndex ); + } + } + + } + CleanupStack::PopAndDestroy( fileList ); + fileList = NULL; + } + + // If no DTD files were found + if ( iDefaultSpecification != ELangTest || !iDefaultSpecificationSet ) + { + // Halt installation, test language was not found + User::Leave( KErrNotFound ); + } + } + +// ----------------------------------------------------------------------------- +// Adds localized resources from the provided subdirectory +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::AddLocalizedResourcesL( + const TDesC& aPath, + const TLanguage aLanguage ) + { + // If FileDTD was declared + if ( iDtdFile && iDtdFile->Des().Length() ) + { + // Append path with the default name of DTD files + const TInt len = aPath.Length() + iDtdFile->Des().Length(); + HBufC* dtdPath = HBufC::NewLC( len ); + dtdPath->Des().Copy( aPath ); + dtdPath->Des().Append( *iDtdFile ); + + // Check whether the file exists + if( !BaflUtils::FileExists( iFsSession, *dtdPath ) ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::AddLocalizedResourcesL(): - DTD file was not found '%S'" ), + &dtdPath ); + } +#endif + iFileNotFound = ETrue; + iResult->iXuikonError = KErrDtdFileNotFound; + User::Leave( KErrNotFound ); + } + + // Store locale specific DTD files into the resource array + TPtrC8 mediaType; + TPtrC8 tagsPtr; + AddResourceL( + *iResourceList, + *dtdPath, + aLanguage, + EResourceDTD, + mediaType, + tagsPtr ); + + CleanupStack::PopAndDestroy( dtdPath ); + } + + // Store locale specific resources if the "localization" element has been declared in XML definition + ChspsResource* resource = NULL; + for( TInt resourceIndex=0; resourceIndex < iTempLocalizedResourceList->Count(); resourceIndex++ ) + { + resource = iTempLocalizedResourceList->At( resourceIndex ); + + HBufC* resourcePath = HBufC::NewLC( aPath.Length() + resource->FileName().Length() ); + resourcePath->Des().Copy( aPath ); + resourcePath->Des().Append( resource->FileName() ); + + TDataType dataType( resource->MimeType() ); + TPtrC8 tagsPtr; + if ( iResourceTag ) + { + tagsPtr.Set( iResourceTag->Des() ); + } + + // Add localized files into the resource array + AddResourceL( + *iResourceList, + *resourcePath, + aLanguage, + EResourceOther, + dataType.Des8(), + tagsPtr + ); + + CleanupStack::PopAndDestroy( resourcePath ); + } + + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ApplyUidRangeTestsL +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ApplyUidRangeTestsL( const TUint aUid ) + { + // Check for TUint to TInt conversion + const TInt intValue( aUid ); + if ( intValue < 1 ) + { + // Check UID ranges in the manifest file +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( _L( "ChspsInstallationHandler::ApplyUidRangeTestsL() - Invalid UID value '%d'" ), aUid ); + } +#endif + User::Leave( KErrArgument ); + } + } + + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::ParseIconDeclarationL +// ----------------------------------------------------------------------------- +// +void ChspsInstallationHandler::ParseIconDeclarationL( + HBufC8& aValue8, + const TDesC8& aTag, + HBufC*& aResultString ) + { + // 8bit > 16bit conversion + TInt size = KMaxFileName - iThemeFilePath.Length(); + aResultString = HBufC::NewLC( KMaxFileName ); + TPtr resultPtr( aResultString->Des() ); + resultPtr.Copy( aValue8.Des().Left( size ) ); + + // check whether skin/mif/uid declarations were used + TFileName filename; + if ( hspsServerUtil::IsFile( resultPtr, filename ) ) + { + // check whether the file reference is valid + TPath fullname; + fullname.Copy( iThemeFilePath ); + fullname.Append( filename ); + + if( !BaflUtils::FileExists( iFsSession, fullname ) ) + { +#ifdef HSPS_LOG_ACTIVE + if( iLogBus ) + { + iLogBus->LogText( + _L( "ChspsInstallationHandler::ParseIconDeclarationL(): - '%S' was not found " ), + &fullname ); + } +#endif +// User::Leave( KErrNotFound ); + } + else + { + // Store logo as a common resource file + TPtrC8 mediaType; + AddResourceL( + *iResourceList, + fullname, + ELangNone, + EResourceOther, + mediaType, + aTag ); + + // get offset of the filename + TInt nameOffset = resultPtr.FindF( (TPtrC)filename ); + if ( nameOffset >= 0 ) + { + // get relative path under the HSPS + if ( iRootUid < 1 || iProviderUid < 1 || iThemeUid < 1 || !iThemeVersion || iThemeVersion->Des().Length() < 1 ) + { + User::Leave( KErrArgument ); + } + // 8bit > 16bit + HBufC* verBuf = HBufC::NewLC( iThemeVersion->Des().Length() ); + verBuf->Des().Copy( *iThemeVersion ); + _LIT(KPathFormat, "%D\\%D\\%D\\%S\\sources\\"); + TFileName relativePath; + relativePath.Format( + KPathFormat, + iRootUid, + iProviderUid, + iThemeUid, + verBuf ); + if ( resultPtr.Length() + relativePath.Length() > KMaxFileName - 1 ) + { + User::Leave( KErrArgument ); + } + resultPtr.Insert( nameOffset, relativePath ); + CleanupStack::PopAndDestroy( verBuf ); + } + + } + + } // IsFile + + CleanupStack::Pop( aResultString ); + } + +// end of file