--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/homescreenpluginsrv/hspsmanager/src/hspsmaintenancehandler.cpp Thu Dec 17 08:54:17 2009 +0200
@@ -0,0 +1,4602 @@
+/*
+* Copyright (c) 2002-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: Implementation of HSPS MhspsMaintenanceService interface defined
+* in hspsThemeManagement.h. For details, see header file.
+*
+*/
+
+
+#include <centralrepository.h>
+
+#include "hsps_builds_cfg.hrh"
+#include "hspsthememanagement.h"
+#include "hspsdefinitionrepository.h"
+#include "hspsresource.h"
+#include "hspsresult.h"
+#include "hspspluginidlist.h"
+#include "hspsodt.h"
+#include "hspsmaintenancehandler.h"
+#include "hspsthemeserver.h"
+#include "hspsinstallationhandler.h"
+#include "hspssecurityenforcer.h"
+#include "hspsconfiguration.h"
+#include "hspsdomdocument.h"
+#include "hspsdomlist.h"
+#include "hspsdomdepthiterator.h"
+#include "hspsdomnode.h"
+#include "hspsdomattribute.h"
+#include "hspsmanifest.h"
+#include "hspsserverutil.h"
+#include "hspsthemeserversession.h"
+
+#ifdef HSPS_LOG_ACTIVE
+#include <hspsodtdump.h>
+#include <hspslogbus.h>
+#endif
+
+
+_LIT(KSourcesFolder, "\\sources\\");
+_LIT(KLocalesFolder, "\\locales\\");
+
+const TInt KAdditionalRequiredDiskSpace = 256 * 1024; /// 256KB in bytes.
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// Callback function for removing repository lock if error occurs while repository is locked
+// Returns: void
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void UnlockRepository( TAny* aObject )
+ {
+ ChspsDefinitionRepository* DefRep = reinterpret_cast<ChspsDefinitionRepository*>( aObject );
+
+ if( DefRep->Locked() )
+ {
+ DefRep->Unlock();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ResetAndDestroyArray Callback function for cleaning up the CArrayPtr.
+// Returns: void
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void ResetAndDestroyArray( TAny* aArray )
+ {
+ reinterpret_cast<CArrayPtrSeg<HBufC>*>( aArray )->ResetAndDestroy();
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ChspsMaintenanceHandler
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+ChspsMaintenanceHandler::ChspsMaintenanceHandler(
+ ChspsThemeServer& aThemeServer,
+ const TUint aSecureId ):
+ CTimer(EPriorityLow),
+ iLanguage ( aThemeServer.DeviceLanguage() ),
+ iThemeServer( aThemeServer ),
+ iSecureId( aSecureId ),
+ iCentralRepository( aThemeServer.CentralRepository() ),
+ iDefinitionRepository( aThemeServer.DefinitionRepository() ),
+ iSecurityEnforcer( aThemeServer.SecurityEnforcer() ),
+ iHeaderListCache( aThemeServer.HeaderListCache() ),
+ iFileMan( NULL )
+ {
+ iDeliveryCount = 0;
+ iSubscription = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceService::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+ChspsMaintenanceHandler* ChspsMaintenanceHandler::NewL(
+ ChspsThemeServer& aThemeServer,
+ const TUint aSecureId )
+ {
+ ChspsMaintenanceHandler* h = ChspsMaintenanceHandler::NewLC(
+ aThemeServer, aSecureId );
+ CleanupStack::Pop(h);
+ return (h);
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceService::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+ChspsMaintenanceHandler* ChspsMaintenanceHandler::NewLC(
+ ChspsThemeServer& aThemeServer,
+ const TUint aSecureId )
+ {
+ ChspsMaintenanceHandler* h = new (ELeave) ChspsMaintenanceHandler(
+ aThemeServer, aSecureId );
+ CleanupStack::PushL(h);
+ h->ConstructL();
+ return (h);
+ }
+
+// Destructor
+ChspsMaintenanceHandler::~ChspsMaintenanceHandler()
+ {
+ Cancel();
+ if (iHeaderDataList)
+ {
+ iHeaderDataList->ResetAndDestroy();
+ }
+ delete iHeaderDataList;
+ delete iSearchMask;
+ delete iSetMask;
+ delete iResult;
+ delete iFileMan;
+ iDefinitionRepository.UnregisterObserver( *this );
+ }
+
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ConstructL()
+ {
+ // call the base class ConstructL
+ CTimer::ConstructL();
+ iHeaderDataList = new( ELeave ) CArrayPtrSeg<HBufC8>(KHeaderListGranularity);
+ iResult = ChspsResult::NewL();
+ // add this timer to the active scheduler
+ CActiveScheduler::Add(this);
+ iDefinitionRepository.RegisterObserverL( *this );
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ServiceGetListHeadersL
+// Fetches the header list from repository and writes the first header back to the caller
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceGetListHeadersL(const RMessage2& aMessage)
+ {
+ // only allow one request to be submitted at a time
+ // all synch call must use local message pointer variable
+ RMessagePtr2 messagePtr = aMessage;
+ ThspsServiceCompletedMessage ret = EhspsGetListHeadersFailed;
+ iDeliveryCount = 0;
+
+ if (!IsActive() && !iSubscription) // first request
+ {
+ TBuf8<KMaxHeaderDataLength8> searchMaskData;// save a search mask
+ messagePtr.ReadL(1,searchMaskData,0);
+ // constructing iSearcMask -object
+ if (iSearchMask)
+ {
+ delete iSearchMask;
+ iSearchMask = NULL;
+ }
+ iSearchMask = ChspsODT::NewL();
+ iSearchMask->UnMarshalHeaderL(searchMaskData);
+
+ // check the device language
+ iLanguage = iThemeServer.DeviceLanguage();
+ iSearchMask->SetOdtLanguage( (TInt)iLanguage );
+
+ // now there is a subscription
+ iSubscription = ETrue;
+ // fetch the header list from repository
+ ret = hspsGetListHeaders(searchMaskData, *iHeaderDataList);
+ if (ret == EhspsGetListHeadersSuccess)
+ {
+ TInt count = iHeaderDataList->Count();
+ // result informs list count in query
+ iResult->iIntValue1 = count;
+ if ( !count )
+ {
+ ret = EhspsGetListHeadersEmpty;
+ }
+ }
+
+ CompleteRequest(ret, messagePtr);
+ }
+ else
+ {
+ iResult->iSystemError = KErrInUse;
+ iResult->iSystemError = KErrInUse;
+ CompleteRequest( EhspsServiceRequestError, iMessagePtr );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ServiceGetNextHeaderL
+// Writes back to the caller the next headers in the header list one at a time
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceGetNextHeaderL(const RMessage2& aMessage)
+ {
+ // only allow one request to be submitted at a time
+ iRequestMessage = (ThspsServiceRequestMessage) aMessage.Function();
+ iCompletedMessage = EhspsGetListHeadersUpdate;
+ // now using message pointer as member variable because of asynch call
+ iMessagePtr = aMessage;
+ if ( !IsActive() && iSubscription) // requesting next as should
+ {
+ // is there headers to delivere left
+ if (iHeaderDataList->Count() > iDeliveryCount)
+ {
+ // Handle copying of logo icon resources
+ CopyIconsToHomescreenL( aMessage.SecureId().iId );
+
+ // at least one header on the list
+ TPtr8 bufPtr( iHeaderDataList->At(iDeliveryCount)->Des() );
+ iMessagePtr.WriteL(2, bufPtr, 0);
+ // add list count
+ iDeliveryCount++;
+ // deliver a list item
+ CompleteRequest( EhspsGetListHeadersUpdate, iMessagePtr );
+ }
+ }
+ else
+ {
+ iResult->iSystemError = KErrInUse;
+ iResult->iXuikonError = KErrPermissionDenied;
+ CompleteRequest( EhspsServiceRequestError, iMessagePtr );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::CopyIconsToHomescreenL
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::CopyIconsToHomescreenL(
+ const TUint aAppUid )
+ {
+ HBufC8* headerData = iHeaderDataList->At(iDeliveryCount);
+ ChspsODT* header = ChspsODT::UnMarshalHeaderLC( headerData->Des() );
+ if ( iServerSession && header )
+ {
+ if( header->LogoFile().Length() )
+ {
+ // If a file reference was found from the logo declaration
+ TFileName filename;
+ if ( hspsServerUtil::IsFile( header->LogoFile(), filename ) )
+ {
+ if ( !iFileMan )
+ {
+ iFileMan = CFileMan::NewL( iServerSession->FileSystem() );
+ }
+
+ // Get client's private directory:
+ // We should use some common directory if there are more than one SAPI clients,
+ // for now we can copy files to AI3's private folder
+ _LIT( KPrivatePath, "c:\\private\\%X\\");
+ TPath privatePath;
+ privatePath.Format( KPrivatePath, aAppUid );
+
+ // Append private path to the logo file reference
+ TInt offset = header->LogoFile().FindF( filename );
+ if ( offset >= 0 )
+ {
+ // Insert private path prior to the file reference
+ HBufC* logoBuf = HBufC::NewLC(
+ privatePath.Length() + header->LogoFile().Length() );
+ logoBuf->Des().Copy( header->LogoFile() );
+ logoBuf->Des().Insert( offset, privatePath );
+ header->SetLogoFileL( logoBuf->Des() );
+ CleanupStack::PopAndDestroy( logoBuf );
+
+ // Replace the serialized header descriptor
+ HBufC8* newHeaderData = header->MarshalHeaderL();
+ CleanupStack::PushL( newHeaderData );
+ iHeaderDataList->InsertL(
+ iDeliveryCount,
+ newHeaderData );
+ CleanupStack::Pop( newHeaderData );
+ delete headerData;
+ headerData = 0;
+ iHeaderDataList->Delete( iDeliveryCount + 1 );
+ }
+
+ // Set target directory for file copying
+ TPath targetPath;
+ targetPath.Copy( privatePath );
+ targetPath.Append( filename );
+
+ // Set source directory for file copying
+ TFileName sourceFile;
+ _LIT( KThemesFolder, "themes\\" );
+ iServerSession->FileSystem().SessionPath( sourceFile );
+ sourceFile.Append( KThemesFolder );
+ sourceFile.Append( filename );
+
+ // Create the target path and copy files when required
+ hspsServerUtil::CopyResourceFileL(
+ iServerSession->FileSystem(),
+ *iFileMan,
+ targetPath,
+ sourceFile );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( header );
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::SetServerSession
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::SetServerSession(
+ ChspsThemeServerSession* aServerSession )
+ {
+ iServerSession = aServerSession;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ServiceSetActiveThemeL
+// Sets the active theme and writes back that themes header data
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceSetActiveThemeL(const RMessage2& aMessage)
+ {
+ ThspsServiceCompletedMessage ret = EhspsSetActiveThemeFailed;
+ // using message pointer as a local variable because of a synch call
+ RMessagePtr2 messagePtr = aMessage;
+
+ TBuf8<KMaxHeaderDataLength8> setMaskData;
+ messagePtr.ReadL(1,setMaskData,0);
+ //constructing setMask -object
+ if( iSetMask )
+ {
+ delete iSetMask;
+ iSetMask = NULL;
+ }
+ iSetMask = ChspsODT::NewL();
+ iSetMask->UnMarshalHeaderL( setMaskData );
+
+ // calling actual activation
+ ChspsODT* odt;
+ odt = ChspsODT::NewL();
+ CleanupStack::PushL(odt);
+
+
+ iDefinitionRepository.Lock();
+ // In case of error. repository is unlocked
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+ ret = hspsSetActiveTheme( *iSetMask, *odt );
+ if ( ret == EhspsSetActiveThemeSuccess )
+ {
+ // Store updated ODT to definition repository
+ iDefinitionRepository.SetOdtL( *odt );
+
+ HBufC8* headerdata;
+ headerdata = odt->MarshalHeaderL();
+ if (headerdata != NULL)
+ {
+ // Write activated ODT header data to client
+ CleanupStack::PushL(headerdata);
+ messagePtr.WriteL(2,headerdata->Des(),0);
+ CleanupStack::PopAndDestroy(headerdata);
+
+ ThspsRepositoryInfo info( EhspsODTActivated );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+
+
+ CleanupStack::Pop(odt);
+ if (odt)
+ {
+ delete odt;
+ odt = NULL;
+ }
+
+ // complete the message
+ CompleteRequest(ret, messagePtr );
+ }
+
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ServiceRestoreDefaultL
+// Restores the default theme according to the information in aMessage and writes
+// back restored themes header data.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceRestoreDefaultL( const RMessage2& aMessage )
+ {
+ ThspsServiceCompletedMessage ret = EhspsRestoreDefaultFailed;
+ // using message pointer as a local variable because of synch call
+ RMessagePtr2 messagePtr = aMessage;
+ // TIpcArgs(TInt aAppUid, &aSetMaskData, &aHeaderData)
+ TBuf8<KMaxHeaderDataLength8> setMaskData;
+ messagePtr.ReadL( 1, setMaskData, 0 );
+ //constructing setMask -object
+ if ( iSetMask )
+ {
+ delete iSetMask;
+ iSetMask = NULL;
+ }
+ iSetMask = ChspsODT::NewL();
+ iSetMask->UnMarshalHeaderL( setMaskData );
+ ChspsODT* odt;
+ odt = ChspsODT::NewL();
+ CleanupStack::PushL( odt );
+
+ if ( !iDefinitionRepository.Locked() )
+ {
+ iDefinitionRepository.Lock();
+ // In case of error. repository is unlocked
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+ // calling actual restoration
+ ret = hspsRestoreDefault( *iSetMask, *odt );
+ if ( ret == EhspsRestoreDefaultSuccess )
+ {
+ HBufC8* headerdata;
+ headerdata = odt->MarshalHeaderL();
+ if (headerdata != NULL)
+ {
+ CleanupStack::PushL( headerdata );
+ messagePtr.WriteL( 2, headerdata->Des(), 0 );
+ CleanupStack::PopAndDestroy( headerdata );
+
+ // inform for cache update to the repository so that everyone will know
+ // about the change
+ ThspsRepositoryInfo info( EhspsCacheUpdate );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+ }
+ else
+ {
+ ret = EhspsRestoreDefaultFailed;
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRestoreDefaultL(): - failed, repository is locked." ) );
+ }
+#endif
+ }
+
+
+ CleanupStack::PopAndDestroy( odt );
+ // complete the message
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ServiceRemoveThemeL
+// Reads ODT from RMessage2 and calls the actual removal method.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceRemoveThemeL( const RMessage2& aMessage )
+ {
+ ThspsServiceCompletedMessage ret = EhspsRemoveThemeFailed;
+ // using message pointer as a local variable because of synch call
+ RMessagePtr2 messagePtr = aMessage;
+
+ // TIpcArgs(TInt aAppUid, &aSetMaskData, &aHeaderData)
+ TBuf8<KMaxHeaderDataLength8> setMaskData;
+ messagePtr.ReadL( 1, setMaskData, 0 );
+
+ //constructing setMask -object
+ if ( iSetMask )
+ {
+ delete iSetMask;
+ iSetMask = NULL;
+ }
+
+ iSetMask = ChspsODT::NewL();
+ iSetMask->UnMarshalHeaderL( setMaskData );
+
+ // calling actual removal
+ ret = hspsRemoveThemeL( *iSetMask );
+
+ // complete the message
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// Appends an application configuration with the provided plugin configuration
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceAddPluginL( const RMessage2& aMessage )
+ {
+ // Defaults
+ ThspsServiceCompletedMessage ret = EhspsAddPluginFailed;
+ iResult->iXuikonError = KErrNotFound;
+ TInt err = KErrNone;
+
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+
+ // IPC slots:
+ // #0) output: externalized ChspsResult for error handling
+ // #1) input: ThpsParamAddPlugin struct
+ // #2) output: added plugin id
+
+ // Get service parameters from IPC slot #1
+ ThpsParamAddPlugin params;
+ TPckg<ThpsParamAddPlugin> packagedStruct(params);
+ aMessage.ReadL(1, packagedStruct);
+ const TInt appUid = params.appUid;
+ const TInt configurationId = params.configurationId;
+ const TInt pluginUid = params.pluginUid;
+ const TInt newPos = params.positionIndex;
+
+ // Application configuration
+ ChspsODT *appODT = NULL;
+ if ( !err )
+ {
+ // Get active application configuration from the central repository
+ TInt appConfUid;
+ err = iCentralRepository.Get( appUid, appConfUid );
+ if ( err || appConfUid < 1 )
+ {
+ err = KErrNotFound;
+ }
+ else
+ {
+ // Get application configuration
+ appODT = ChspsODT::NewL();
+ CleanupStack::PushL( appODT );
+ err = iThemeServer.GetConfigurationL(
+ appUid,
+ appConfUid,
+ *appODT );
+ }
+ }
+
+ // Plugin configuration
+ ChspsODT* pluginODT = NULL;
+ if ( !err )
+ {
+ // Find the plugin configuration (interface is unknown, so 1st argument is set to zero)
+ pluginODT = ChspsODT::NewL();
+ CleanupStack::PushL( pluginODT );
+ err = iThemeServer.GetConfigurationL(
+ 0,
+ pluginUid,
+ *pluginODT );
+ }
+
+ // Check needed space for addition. Returns system wide error code.
+ if( !err )
+ {
+ err = hspsServerUtil::EnoughDiskSpaceAvailableL(
+ *pluginODT,
+ iThemeServer.DeviceLanguage(),
+ iServerSession->FileSystem(),
+ EDriveC,
+ KAdditionalRequiredDiskSpace );
+ }
+
+ // Modifications
+ TInt usedConfId = 0;
+ TInt usedPluginId = 0;
+ if ( !err && appODT && pluginODT )
+ {
+ if ( iDefinitionRepository.Locked() )
+ {
+ // Repository locked
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ // Lock the Plugin Repository (a.k.a. Def.rep)
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // Get used conf & plugin ids
+ GetUsedIdsL(
+ appODT->DomDocument(),
+ usedConfId,
+ usedPluginId );
+
+ // Add the plugin configuration into the application configuration
+ err = AppendConfigurationL(
+ *appODT,
+ *pluginODT,
+ configurationId,
+ newPos,
+ usedConfId,
+ usedPluginId );
+
+#ifdef HSPS_LOG_ACTIVE
+ if( appODT && iLogBus )
+ {
+ ChspsOdtDump::Dump( *appODT, *iLogBus );
+ }
+#endif
+
+ // Stores the new application configuration into the repository
+ if ( !err )
+ {
+ err = iDefinitionRepository.SetOdtL( *appODT );
+ if ( err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceAddPluginL(): - Updating failed with code: %d" ), err );
+ }
+#endif
+ }
+ }
+
+ // Unlock after the changes have been done
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+
+ if ( !err )
+ {
+ // Inform clients that the ODT has been modified
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent(EhspsODTModified),
+ appODT->RootUid(),
+ appODT->ThemeUid(),
+ aMessage.SecureId().iId,
+ appODT->ProviderUid(),
+ 0,
+ 0,
+ pluginUid,usedPluginId,ETrue,
+ pluginODT->ThemeFullName(),
+ (TLanguage)(appODT->OdtLanguage() ) );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ }
+
+ // Cleaning
+ if ( pluginODT )
+ {
+ CleanupStack::PopAndDestroy( pluginODT );
+ pluginODT = NULL;
+ }
+ if ( appODT )
+ {
+ CleanupStack::PopAndDestroy( appODT );
+ appODT = NULL;
+ }
+
+ // Error handling
+ iResult->iXuikonError = err;
+ if ( !err )
+ {
+ // Get plugin configuration
+ ret = EhspsAddPluginSuccess;
+ }
+
+ // Return id of the added plugin
+ TPckg<TInt> packagedInt(usedPluginId);
+ messagePtr.WriteL(2, packagedInt );
+
+ // Completion
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// Finds last id value from the provided DOM.
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::GetUsedIdsL(
+ ChspsDomDocument& aDom,
+ TInt& aLastUsedConfId,
+ TInt& aLastUsedPluginId )
+ {
+ aLastUsedConfId = 0;
+ aLastUsedPluginId = 0;
+
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *aDom.RootNode() );
+ CleanupStack::PushL( iter );
+
+ // Find a plugin node with an id attribute that matches the provided parent plugin id
+ ChspsDomNode* node = iter->First();
+ while( node )
+ {
+ const TDesC8& name = node->Name();
+
+ // A Configuration element was found
+ if ( name == KConfigurationElement )
+ {
+ // Get value of the id attribute (should exist)
+ ChspsDomList& attrList = node->AttributeList();
+ ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KConfigurationAttrId) );
+ if ( !attr )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Id attribute is missing!" ) );
+ }
+#endif
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt id(0);
+ const TDesC8& idDesc = attr->Value();
+ TLex8 lex( idDesc );
+ if ( lex.Val( id ) )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Invalid id" ) );
+ }
+#endif
+ User::Leave( KErrCorrupt );
+ }
+ if ( id > aLastUsedConfId )
+ {
+ aLastUsedConfId = id;
+ }
+ }
+
+ // A Plugin element was found
+ else if ( name == KPluginElement )
+ {
+ // Get value of the id attribute (should exist)
+ ChspsDomList& attrList = node->AttributeList();
+ ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KPluginAttrId) );
+ if ( !attr )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Id attribute is missing!" ) );
+ }
+#endif
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt id(0);
+ const TDesC8& idDesc = attr->Value();
+ TLex8 lex( idDesc );
+ if ( lex.Val( id ) )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Invalid id" ) );
+ }
+#endif
+ User::Leave( KErrCorrupt );
+ }
+ if ( id > aLastUsedPluginId )
+ {
+ aLastUsedPluginId = id;
+ }
+ }
+ node = iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+ }
+
+// -----------------------------------------------------------------------------
+// Appends an application configuration with an instance of a plugin configuration.
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::AppendConfigurationL(
+ ChspsODT& aAppODT,
+ const ChspsODT& aPluginODT,
+ const TInt aConfigurationId,
+ const TInt aNewPosition,
+ TInt& aConfId,
+ TInt& aPluginId )
+ {
+ TInt ret = KErrNone;
+
+ // Input validation
+ if ( aPluginODT.ConfigurationType() == EhspsAppConfiguration
+ || aConfigurationId < 0
+ || aPluginODT.ThemeUid() < 1
+ || aConfId < 0
+ || aPluginId < 0 )
+ {
+ return KErrArgument;
+ }
+
+ // Find a specific configuration node
+ ChspsDomNode* confNode = hspsServerUtil::FindConfigurationNodeL(
+ aAppODT,
+ aConfigurationId );
+ if ( !confNode )
+ {
+ return KErrNotFound;
+ }
+
+ // Find first plugins node under the searchFromNode node
+ ChspsDomNode* pluginsNode = FindPluginsNode( *confNode );
+ if ( !pluginsNode )
+ {
+ // If there is no plugins node, it means we cannot add plugins!
+ return KErrAccessDenied;
+ }
+
+ // Find plugin references from the plugin configuration being added,
+ // generate ids and update the plugin dom accordingly (changes are not saved)
+ ret = HandlePluginReferencesL(
+ aAppODT,
+ (ChspsODT&)aPluginODT,
+ aConfId,
+ aPluginId );
+ if ( !ret )
+ {
+ // Get new unique id
+ aPluginId++;
+
+ // Append the application configuration with the full plugin configuration dom
+ ret = AppendPluginConfigurationL(
+ aAppODT,
+ *pluginsNode,
+ aPluginODT,
+ aNewPosition,
+ aPluginId );
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// Finds the plugins node of the provided plugin node.
+// -----------------------------------------------------------------------------
+//
+ChspsDomNode* ChspsMaintenanceHandler::FindPluginsNode(
+ ChspsDomNode& aPluginNode )
+ {
+ ChspsDomNode* pluginsNode = NULL;
+ ChspsDomNode* confNode = &aPluginNode;
+ if ( aPluginNode.Name() != KConfigurationElement )
+ {
+ ChspsDomList& childList = aPluginNode.ChildNodes();
+ confNode = (ChspsDomNode*)childList.FindByName( KConfigurationElement );
+ }
+ if ( confNode )
+ {
+ ChspsDomNode* controlNode = (ChspsDomNode*)confNode->ChildNodes().FindByName( KControlElement );
+ if ( controlNode )
+ {
+ pluginsNode = (ChspsDomNode*)controlNode->ChildNodes().FindByName( KPluginsElement );
+ }
+ }
+
+#ifdef HSPS_LOG_ACTIVE
+ if ( !pluginsNode )
+ {
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::FindPluginsNode(): failed to find a plugins node" ) );
+ }
+ }
+#endif
+
+ return pluginsNode;
+ }
+
+// -----------------------------------------------------------------------------
+// Appends a plugins list with a new plugin node
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::AppendPluginConfigurationL(
+ ChspsODT& aAppODT,
+ ChspsDomNode& aPluginsNode,
+ const ChspsODT& aPluginODT,
+ const TInt aNewPosition,
+ const TInt aNewPluginId )
+ {
+ TInt err = KErrGeneral;
+
+ // Input validation
+ if ( aPluginODT.ThemeUid() < 1 || aNewPluginId < 1 )
+ {
+ return KErrArgument;
+ }
+
+ // Find a node to be added, step over any optional xml elements
+ // (start cloning from the configuration element onwards)
+ ChspsDomDocument& appDom = aAppODT.DomDocument();
+ ChspsDomDepthIterator* pluginIter = ChspsDomDepthIterator::NewL( *aPluginODT.DomDocument().RootNode() );
+ CleanupStack::PushL( pluginIter );
+ ChspsDomNode* node = pluginIter->First();
+ TBool steppingtoConfNode(EFalse);
+ while(node && !steppingtoConfNode)
+ {
+ const TDesC8& pluginNodeName = node->Name();
+
+ // Find the Configuration element
+ if( pluginNodeName == KConfigurationElement )
+ {
+ steppingtoConfNode=ETrue;
+ }
+ else
+ {
+ node = pluginIter->NextL();
+ }
+ }
+ CleanupStack::PopAndDestroy( pluginIter );
+
+ if ( node )
+ {
+ // The node instance should now hold the configuration element etc
+ ChspsDomNode* confNode = node->CloneL( aPluginsNode.StringPool());
+ CleanupStack::PushL( confNode );
+
+ // Create a new plugin node with mandatory attributes
+ ChspsDomNode* pluginNode = appDom.CreateElementNSL(
+ KPluginElement,
+ aPluginsNode.Namespace()
+ );
+ CleanupStack::PushL( pluginNode );
+
+ // Attach to the plugin node
+ pluginNode->AddChildL( confNode );
+ confNode->SetParent( pluginNode );
+
+ // Set attributes of the plugin node
+ hspsServerUtil::AddAttributeNumericL( *pluginNode, KPluginAttrId, aNewPluginId );
+ hspsServerUtil::AddAttributeNumericL( *pluginNode, KPluginAttrUid, aPluginODT.ThemeUid(), EHex );
+
+ // Add active attribute.
+ // If first plugin in list, then set as active.
+ // Otherwise other plugin should already be active at this level.
+ if( aPluginsNode.ChildNodes().Length() == 0 )
+ {
+ hspsServerUtil::AddAttributeDescL( *pluginNode, KPluginAttrActive, KPluginActiveStateActive );
+ }
+ else
+ {
+ hspsServerUtil::AddAttributeDescL( *pluginNode, KPluginAttrActive, KPluginActiveStateNotActive );
+ }
+
+ // Also make sure that if new node has child nodes, that they get active parameter also.
+ hspsServerUtil::EditPluginNodeActivityL( pluginNode,
+ hspsServerUtil::EActivateFirst );
+
+ // Check when to insert and when to add to the end
+ if ( aNewPosition < 0 || aNewPosition >= aPluginsNode.ChildNodes().Length() )
+ {
+ // Append the plugin node to the end
+ aPluginsNode.AddChildL( pluginNode );
+ }
+ else
+ {
+ // Insert the plugin node to the position
+ aPluginsNode.AddChildL( pluginNode, aNewPosition );
+ }
+ pluginNode->SetParent( &aPluginsNode );
+
+ CleanupStack::Pop( pluginNode );
+ CleanupStack::Pop( confNode );
+ err = KErrNone;
+ }
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::HandlePluginReferencesL()
+// ImportPlugins phase.
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::HandlePluginReferencesL(
+ ChspsODT& aAppODT,
+ ChspsODT& aPluginODT,
+ TInt& aLastConfId,
+ TInt& aLastPluginId )
+ {
+
+ ChspsDomDocument& pluginDom = aPluginODT.DomDocument();
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *pluginDom.RootNode() );
+ CleanupStack::PushL( iter );
+
+ // Each configuration element get's an unique id value - same applies to the plugin elements.
+ // The ids are then used to reference a specific configuration or plugin instance
+ // in the whole application configuration
+
+ ChspsDomNode* node = iter->First();
+ while( node )
+ {
+ const TDesC8& name = node->Name();
+
+ // Configuration element
+ if ( name == KConfigurationElement )
+ {
+ // Generate an ID attribute for the configuration element
+ aLastConfId++;
+ hspsServerUtil::AddAttributeNumericL( *node, KConfigurationAttrId, aLastConfId );
+ }
+
+ // Plugin element
+ else if ( name == KPluginElement )
+ {
+ // Check parent element
+ ChspsDomNode* parentNode = node->Parent();
+ const TDesC8& parentName = parentNode->Name();
+ if( parentName == KPluginsElement )
+ {
+ ChspsDomList& attrList = node->AttributeList();
+
+ // Get configuration attribute from the plugin configuration
+ ChspsDomAttribute* pluginUidAttr =
+ static_cast<ChspsDomAttribute*> ( attrList.FindByName(KPluginAttrUid) );
+ if( !pluginUidAttr )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::HandlePluginReferencesL(): - Invalid XML" ) );
+ }
+#endif
+ User::Leave( KErrCorrupt );
+ }
+
+ // Convert uids from string to numeric format
+ const TDesC8& pluginUidValue = pluginUidAttr->Value();
+ const TUid pluginUid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);
+
+ // Get plugin configuration
+ ChspsODT* pluginOdt = ChspsODT::NewL();
+ CleanupStack::PushL( pluginOdt );
+ TInt err = iThemeServer.GetConfigurationL(
+ 0,
+ pluginUid.iUid,
+ *pluginOdt );
+ if ( err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::HandlePluginReferencesL(): - Failed to find a plugin" ) );
+ }
+#endif
+
+ // Append an empty configuration with error status
+ AddErrorConfigurationL(
+ pluginDom,
+ *node,
+ pluginUid.iUid );
+
+ // Generate an ID attribute for the plugin element
+ aLastPluginId++;
+ hspsServerUtil::AddAttributeNumericL( *node, KPluginAttrId, aLastPluginId );
+ }
+ else
+ {
+ // Set value of the ID attribute
+ aLastPluginId++;
+ hspsServerUtil::AddAttributeNumericL( *node, KPluginAttrId, aLastPluginId );
+
+
+ // Copy resources of the referenced plug-in instance to the application configuration
+ TInt resourceCount = pluginOdt->ResourceCount();
+ for ( TInt index=0; index < resourceCount; index++ )
+ {
+ ChspsResource& pluginResource = pluginOdt->ResourceL(index);
+ // Add only those that are located under the sources folder
+ if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
+ || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
+
+ {
+ ChspsResource* r = pluginResource.CloneL();
+ CleanupStack::PushL( r );
+ aAppODT.AddResourceL( r );
+ CleanupStack::Pop( r );
+ }
+ }
+
+ ChspsDomDocument& document = pluginOdt->DomDocument();
+ if ( !document.RootNode() )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ // Find the KConfigurationElement to step over any optional xml elements
+ ChspsDomDepthIterator* pluginIter = ChspsDomDepthIterator::NewL( *document.RootNode() );
+ CleanupStack::PushL( pluginIter );
+ ChspsDomNode* pluginNode = pluginIter->First();
+ TBool steppingtoConfNode(EFalse);
+ while(pluginNode && !steppingtoConfNode)
+ {
+ const TDesC8& pluginNodeName = pluginNode->Name();
+
+ if( pluginNodeName == KConfigurationElement )
+ {
+ steppingtoConfNode=ETrue;
+ }
+ else
+ {
+ pluginNode = pluginIter->NextL();
+ }
+ }
+ CleanupStack::PopAndDestroy( pluginIter );
+
+ // Copy the plugin configuration to the main document.
+ ChspsDomNode* rootCopy = pluginNode->CloneL( node->StringPool());
+ rootCopy->SetParent( node );
+ node->AddChildL( rootCopy );
+ }
+
+ CleanupStack::PopAndDestroy( pluginOdt );
+ }
+ }
+ node = iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+
+ // Copy resources of the plugin to the application configuration
+ TInt resourceCount = aPluginODT.ResourceCount();
+ for ( TInt index=0; index < resourceCount; index++ )
+ {
+ ChspsResource& pluginResource = aPluginODT.ResourceL(index);
+
+ // Add only those that are located under the sources folder
+ if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
+ || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
+ {
+ ChspsResource* r = pluginResource.CloneL();
+ CleanupStack::PushL( r );
+ aAppODT.AddResourceL( r );
+ CleanupStack::Pop( r );
+ }
+ }
+
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// Service for removing a plugin
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceRemovePluginL( const RMessage2& aMessage )
+ {
+ // Defaults
+ ThspsServiceCompletedMessage ret = EhspsRemovePluginFailed;
+ iResult->iXuikonError = KErrNotFound;
+ TInt err = KErrNone;
+
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+
+ // IPC slots:
+ // #0) output: externalized ChspsResult for error handling
+ // #1) input: ThpsParamRemovePlugin struct
+
+ // Get service parameters from IPC slot #1
+ ThpsParamRemovePlugin params;
+ TPckg<ThpsParamRemovePlugin> packagedStruct(params);
+ aMessage.ReadL(1, packagedStruct);
+ const TInt appUid = params.appUid;
+ const TInt pluginId = params.pluginId;
+
+ if ( pluginId < 1 )
+ {
+ err = KErrArgument;
+ }
+
+ // Application configuration
+ ChspsODT *appODT = NULL;
+ if ( !err )
+ {
+ // Get active application configuration from the central repository
+ TInt appConfUid;
+ err = iCentralRepository.Get( appUid, appConfUid );
+ if ( err || appConfUid < 1 )
+ {
+ err = KErrNotFound;
+ }
+ else
+ {
+ appODT = ChspsODT::NewL();
+ CleanupStack::PushL( appODT );
+ err = iThemeServer.GetConfigurationL(
+ appUid,
+ appConfUid,
+ *appODT );
+ }
+ }
+
+ // Modifications
+ if ( !err )
+ {
+ if ( iDefinitionRepository.Locked() )
+ {
+ // Repository locked
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ TInt pluginUid;
+ TBuf<KMaxFileName> pluginName;
+ err = GetConfigurationNodeDataL(*appODT,
+ pluginId,pluginUid, pluginName);
+ // Lock the Plugin Repository (a.k.a. Def.rep)
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+ if( !err )
+ {
+ // Remove the plugin configuration from the application configuration
+ err = RemoveConfigurationL(
+ *appODT,
+ pluginId );
+ }
+ if ( !err )
+ {
+
+#ifdef HSPS_LOG_ACTIVE
+ if( appODT && iLogBus )
+ {
+ ChspsOdtDump::Dump( *appODT, *iLogBus );
+ }
+#endif
+ // Stores the new application configuration into the repository
+ err = iDefinitionRepository.SetOdtL( *appODT );
+ if ( err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL(): - Updating failed" ) );
+ }
+#endif
+ }
+ }
+
+ // Unlock after the changes have been done
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+
+ if ( !err )
+ {
+ // Inform clients that the ODT has been modified
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent(EhspsODTRemoved),
+ appODT->RootUid(),
+ appODT->ThemeUid(),
+ aMessage.SecureId().iId,
+ appODT->ProviderUid(),
+ 0,0,
+ pluginUid,pluginId,ETrue,
+ pluginName,
+ (TLanguage)(appODT->OdtLanguage())
+ );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ }
+
+ // Cleaning
+ if ( appODT )
+ {
+ CleanupStack::PopAndDestroy( appODT );
+ appODT = NULL;
+ }
+
+ // Error handling
+ iResult->iXuikonError = err;
+ if ( !err )
+ {
+ ret = EhspsRemovePluginSuccess;
+ }
+
+ // Completion
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// Service for setting plugin active.
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceSetActivePluginL( const RMessage2& aMessage )
+ {
+ // Init output parameters.
+ iResult->ResetData();
+
+ // Read input parameters.
+ ThpsParamSetActivePlugin params;
+ TPckg<ThpsParamSetActivePlugin> packagedStruct( params );
+ aMessage.ReadL( 1, packagedStruct );
+
+ // Get uid of active application configuration.
+ TInt appConfUid = 0;
+ TInt err = iCentralRepository.Get( params.appUid, appConfUid );
+ if ( err != KErrNone || appConfUid < 1 )
+ {
+ err = KErrNotFound;
+ }
+
+ // Load configuration from repository.
+ ChspsODT* appODT = NULL;
+ if( err == KErrNone )
+ {
+ appODT = ChspsODT::NewL();
+ CleanupStack::PushL( appODT );
+ err = iThemeServer.GetConfigurationL(
+ params.appUid,
+ appConfUid,
+ *appODT );
+ }
+
+ // Initialize notification structure.
+ ThspsRepositoryInfo notification( EhspsPluginActivated );
+ if( err == KErrNone && appODT )
+ {
+ notification.iAppUid = appODT->RootUid();
+ notification.iAppConfUid = appODT->ThemeUid();
+ notification.iSecureId = 0;
+ notification.iAppConfProviderUid = 0;
+ notification.iPluginIfUid = 0;
+ notification.iPluginProviderUid = 0;
+ notification.iPluginUid = 0;
+ notification.iPluginId = 0;
+ notification.iLastNotification = ETrue;
+ notification.iName = KNullDesC();
+ notification.iLanguage = ELangTest;
+ }
+
+ // Find required node and set it active.
+ if( err == KErrNone )
+ {
+ // Find a plugin node with the provided id.
+ ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( *appODT,
+ params.pluginId );
+ if ( pluginNode )
+ {
+ // Get parent node.
+ ChspsDomNode* parentNode = pluginNode->Parent();
+ if ( parentNode )
+ {
+ // Deactivate all plugins at defined level. Do not recurse.
+ const TInt KDepth = 1;
+ hspsServerUtil::EditPluginNodeActivityL( parentNode,
+ hspsServerUtil::EDeactivateAll,
+ KDepth );
+
+ // Activate defined plugin.
+ hspsServerUtil::AddAttributeDescL( *pluginNode,
+ KPluginAttrActive,
+ KPluginActiveStateActive );
+
+ // Fill notification up2date.
+ notification.iPluginUid = hspsServerUtil::GetPluginUid( pluginNode ).iUid;
+ notification.iPluginId = hspsServerUtil::GetPluginId( pluginNode );
+ }
+ else
+ {
+ err = KErrCorrupt;
+ }
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ if ( iDefinitionRepository.Locked() )
+ {
+ // Repository locked
+ err = KErrAccessDenied;
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ // Lock and push to cleanup stack.
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // Stores the new application configuration into the repository
+ err = iDefinitionRepository.SetOdtL( *appODT );
+
+ // Unlock and remove from cleanupstack.
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop( &iDefinitionRepository );
+ }
+
+ // Notify.
+ if( err == KErrNone )
+ {
+ iDefinitionRepository.RegisterNotification( notification );
+ }
+
+ // Set output parameter values and complete request.
+ iResult->iSystemError = err;
+ iResult->iXuikonError = err;
+
+ // Complete the message.
+ RMessagePtr2 messagePtr = aMessage;
+ if( err == KErrNone )
+ {
+ CompleteRequest( EhspsSetActivePluginSuccess, messagePtr );
+ }
+ else
+ {
+ CompleteRequest( EhspsSetActivePluginFailed, messagePtr );
+ }
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ ChspsOdtDump::Dump( *appODT, *iLogBus );
+ }
+#endif
+
+ // Cleanup.
+ if ( appODT )
+ {
+ CleanupStack::PopAndDestroy( appODT );
+ appODT = NULL;
+ }
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ if( err == KErrNone )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetActivePluginL: - OK" ) );
+ }
+ else
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetActivePluginL: - Error" ) );
+ }
+ }
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// Get plugin's configuration node attributes(plugin name, pluginUid )
+// Can expanded to get configuration Id and plugin type also
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::GetConfigurationNodeDataL(
+ ChspsODT& aAppODT,
+ const TInt aPluginId,
+ TInt& aPluginUid,
+ TDes& aPluginName )
+ {
+ TInt err = KErrNotFound;
+ ChspsDomNode *node = hspsServerUtil::FindPluginNodeL( aAppODT, aPluginId );
+ if ( node )
+ {
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *node );
+ CleanupStack::PushL( iter );
+
+ // Find a configuration node with an id attribute that matches the provided id
+ ChspsDomNode* node2 = iter->First();
+ TBool jobDone = EFalse;
+ while( node2 && !jobDone )
+ {
+ const TDesC8& name = node2->Name();
+
+ // An element was found
+ if ( name == KConfigurationElement )
+ {
+ TInt pluginUid = 0;
+ TBuf<KMaxFileName> pluginName;
+ ChspsDomList& attrList = node2->AttributeList();
+ ChspsDomAttribute* pluginUidAttr =
+ static_cast<ChspsDomAttribute*> ( attrList.FindByName(KConfigurationAttrUid) );
+ if( !pluginUidAttr )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetConfigurationNodeDataL(): - Invalid XML" ) );
+ }
+#endif
+ err = KErrGeneral;
+ }
+ else
+ {
+ // Convert uids from string to numeric format
+ const TDesC8& pluginUidValue = pluginUidAttr->Value();
+ const TUid uid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);
+ if ( uid.iUid > 0 )
+ {
+ pluginUid = uid.iUid;
+ // Override default status
+ err = KErrNone;
+ }
+ }
+ if( !err )
+ {
+ ChspsDomAttribute* pluginUidNameAttr =
+ static_cast<ChspsDomAttribute*> ( attrList.FindByName(KConfigurationAttrName) );
+ if( !pluginUidNameAttr )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetConfigurationNodeDataL(): - Invalid XML" ) );
+ }
+#endif
+ err = KErrGeneral;
+ }
+ else
+ {
+ // Convert uids from string to numeric format
+ const TDesC8& pluginNameValue = pluginUidNameAttr->Value();
+ if ( pluginNameValue.Length() > 0 )
+ {
+ pluginName.Copy( pluginNameValue );
+ err = KErrNone;
+ }
+ }
+ }
+ if( !err )
+ {
+ aPluginUid = pluginUid;
+ aPluginName.Copy( pluginName );
+ jobDone = ETrue;
+ }
+ }
+ node2 = iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+ }
+
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ServiceReplacePluginL()
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceReplacePluginL( const RMessage2& aMessage )
+ {
+ // Defaults
+ ThspsServiceCompletedMessage ret = EhspsReplacePluginFailed;
+ iResult->iXuikonError = KErrNotFound;
+ TInt err = KErrNone;
+
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+
+ // IPC slots:
+ // #0) output: externalized ChspsResult for error handling
+ // #1) input: ThpsParamReplacePlugin struct
+ ThspsParamReplacePlugin params;
+ TPckg<ThspsParamReplacePlugin> packagedStruct(params);
+ aMessage.ReadL(1, packagedStruct);
+ const TInt appUid( params.appUid );
+ const TInt pluginId( params.pluginId );
+ const TInt confUid( params.confUid );
+ if ( pluginId < 1 || confUid < 1 )
+ {
+ err = KErrArgument;
+ }
+
+ // Application configuration
+ ChspsODT *appODT = NULL;
+ if ( !err )
+ {
+ // Get active application configuration from the central repository
+ TInt appConfUid;
+ err = iCentralRepository.Get( appUid, appConfUid );
+ if ( err || appConfUid < 1 )
+ {
+ err = KErrNotFound;
+ }
+ else
+ {
+ appODT = ChspsODT::NewL();
+ CleanupStack::PushL( appODT );
+ err = iThemeServer.GetConfigurationL(
+ appUid,
+ appConfUid,
+ *appODT );
+ }
+ }
+
+ // Plugin configuration
+ ChspsODT *pluginODT = NULL;
+ if ( !err )
+ {
+ // Find the plugin configuration (interface is unknown, so 1st argument is set to zero)
+ pluginODT = ChspsODT::NewL();
+ CleanupStack::PushL( pluginODT );
+ err = iThemeServer.GetConfigurationL(
+ 0,
+ confUid,
+ *pluginODT );
+ }
+
+ // Check needed space for replace. Returns system wide error code.
+ if( !err )
+ {
+ err = hspsServerUtil::EnoughDiskSpaceAvailableL(
+ *pluginODT,
+ iThemeServer.DeviceLanguage(),
+ iServerSession->FileSystem(),
+ EDriveC,
+ KAdditionalRequiredDiskSpace );
+ }
+
+ // Modifications
+ if ( !err )
+ {
+ if ( iDefinitionRepository.Locked() )
+ {
+ // Repository locked
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ // Lock the Plugin Repository (a.k.a. Def.rep)
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // Remove the plugin configuration from the application configuration
+ err = ReplaceConfigurationL(
+ *appODT,
+ pluginId,
+ *pluginODT );
+ if ( !err )
+ {
+
+#ifdef HSPS_LOG_ACTIVE
+ if( appODT && iLogBus )
+ {
+ ChspsOdtDump::Dump( *appODT, *iLogBus );
+ }
+#endif
+ // Stores the new application configuration into the repository
+ err = iDefinitionRepository.SetOdtL( *appODT );
+ // Unlock after the changes have been done
+ iDefinitionRepository.Unlock();
+ if ( err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceReplacePluginL(): - Updating failed" ) );
+ }
+#endif
+ }
+ else
+ {
+ // Inform clients that the ODT has been modified
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent(EhspsPluginReplaced),
+ appODT->RootUid(),
+ appODT->ThemeUid(),
+ aMessage.SecureId().iId,
+ 0,
+ 0,
+ 0,
+ confUid,
+ pluginId,
+ ETrue,
+ KNullDesC(),
+ (TLanguage)(appODT->OdtLanguage())
+ );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ else
+ {
+ // Unlock repository
+ iDefinitionRepository.Unlock();
+ }
+
+ CleanupStack::Pop(&iDefinitionRepository);
+ }
+ }
+
+ // Cleaning
+ if ( pluginODT )
+ {
+ CleanupStack::PopAndDestroy( pluginODT );
+ }
+ if ( appODT )
+ {
+ CleanupStack::PopAndDestroy( appODT );
+ appODT = NULL;
+ }
+
+ // Error handling
+ iResult->iXuikonError = err;
+ if ( !err )
+ {
+ ret = EhspsReplacePluginSuccess;
+ }
+
+ // Completion
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ReplaceConfigurationL()
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::ReplaceConfigurationL(
+ ChspsODT& aAppODT,
+ const TInt aPluginId,
+ const ChspsODT& aPluginODT )
+ {
+ // Input validation
+ if ( aAppODT.ConfigurationType() != EhspsAppConfiguration
+ || aAppODT.ThemeUid() < 1
+ || aPluginId < 1
+ || aPluginODT.ConfigurationType() == EhspsAppConfiguration
+ || aPluginODT.ThemeUid() < 1 )
+ {
+ return KErrArgument;
+ }
+
+ TInt err = KErrNotFound;
+
+ // Find a plugin node with the provided plugin id
+ ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( aAppODT, aPluginId);
+ if ( pluginNode )
+ {
+ ChspsDomNode* pluginsNode = pluginNode->Parent();
+
+ // Get current position in the plugins list
+ TInt currentPosition = FindPluginPosition( *pluginNode );
+ if ( currentPosition < 0 )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ // Get configuration id from existing configuration
+ ChspsDomNode* oldConfNode = (ChspsDomNode *)pluginNode->ChildNodes().Item( 0 );
+ if ( !oldConfNode )
+ {
+ User::Leave( KErrGeneral );
+ }
+ ChspsDomList& attrList = oldConfNode->AttributeList();
+ ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KConfigurationAttrId) );
+ if ( !attr )
+ {
+ User::Leave( KErrGeneral );
+ }
+ const TInt oldConfId = hspsServerUtil::DecString2Int( attr->Value() );
+ oldConfNode = 0;
+
+ // Remove old plugin configuration instance and it's resources from the application configuration
+ err = RemoveConfigurationL( aAppODT, aPluginId );
+ if ( err )
+ {
+ User::Leave( KErrGeneral );
+ }
+ pluginNode = 0;
+
+ // Find configuration node from the plugin ODT
+ ChspsDomNode* confNode = aPluginODT.DomDocument().RootNode();
+ if ( confNode->Name().CompareF(KConfigurationElement) != 0 )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ // Add configuration id attribute
+ hspsServerUtil::AddAttributeNumericL( *confNode, KConfigurationAttrId, oldConfId );
+
+ // Append new plugin configuration node to the application configuration
+ err = AppendPluginConfigurationL(
+ aAppODT,
+ *pluginsNode,
+ aPluginODT,
+ currentPosition,
+ aPluginId );
+
+ if( !err )
+ {
+ // Add resources of the new plugin into the application configuration
+ AddPluginResourcesL(
+ aAppODT,
+ aPluginODT.ThemeUid() );
+ }
+ }
+
+ return err;
+ }
+
+TInt ChspsMaintenanceHandler::FindPluginPosition(
+ ChspsDomNode& aPluginNode )
+ {
+ TInt pos = -1;
+ ChspsDomList& childList = aPluginNode.Parent()->ChildNodes();
+ for( TInt nodeIndex=0; nodeIndex < childList.Length(); nodeIndex++ )
+ {
+ ChspsDomNode* node = (ChspsDomNode *)childList.Item( nodeIndex );
+
+ if ( node == &aPluginNode )
+ {
+ pos = nodeIndex;
+ break;
+ }
+ }
+ return pos;
+ }
+
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::SetLogBus()
+// -----------------------------------------------------------------------------
+//
+#ifdef HSPS_LOG_ACTIVE
+void ChspsMaintenanceHandler::SetLogBus( ChspsLogBus* aLogBus )
+ {
+ iLogBus = aLogBus;
+ }
+#endif
+
+// -----------------------------------------------------------------------------
+// Removes an plugin instance from the provided application configuration
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::RemoveConfigurationL(
+ ChspsODT& aAppODT,
+ const TInt aPluginId )
+ {
+ TInt err = KErrNotFound;
+
+ // Find a plugin node with the provided id
+ ChspsDomNode *node = hspsServerUtil::FindPluginNodeL( aAppODT, aPluginId );
+ if ( node )
+ {
+ // Get parent node
+ ChspsDomNode *parentNode = node->Parent();
+ if ( parentNode )
+ {
+ // Get uid attribute from the node
+ TInt pluginUid = 0;
+ ChspsDomList& attrList = node->AttributeList();
+ ChspsDomAttribute* pluginUidAttr =
+ static_cast<ChspsDomAttribute*> ( attrList.FindByName(KPluginAttrUid) );
+ if( !pluginUidAttr )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::RemoveConfigurationL(): - Invalid XML" ) );
+ }
+#endif
+
+ err = KErrGeneral;
+ }
+ else
+ {
+ // Convert uids from string to numeric format
+ const TDesC8& pluginUidValue = pluginUidAttr->Value();
+ const TUid uid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);
+ if ( uid.iUid > 0 )
+ {
+ pluginUid = uid.iUid;
+ // Override default status
+ err = KErrNone;
+ }
+ }
+
+ // Store activity state for use after deletion.
+ TBool pluginWasActive = EFalse;
+ ChspsDomAttribute* pluginActivityAttr =
+ static_cast<ChspsDomAttribute*>( attrList.FindByName( KPluginAttrActive ) );
+ if( pluginActivityAttr )
+ {
+ if( pluginActivityAttr->Value().CompareF( KPluginActiveStateActive ) == 0 )
+ {
+ pluginWasActive = ETrue;
+ }
+ }
+
+ if ( !err )
+ {
+ // Get number of plugin instances with the plugin uid
+ TInt instanceCount = 0;
+ GetPluginInstanceCountL(
+ aAppODT,
+ pluginUid,
+ instanceCount );
+
+ // Remove plugin resources form the application configuration:
+ // By default remove all plugin's resources from all instances
+ // - otherwise, after upgrades, there might be various versions of the same resources
+ err = RemovePluginResourcesL( aAppODT, pluginUid );
+ if ( !err )
+ {
+ // If the application configuration holds other instances of the same plugin
+ if ( instanceCount > 1 )
+ {
+ // Put back the resources
+ AddPluginResourcesL(
+ aAppODT,
+ pluginUid );
+ }
+
+ // Remove the plugin node from parent node
+ parentNode->DeleteChild( node );
+ }
+ }
+
+ // If plugin was succesfully deleted and was active ->
+ // need set another plugin active.
+ // ( Choose to activate topmost item. )
+ // ( Use depth of 1 to affect only one level. )
+ if ( !err && pluginWasActive )
+ {
+ const TInt KDepth = 1;
+ hspsServerUtil::EditPluginNodeActivityL( parentNode,
+ hspsServerUtil::EActivateFirst,
+ KDepth );
+ }
+ }
+ }
+
+ return err;
+ }
+
+//----------------------------------------------------------------------------
+// Finds a plugin node with the provided id which is also a children of
+// the provided plugins node
+// ----------------------------------------------------------------------------
+//
+ChspsDomNode* ChspsMaintenanceHandler::FindChildPluginNode(
+ ChspsDomNode& aPluginsNode,
+ const TInt aPluginId )
+ {
+ ChspsDomNode* pluginNode = NULL;
+
+ // Loop child nodes
+ ChspsDomList& childList = aPluginsNode.ChildNodes();
+ for( TInt nodeIndex=0; nodeIndex < childList.Length(); nodeIndex++ )
+ {
+ // Find a specific node with the provided id value
+ ChspsDomNode* node = (ChspsDomNode *)childList.Item( nodeIndex );
+ if ( node )
+ {
+ // Find the ID attribute
+ ChspsDomList& attrList = node->AttributeList();
+ ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KPluginAttrId) );
+ if ( attr )
+ {
+ TInt id = 0;
+ const TDesC8& idValue = attr->Value();
+ TLex8 lex( idValue );
+ if ( lex.Val( id ) == 0 && id == aPluginId )
+ {
+ pluginNode = node;
+ break;
+ }
+ }
+ }
+ }
+
+ return pluginNode;
+ }
+
+// -----------------------------------------------------------------------------
+// Returns a count of plugin instances.
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::GetPluginInstanceCountL(
+ const ChspsODT& aAppODT,
+ const TInt aPluginUid,
+ TInt& aInstanceCount )
+
+ {
+ aInstanceCount = 0;
+
+ ChspsDomDocument& dom = aAppODT.DomDocument();
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() );
+ CleanupStack::PushL( iter );
+
+ // Find a plugin node with the provided id attribute
+ ChspsDomNode* node = iter->First();
+ ChspsDomNode* prevNode = NULL;
+ TBool jobDone = EFalse;
+ while( node && !jobDone && prevNode != node )
+ {
+ const TDesC8& name = node->Name();
+
+ // Plugin element was found
+ if ( name == KPluginElement )
+ {
+ ChspsDomList& attrList = node->AttributeList();
+ ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KPluginAttrUid) );
+ if ( !attr )
+ {
+ // Mandatory information is missing for some reason (should be set at installation handler)!
+ // Exit with NULL
+ jobDone = ETrue;
+ }
+ else
+ {
+ // Convert from (hex?) string into TUid presentation
+ const TUid uid = hspsServerUtil::ConvertDescIntoUid( attr->Value() );
+ if ( aPluginUid == uid.iUid )
+ {
+ aInstanceCount++;
+ }
+ }
+ }
+
+ prevNode = node;
+ node = iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+ }
+
+// -----------------------------------------------------------------------------
+// Removes plugin resources from the provided ODT
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::RemovePluginResourcesL(
+ ChspsODT& aAppODT,
+ const TInt aPluginUid )
+ {
+ // Loop resources of the application configuration
+ for(TInt aresIndex = 0; aresIndex < aAppODT.ResourceCount(); aresIndex++ )
+ {
+ ChspsResource& ares = aAppODT.ResourceL( aresIndex );
+
+ // If the plugin resource was found at resource list of the application configuration
+ if ( ares.ConfigurationUid() == aPluginUid )
+ {
+ // Deletes resource from the application configuration
+ aAppODT.DeleteResourceL( aresIndex );
+ aresIndex--;
+ }
+
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// Adds plugin resources to the provided application ODT
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::AddPluginResourcesL(
+ ChspsODT& aAppODT,
+ const TInt aPluginUid )
+ {
+ // Get plugin ODT
+ ChspsODT* pluginODT = ChspsODT::NewL();
+ CleanupStack::PushL( pluginODT );
+ TInt ret = iThemeServer.GetConfigurationL(
+ 0,
+ aPluginUid,
+ *pluginODT );
+
+ if ( !ret && pluginODT->ThemeUid() )
+ {
+ // Copy resources of the referenced plug-in instance to the application configuration
+ TInt resourceCount = pluginODT->ResourceCount();
+ for ( TInt index=0; index < resourceCount; index++ )
+ {
+ ChspsResource& pluginResource = pluginODT->ResourceL(index);
+ // Add only those that are located under the sources folder
+ if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
+ || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
+ {
+ ChspsResource* r = pluginResource.CloneL();
+ CleanupStack::PushL( r );
+ aAppODT.AddResourceL( r );
+ CleanupStack::Pop( r );
+ }
+ }
+ }
+
+ if ( pluginODT )
+ {
+ CleanupStack::PopAndDestroy( pluginODT );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Service for personalizing settings
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceSetPluginSettingsL( const RMessage2& aMessage )
+ {
+ // Defaults
+ ThspsServiceCompletedMessage ret = EhspsSetPluginSettingsFailed;
+ iResult->iXuikonError = KErrNotFound;
+ TInt err = KErrNone;
+
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+
+ TBuf8<KMaxHeaderDataLength8> setMaskData;
+
+
+ ChspsODT* odt = NULL;
+ TInt appConfUid;
+ TInt pluginId;
+ TBool storingStatus(EFalse);
+
+ // Checking active congiruation and security
+ messagePtr.ReadL(1,setMaskData,0);
+
+ if (iSetMask)
+ {
+ delete iSetMask;
+ iSetMask = NULL;
+ }
+
+ iSetMask = ChspsODT::NewL();
+ iSetMask->UnMarshalHeaderL( setMaskData );
+
+ iCentralRepository.Get( iSetMask->RootUid(), appConfUid );
+
+ // Getting active configuration
+ odt = ChspsODT::NewL();
+ CleanupStack::PushL(odt);
+
+ err = iThemeServer.GetConfigurationL(
+ iSetMask->RootUid(),
+ appConfUid,
+ *odt );
+
+ if (iSetMask)
+ {
+ delete iSetMask;
+ iSetMask = NULL;
+ }
+
+ // Set settings to active configuration
+ if( !err )
+ {
+ if( iDefinitionRepository.Locked() )
+ {
+ // Repository locked
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ // Lock the Plugin Repository (a.k.a. Def.rep)
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+ //Read pluginID
+ // Get configuration
+ ThspsParamSetPluginSettings params;
+ TPckg<ThspsParamSetPluginSettings> packagedStruct(params);
+
+ messagePtr.ReadL( 2, packagedStruct );
+
+ pluginId = params.pluginId ;
+ storingStatus = params.storingStatus ;
+
+
+
+ // read Domdata
+ HBufC8* domData = HBufC8::NewL( messagePtr.GetDesLengthL( 3 ) );
+ CleanupStack::PushL( domData );
+ TPtr8 domPtr = domData->Des();
+ messagePtr.ReadL( 3, domPtr, 0 );
+ RDesReadStream readBuf( *domData );
+ CleanupClosePushL( readBuf );
+
+ ChspsDomDocument* domDocument = ChspsDomDocument::NewL( readBuf );
+
+ CleanupStack::PopAndDestroy( &readBuf );
+ CleanupStack::PopAndDestroy( domData );
+
+ CleanupStack::PushL( domDocument );
+ err = hspsSetPluginSettingsL( *odt, pluginId, *domDocument );
+
+ if( !err )
+ {
+
+#ifdef HSPS_LOG_ACTIVE
+ if( odt && iLogBus )
+ {
+ ChspsOdtDump::Dump( *odt, *iLogBus );
+ }
+#endif
+ // Stores the new application configuration into the repository
+ err = iDefinitionRepository.SetOdtL( *odt );
+
+ if( !err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetPluginSettingsL(): - Updating Success" ) );
+ }
+#endif
+ }
+ }
+ CleanupStack::PopAndDestroy( domDocument );
+
+ // Unlock after the changes have been done
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+
+ if( storingStatus )
+ {
+ // Lock the Plugin Repository (a.k.a. Def.rep)
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( *odt, pluginId );
+
+ if( pluginNode )
+ {
+
+ ChspsDomList& attrList = pluginNode->AttributeList();
+ // Get configuration attribute from the plugin configuration
+ ChspsDomAttribute* pluginUidAttr = static_cast<ChspsDomAttribute*> ( attrList.FindByName(KPluginAttrUid) );
+
+ if( pluginUidAttr )
+ {
+
+ // Convert uids from string to numeric format
+ const TDesC8& pluginUidValue = pluginUidAttr->Value();
+ const TUid pluginUid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);
+ // Get plugin configuration
+ ChspsODT* pluginOdt = ChspsODT::NewL();
+ CleanupStack::PushL( pluginOdt );
+
+ err = iThemeServer.GetConfigurationL(
+ 0,
+ pluginUid.iUid,
+ *pluginOdt );
+
+ if( !err )
+ {
+ // read Domdata
+ HBufC8* domData = HBufC8::NewL( messagePtr.GetDesLengthL( 3 ) );
+ CleanupStack::PushL( domData );
+ TPtr8 domPtr = domData->Des();
+ messagePtr.ReadL( 3, domPtr, 0 );
+ RDesReadStream readBuf( *domData );
+ CleanupClosePushL( readBuf );
+
+ ChspsDomDocument* domDocument = ChspsDomDocument::NewL( readBuf );
+
+ CleanupStack::PopAndDestroy( &readBuf );
+ CleanupStack::PopAndDestroy( domData );
+
+ CleanupStack::PushL( domDocument );
+
+ err = hspsSavePluginSettingsL( *pluginOdt, *domDocument );
+
+ if( !err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( odt && iLogBus )
+ {
+ ChspsOdtDump::Dump( *pluginOdt, *iLogBus );
+ }
+#endif
+ // Stores the new application configuration into the repository
+ err = iDefinitionRepository.SetOdtL( *pluginOdt );
+
+ if( !err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetPluginSettingsL(): - Updating plugin reference Success" ) );
+ }
+#endif
+ }
+ }
+ CleanupStack::PopAndDestroy( domDocument );
+ }
+ if ( pluginOdt )
+ {
+ CleanupStack::PopAndDestroy( pluginOdt );
+ pluginOdt = NULL;
+ }
+
+ }
+ else
+ {
+ err = KErrCorrupt;
+ }
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+
+ // Unlock after the changes have been done
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+ }
+
+ if ( !err )
+ {
+ // Inform clients that the ODT has been modified
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent(EhspsSettingsChanged),
+ odt->RootUid(),
+ odt->ThemeUid(),
+ aMessage.SecureId().iId, //=Any file
+ odt->ProviderUid(),
+ 0,0,
+ 0,pluginId,ETrue,odt->ThemeFullName(),
+ (TLanguage)(odt->OdtLanguage())
+ );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ }
+
+ // Cleaning
+ if (odt)
+ {
+ CleanupStack::PopAndDestroy( odt );
+ odt = NULL;
+ }
+
+ // Error handling
+ iResult->iXuikonError = err;
+ if ( !err )
+ {
+ ret = EhspsSetPluginSettingsSuccess;
+ }
+
+ // Completion
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+//
+// Service to get plugin Odt according plugin uid
+// packed parameters
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceGetPluginOdtL( const RMessage2& aMessage )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - service called" ) );
+ }
+#endif
+
+ iMessagePtr = aMessage;
+ TInt err = KErrNone;
+
+ // Get configuration
+ ThspsParamGetPluginOdt params;
+ TPckg<ThspsParamGetPluginOdt> packagedStruct(params);
+ iMessagePtr.ReadL(1, packagedStruct);
+
+ ChspsODT* odt = ChspsODT::NewL();
+ CleanupStack::PushL( odt );
+ err = iThemeServer.GetConfigurationL( 0, params.pluginUid, *odt );
+
+ if( !err )
+ {
+ TPath odtPath;
+ // Resolve odt path if no errors were occured
+ iDefinitionRepository.GetResourcePathL( *odt, EResourceODT, odtPath );
+ TPckg<ThspsParamGetPluginOdt> packagedStruct( params );
+ iMessagePtr.WriteL(2, odtPath);
+ }
+#ifdef HSPS_LOG_ACTIVE
+ else
+ {
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - error occured during GetConfigurationL()" ) );
+ }
+ }
+#endif
+
+ CleanupStack::PopAndDestroy( odt );
+
+ // Error handling
+ iResult->iXuikonError = err;
+
+ if ( err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - EhspsGetPluginOdtFailed code: %d" ), err );
+ }
+#endif
+
+ CompleteRequest( EhspsGetPluginOdtFailed, iMessagePtr );
+ }
+ else
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - EhspsGetPluginOdtSuccess" ) );
+ }
+#endif
+
+ CompleteRequest( EhspsGetPluginOdtSuccess, iMessagePtr );
+ }
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// hspsMaintenanceHandler::hspsSetPluginSettings
+
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::hspsSetPluginSettingsL( ChspsODT& aOdt,
+ TInt aPluginId, ChspsDomDocument& aDom )
+ {
+ TInt error = KErrNotFound;
+
+
+ TUint value = aPluginId;
+
+ // Find a plugin node with the provided id
+ ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( aOdt, value );
+ if( !pluginNode )
+ {
+ error = KErrNotFound;
+ return error;
+ }
+ ChspsDomNode* controlNode = &(FindNodeByTagL(KControlElement, *pluginNode ));
+ if( !controlNode )
+ {
+ error = KErrNotFound;
+ return error;
+ }
+ ChspsDomList& childList = controlNode->ChildNodes();
+ ChspsDomNode* settingsNode = (ChspsDomNode*)childList.FindByName( KSettingsElement );
+ if( !settingsNode )
+ {
+ error = KErrNotFound;
+ return error;
+ }
+ TInt index = controlNode->ItemIndex( *settingsNode );
+ controlNode->DeleteChild(settingsNode);
+
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *aDom.RootNode() );
+ CleanupStack::PushL( iter );
+ ChspsDomNode* node = iter->First();
+ ChspsDomNode* prevNode = NULL;
+ TBool jobDone = EFalse;
+ while( node && !jobDone && node != prevNode)
+ {
+ const TDesC8& name = node->Name();
+ if( name == KSettingsElement )
+ {
+ // Attach to the plugin node
+
+ ChspsDomNode* clone = node->CloneL( aOdt.DomDocument().StringPool() );
+ CleanupStack::PushL( clone );
+ controlNode->AddChildL( clone, index );
+ clone->SetParent( controlNode );
+ CleanupStack::Pop( clone );
+ jobDone=ETrue;
+ error=KErrNone;
+ }
+ prevNode=node;
+ node=iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+
+
+
+ return error;
+
+ }
+
+// -----------------------------------------------------------------------------
+// Finds a node from a dom document.
+// Looks for the next node tag.
+// -----------------------------------------------------------------------------
+ChspsDomNode& ChspsMaintenanceHandler::FindNodeByTagL(
+ const TDesC8& aNodeTag,
+ ChspsDomNode& aDomNode )
+ {
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( aDomNode );
+ CleanupStack::PushL( iter );
+ ChspsDomNode* targetNode( NULL );
+ ChspsDomNode* node = iter->First();
+ TBool found = EFalse;
+ while( !found && node )
+ {
+ const TDesC8& name = node->Name();
+ if ( name.Compare( aNodeTag ) == 0 )
+ {
+ found = ETrue;
+ targetNode = node;
+ }
+ node = iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+ return *targetNode;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsSavePluginSettingsL
+
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::hspsSavePluginSettingsL(
+ ChspsODT& aOdt,
+ ChspsDomDocument& aDom )
+ {
+ TInt error;
+ ChspsDomNode* node = aOdt.DomDocument().RootNode();
+
+ ChspsDomNode* controlNode = &(FindNodeByTagL(KControlElement, *node ));
+
+ if( !controlNode )
+ {
+ return KErrNotFound;
+ }
+
+ ChspsDomList& childList = controlNode->ChildNodes();
+ ChspsDomNode* settingsNode = (ChspsDomNode*)childList.FindByName( KSettingsElement );
+
+ if( !settingsNode )
+ {
+ return KErrNotFound;
+ }
+
+ TInt index = controlNode->ItemIndex( *settingsNode );
+ controlNode->DeleteChild(settingsNode);
+
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *aDom.RootNode() );
+ CleanupStack::PushL( iter );
+ ChspsDomNode* iterNode = iter->First();
+ ChspsDomNode* prevNode = NULL;
+ TBool jobDone = EFalse;
+
+ while( iterNode && !jobDone && iterNode != prevNode)
+ {
+ const TDesC8& name = iterNode->Name();
+ if( name == KSettingsElement )
+ {
+ // Attach to the plugin node
+
+ ChspsDomNode* clone = iterNode->CloneL( aOdt.DomDocument().StringPool() );
+ CleanupStack::PushL( clone );
+ controlNode->AddChildL( clone, index );
+ clone->SetParent( controlNode );
+ CleanupStack::Pop( clone );
+ jobDone=ETrue;
+ error=KErrNone;
+ }
+ prevNode=iterNode;
+ iterNode=iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+
+ return error;
+
+ }
+// Service for updating plugin positions
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceMovePluginsL( const RMessage2& aMessage )
+ {
+ // Defaults
+ ThspsServiceCompletedMessage ret = EhspsMovePluginsFailed;
+ iResult->iXuikonError = KErrNotFound;
+ TInt err = KErrNone;
+
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+
+ // IPC slots:
+ // #0) output: externalized ChspsResult for error handling
+ // #1) input: a struct
+
+ // Get service parameters from IPC slot #1
+ ThpsParamMovePlugins params;
+ TPckg<ThpsParamMovePlugins> packagedStruct(params);
+ aMessage.ReadL(1, packagedStruct);
+ const TInt appUid = params.appUid;
+ const TInt confId = params.configurationId;
+ TPtrC8 bufPtr( params.pluginIdsBuf );
+
+ // Internalize the plugin ids array from a descriptor
+ const TInt KGranularity = 6;
+ ChspsPluginIdList* idArray = new (ELeave)ChspsPluginIdList( KGranularity );
+ CleanupStack::PushL( idArray );
+ RDesReadStream readStream( bufPtr );
+ CleanupClosePushL( readStream );
+ TRAP( err, idArray->InternalizeL(readStream) );
+ CleanupStack::PopAndDestroy( &readStream );
+
+ if ( err || appUid < 1 || confId < 1 || idArray->Count() < 1 )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceMovePluginsL(): invalid input" ) );
+ }
+#endif
+
+ err = KErrArgument;
+ }
+
+ // Application configuration
+ ChspsODT *appODT = NULL;
+ if ( !err )
+ {
+ // Get active application configuration from the central repository
+ TInt appConfUid;
+ err = iCentralRepository.Get( appUid, appConfUid );
+ if ( err || appConfUid < 1 )
+ {
+ err = KErrNotFound;
+ }
+ else
+ {
+ appODT = ChspsODT::NewL();
+ CleanupStack::PushL( appODT );
+ err = iThemeServer.GetConfigurationL(
+ appUid,
+ appConfUid,
+ *appODT );
+ }
+ }
+
+ // Modifications
+ if ( !err )
+ {
+ if ( iDefinitionRepository.Locked() )
+ {
+ // Repository locked
+ err = KErrAccessDenied;
+ }
+ else
+ {
+ // Lock the Plugin Repository (a.k.a. Def.rep)
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // Update the provided configuration
+ err = UpdatePluginListL(
+ *appODT,
+ confId,
+ *idArray );
+ if ( !err )
+ {
+
+#ifdef HSPS_LOG_ACTIVE
+ if( appODT && iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL() - plugins moved:" ) );
+ ChspsOdtDump::Dump( *appODT, *iLogBus );
+ }
+#endif
+ // Stores the new application configuration into the repository
+ err = iDefinitionRepository.SetOdtL( *appODT );
+ if ( err )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL(): - Updating failed" ) );
+ }
+#endif
+ }
+ }
+ else
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL(): - UpdatePluginListL failed" ) );
+ }
+#endif
+ }
+
+ // Unlock after the changes have been done
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop(&iDefinitionRepository);
+
+ if ( !err )
+ {
+ // Inform clients that the ODT has been modified
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent(EhspsODTModified),
+ appODT->RootUid(),
+ appODT->ThemeUid(),
+ 0, //=Any file
+ appODT->ProviderUid(),
+ (TLanguage)(appODT->OdtLanguage())
+ );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ }
+ }
+
+ // Cleaning
+ if ( appODT )
+ {
+ CleanupStack::PopAndDestroy( appODT );
+ appODT = NULL;
+ }
+
+ CleanupStack::PopAndDestroy( idArray );
+
+ // Error handling
+ iResult->iXuikonError = err;
+ if ( !err )
+ {
+ ret = EhspsMovePluginsSuccess;
+ }
+
+ // Completion
+ CompleteRequest( ret, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// Service for updating configuration state
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceSetConfStateL( const RMessage2& aMessage )
+ {
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+
+ // Get service parameters from IPC slot #1
+ ThspsParamSetConfState params;
+ TPckg<ThspsParamSetConfState> packagedStruct( params );
+ aMessage.ReadL( 1, packagedStruct );
+
+ // Reserve definition repository
+ if ( iDefinitionRepository.Locked() )
+ {
+ // Definition repository reserved
+ User::Leave( KErrAccessDenied );
+ }
+ iDefinitionRepository.Lock();
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // Get application configuration
+ TInt appConfUid;
+ User::LeaveIfError( iCentralRepository.Get( params.appUid, appConfUid ) );
+ ChspsODT* appODT = ChspsODT::NewL();
+ CleanupStack::PushL( appODT );
+ User::LeaveIfError( iThemeServer.GetConfigurationL(
+ params.appUid,
+ appConfUid,
+ *appODT ) );
+
+ // Update configuration state
+ SetConfStateL( *appODT, params.confId, params.state, params.filter );
+
+ // Store updated configuration
+ User::LeaveIfError( iDefinitionRepository.SetOdtL( *appODT ) );
+ CleanupStack::PopAndDestroy( appODT );
+
+ // Release definition repository
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop( &iDefinitionRepository );
+
+ // Completion
+ CompleteRequest( EhspsSetConfStateSuccess, messagePtr );
+ }
+
+// -----------------------------------------------------------------------------
+// Service for restoring active application configuration
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::ServiceRestoreActiveAppConfL( const RMessage2& aMessage )
+ {
+ // Parameters
+ RMessagePtr2 messagePtr = aMessage;
+ ThspsServiceCompletedMessage ret( EhspsRestoreActiveAppConfFailed );
+ TInt err( KErrNone );
+
+ // Get service parameters from IPC slot #1
+ ThspsParamRestoreActiveAppConf params;
+ TPckg<ThspsParamRestoreActiveAppConf> packagedStruct( params );
+ aMessage.ReadL( 1, packagedStruct );
+
+ // Create search criteria
+ ChspsODT* searchMask = ChspsODT::NewL();
+ CleanupStack::PushL( searchMask );
+ searchMask->SetRootUid( params.appUid );
+ searchMask->SetThemeUid( params.confUid );
+
+ // Get configuration header
+ ChspsODT* confHeader( NULL );
+ TInt pos( 0 );
+ iThemeServer.GetConfigurationHeader( *searchMask, confHeader, pos );
+
+ if ( confHeader &&
+ !iDefinitionRepository.Locked() )
+ {
+ // Lock definition repository
+ iDefinitionRepository.Lock();
+ // Restore backup configuration if it exists
+ err = iDefinitionRepository.RestoreBackupConfiguration( *confHeader );
+ // Release definition repository
+ iDefinitionRepository.Unlock();
+
+ if ( err != KErrNone )
+ {
+ // Configuration backup not found - Restore default configuration
+ ChspsODT* odt = ChspsODT::NewL();
+ CleanupStack::PushL( odt );
+ RestoreDefaultAppConfL( confHeader, *odt );
+ iDefinitionRepository.SetOdtL( *odt );
+ CleanupStack::PopAndDestroy( odt );
+ }
+ ret = EhspsRestoreActiveAppConfSuccess;
+ }
+
+ CleanupStack::PopAndDestroy( searchMask );
+
+ // Completion
+ CompleteRequest( ret, messagePtr );
+ }
+
+//----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::UpdatePluginListL()
+// ----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::UpdatePluginListL(
+ ChspsODT& aAppODT,
+ const TInt aConfigurationId,
+ const CArrayFixFlat<TInt>& aPluginIdList )
+ {
+ TInt err = KErrNone;
+
+ // Find the configuration node
+ ChspsDomNode* confNode = hspsServerUtil::FindConfigurationNodeL( aAppODT, aConfigurationId );
+ if ( !confNode )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - configuration node was not found" ) );
+ }
+#endif
+
+ err = KErrNotFound;
+ }
+
+ ChspsDomNode* controlNode = NULL;
+ if ( !err )
+ {
+ // Find a control node under the configuration node
+ controlNode = (ChspsDomNode *)confNode->ChildNodes().FindByName( KControlElement );
+ if ( !controlNode )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - control node was not found" ) );
+ }
+#endif
+
+ err = KErrNotFound;
+ }
+ }
+
+ ChspsDomNode* oldPluginsNode = NULL;
+ if ( !err )
+ {
+ // Find a plugins node under the control node
+ oldPluginsNode = (ChspsDomNode *)controlNode->ChildNodes().FindByName( KPluginsElement );
+ if ( !oldPluginsNode )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - plugin node was not found" ) );
+ }
+#endif
+ err = KErrNotFound;
+ }
+ else
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - old plugins node has %d childs" ),
+ oldPluginsNode->ChildNodes().Length() );
+ }
+#endif
+ }
+ }
+
+ const TInt nodeCount = aPluginIdList.Count();
+ if ( !err )
+ {
+ // Plugin node count and provided id count should match
+ if ( nodeCount < 1 || nodeCount != oldPluginsNode->ChildNodes().Length() )
+ {
+ err = KErrArgument;
+ }
+ }
+
+ // Find all plugin nodes under the plugins node in the requested sequence
+ CArrayFixFlat<ChspsDomNode*>* nodeArray = NULL;
+ if ( !err )
+ {
+ nodeArray = new (ELeave)CArrayFixFlat<ChspsDomNode*>( nodeCount );
+ CleanupStack::PushL( nodeArray );
+ ChspsDomNode* node = NULL;
+ for( TInt nodeIndex=0; nodeIndex < nodeCount; nodeIndex++ )
+ {
+ const TInt pluginId = aPluginIdList.At(nodeIndex);
+ node = FindChildPluginNode(
+ *oldPluginsNode,
+ pluginId );
+ if ( !node )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - FindChildPluginNode failure" ) );
+ }
+#endif
+
+ err = KErrNotFound;
+ break;
+ }
+ nodeArray->AppendL( node );
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - plugin id=%d" ),
+ pluginId );
+ }
+#endif
+ }
+ }
+
+ ChspsDomNode* newPluginsNode = NULL;
+ if ( !err )
+ {
+ // Clone the plugins node
+ newPluginsNode = oldPluginsNode->CloneWithoutKidsL( oldPluginsNode->StringPool() );
+ CleanupStack::PushL( newPluginsNode );
+
+ // Add the cloned plugins node into the control node (removal of the old plugins node is done later)
+ const TInt KNewPosition = 0;
+ controlNode->ChildNodes().AddItemL( newPluginsNode, KNewPosition );
+ newPluginsNode->SetParent( controlNode );
+
+ // Transfer ownership of the plugin nodes
+ const TInt arrayCount = nodeArray->Count();
+ for( TInt arrayIndex=0; arrayIndex < arrayCount; arrayIndex++)
+ {
+ ChspsDomNode* pluginNode = nodeArray->At(arrayIndex);
+ if ( !pluginNode )
+ {
+ err = KErrGeneral;
+ break;
+ }
+ newPluginsNode->AddChildL( pluginNode );
+ pluginNode->SetParent( newPluginsNode );
+ }
+ }
+
+ if ( !err )
+ {
+ // Remove plugin nodes from the old plugins node
+ const TInt remainingCount = oldPluginsNode->ChildNodes().Length();
+ for( TInt nodeIndex=0; nodeIndex < remainingCount; nodeIndex++)
+ {
+ ChspsDomNode* node = (ChspsDomNode*)oldPluginsNode->ChildNodes().Item( 0 );
+ if ( node )
+ {
+ oldPluginsNode->ChildNodes().RemoveItem( node );
+ }
+ }
+ if ( oldPluginsNode->ChildNodes().Length() != 0 )
+ {
+ err = KErrGeneral;
+ }
+ }
+
+ if ( !err )
+ {
+ // Remove the old plugins node from the control node
+ controlNode->ChildNodes().RemoveItem( oldPluginsNode );
+ delete oldPluginsNode;
+ oldPluginsNode = NULL;
+ }
+
+ if ( newPluginsNode )
+ {
+ CleanupStack::Pop( newPluginsNode );
+ }
+ if ( nodeArray )
+ {
+ CleanupStack::PopAndDestroy( nodeArray );
+ }
+
+ return err;
+ }
+
+//----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::SetConfStateL()
+// ----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::SetConfStateL(
+ ChspsODT& aAppODT,
+ TInt aConfId,
+ ThspsConfigurationState aState,
+ ThspsConfStateChangeFilter aFilter )
+ {
+
+ // Get state attribute value
+ TPtrC8 state;
+ switch ( aState )
+ {
+ case EhspsConfStateNotConfirmed:
+ state.Set( KConfStateNotConfirmed );
+ break;
+ case EhspsConfStateWaitForConfirmation:
+ state.Set( KConfStateWaitForConfirmation );
+ break;
+ case EhspsConfStateConfirmed:
+ state.Set( KConfStateConfirmed );
+ break;
+ default:
+ state.Set( KConfStateError );
+ break;
+ }
+
+ // Find a configuration node with an id attribute that matches the
+ // provided id and update found node state attribute
+ // If aConfId is -1 all configuration nodes are updated
+ ChspsDomDocument& dom = aAppODT.DomDocument();
+ ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() );
+ CleanupStack::PushL( iter );
+ ChspsDomNode* node = iter->First();
+ ChspsDomNode* prevNode = NULL;
+ TBool jobDone = EFalse;
+ while( node && !jobDone && prevNode != node )
+ {
+ const TDesC8& name = node->Name();
+
+ // Configuration node is found
+ if ( name == KConfigurationElement )
+ {
+ if ( aConfId != -1 )
+ {
+ ChspsDomList& attrList = node->AttributeList();
+ ChspsDomAttribute* idAttr = static_cast<ChspsDomAttribute*>(
+ attrList.FindByName( KConfigurationAttrId ) );
+ if ( !idAttr )
+ {
+ User::Leave( KErrNotFound );
+ }
+ TInt id(0);
+ const TDesC8& idValue = idAttr->Value();
+ TLex8 lex( idValue );
+ lex.Val( id );
+ TBuf8<10> confId;
+ confId.Num( aConfId );
+ if ( aConfId == id && aFilter == EhspsConfStateChangeNoFilter )
+ {
+ hspsServerUtil::AddAttributeDescL(
+ *node,
+ KConfigurationAttrState,
+ state );
+ jobDone = ETrue;
+ }
+ else if ( aFilter == EhspsConfStateChangePlugins &&
+ hspsServerUtil::GetParentNode(
+ *node,
+ KConfigurationElement,
+ KConfigurationAttrId,
+ confId ) )
+ {
+ hspsServerUtil::AddAttributeDescL(
+ *node,
+ KConfigurationAttrState,
+ state );
+ }
+ }
+ else
+ {
+ hspsServerUtil::AddAttributeDescL(
+ *node,
+ KConfigurationAttrState,
+ state );
+ }
+ }
+
+ prevNode = node;
+ node = iter->NextL();
+ }
+ CleanupStack::PopAndDestroy( iter );
+
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceService::hspsGetListHeadersL
+// Gets the header list to aHeaderDataList
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsGetListHeaders(const TDesC8&
+ /*aSearchMaskData*/, CArrayPtrSeg<HBufC8>& aHeaderDataList)
+ {
+ // set the default response
+ ThspsServiceCompletedMessage ret = EhspsGetListHeadersEmpty;
+ TInt errorCode;
+ TRAP( errorCode, GetHeaderListL( aHeaderDataList, *iSearchMask ) );
+ if (errorCode)
+ {
+ ret = EhspsGetListHeadersFailed;
+ }
+ else
+ {
+ ret = EhspsGetListHeadersSuccess;
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsGetNextHeader()
+// Gets the header list to aHeaderDataList
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsGetNextHeader()
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsSetActiveTheme
+// Sets the active theme to central repository.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetActiveTheme(const ChspsODT& aSetMask,
+ ChspsODT& aOdt)
+ {
+ // set the default response
+ ThspsServiceCompletedMessage ret = EhspsSetActiveThemeFailed;
+ TInt errorCode = KErrNone;
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::hspsSetActiveTheme(): - requested for AppUid = %d, ThemeUid= %d." ),
+ aSetMask.RootUid(),
+ aSetMask.ThemeUid() );
+ }
+#endif
+
+ TRAP( errorCode, errorCode = iThemeServer.ActivateThemeL( aSetMask, aOdt ));
+ if ( errorCode )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::hspsSetActiveTheme(): - theme activation failed - bad ODT!" ) );
+ }
+#endif
+
+ ret = EhspsSetActiveThemeFailed;
+ }
+ else
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::hspsSetActiveTheme(): - activated for AppUid = %d, ThemeUid= %d." ),
+ aOdt.RootUid(),
+ aOdt.ThemeUid() );
+ }
+#endif
+
+ ret = EhspsSetActiveThemeSuccess;
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsRestoreDefault
+// Restores the default theme and returns either EhspsRestoreDefaultSuccess or
+// EhspsRestoreDefaultFailed.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRestoreDefault( const ChspsODT& aSetMask,
+ ChspsODT& aHeader )
+ {
+ // set the default response
+ ThspsServiceCompletedMessage ret = EhspsRestoreDefaultFailed;
+ TInt errorCode = 0;
+ TRAP( errorCode, RestoredDefaultL( aSetMask, aHeader ) );
+ if ( errorCode )
+ {
+ ret = EhspsRestoreDefaultFailed;
+ }
+ else
+ {
+ ret = EhspsRestoreDefaultSuccess;
+ }
+ return ret;
+ }
+
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsRemoveThemeL
+// Removes the theme by calling the appropriate method in definition repository.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRemoveThemeL( const ChspsODT& aSetMask )
+ {
+ ThspsServiceCompletedMessage ret( EhspsRemoveThemeFailed );
+
+ if( !( aSetMask.Flags() & EhspsThemeStatusLicenceeDefault ) )
+ {
+ RArray<ThspsRepositoryInfo> notifParams;
+
+ if( !iDefinitionRepository.Locked() )
+ {
+ iDefinitionRepository.Lock();
+
+ // In case of error. repository is unlocked
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // Check what is being being uninstalled
+ TInt error( KErrNone );
+ if ( aSetMask.ConfigurationType() != EhspsAppConfiguration )
+ {
+ // Fix plugin instances and get notifications from valid cases
+ TRAP( error, RemovePluginFromAppConfsL( aSetMask, notifParams ) );
+ }
+
+ if( !error )
+ {
+ // Remove the actual plugin from file system
+ TRAP( error, RemoveThemeL( aSetMask ) );
+ }
+
+ if( !error )
+ {
+ // Remove header from the cache
+ iThemeServer.UpdateHeaderListCache(
+ EhspsCacheRemoveHeader,
+ aSetMask.RootUid(),
+ aSetMask.ProviderUid(),
+ aSetMask.ThemeUid() );
+ }
+
+ // Must be done before the notifications are sent
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop( &iDefinitionRepository );
+
+ if ( !error )
+ {
+ // Send the notifications which will update the client UIs
+ for( TInt i=0; i < notifParams.Count(); i++ )
+ {
+ iDefinitionRepository.RegisterNotification( notifParams[i] );
+ }
+
+ ret = EhspsRemoveThemeSuccess;
+ }
+ }
+
+ notifParams.Close();
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// RemovePluginFromAppConfsL
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::RemovePluginFromAppConfsL(
+ const ChspsODT& aOdt,
+ RArray<ThspsRepositoryInfo>& aNotificationParams )
+ {
+ __ASSERT_DEBUG( aOdt.ThemeUid(), User::Leave( KErrArgument ) );
+
+ // Loop application configurations
+ const TInt count = iHeaderListCache.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ ChspsODT* header = iHeaderListCache.At(i);
+ if ( header && header->ConfigurationType() == EhspsAppConfiguration )
+ {
+ // Get an ODT from the looped application configuration header
+ ChspsODT* appOdt = ChspsODT::NewL();
+ CleanupStack::PushL( appOdt );
+
+ // Fill only those values which are required by the GetOdtL call
+ appOdt->SetRootUid( header->RootUid() );
+ appOdt->SetProviderUid( header->ProviderUid() );
+ appOdt->SetThemeUid( header->ThemeUid() );
+ appOdt->SetProviderNameL( header->ProviderName() );
+ appOdt->SetThemeShortNameL( header->ThemeShortName() );
+ appOdt->SetThemeVersionL( header->ThemeVersion() );
+ User::LeaveIfError( iDefinitionRepository.GetOdtL( *appOdt ) );
+
+ // Get active application configuration for the client in question
+ TInt activeAppConfUid = 0;
+ iCentralRepository.Get( appOdt->RootUid(), activeAppConfUid );
+
+ // Get plugin id's from the instances in the application configuration
+ RArray<TInt> pluginIds;
+ CleanupClosePushL( pluginIds );
+
+ hspsServerUtil::GetPluginIdsByUidL( *appOdt,
+ TUid::Uid( aOdt.ThemeUid() ),
+ pluginIds );
+
+ // If there were plugin instances in an application configuration
+ if ( pluginIds.Count() > 0 )
+ {
+
+ // If the application configuration is inactive
+ if ( activeAppConfUid != appOdt->ThemeUid() )
+ {
+ // Prevent notifications and set state of the plugin instances to "uninstalled",
+ // AI3 will remove instances (or replaces them with an empty widget)
+ // when it loads the configuration after it has first been activated
+ TBool updatesDone = InvalidateUninstalledPluginInstancesL(
+ *appOdt,
+ aOdt.ThemeUid(),
+ pluginIds );
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ if ( updatesDone )
+ {
+ iLogBus->LogText(
+ _L( "ChspsMaintenanceHandler::RemovePluginFromAppConfsL(): old plugin instances were updated in inactive root configuration" )
+ );
+ }
+ else
+ {
+ iLogBus->LogText(
+ _L( "ChspsMaintenanceHandler::RemovePluginFromAppConfsL(): nothing was done" )
+ );
+ }
+ }
+#endif
+ }
+ else
+ {
+ // Notify active application configuration that old plugin instances need to be replaced
+ TBool lastNotification = EFalse;
+ for( TInt i = 0; i < pluginIds.Count(); i++ )
+ {
+ if( i == pluginIds.Count() - 1 )
+ {
+ lastNotification = ETrue;
+ }
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent( EhspsClean ),
+ appOdt->RootUid(),
+ appOdt->ThemeUid(),
+ 0, //=Any file
+ appOdt->ProviderUid(),
+ aOdt.RootUid(),
+ aOdt.ProviderUid(),
+ aOdt.ThemeUid(),
+ pluginIds[i],
+ lastNotification,
+ aOdt.ThemeFullName(),
+ (TLanguage)( aOdt.OdtLanguage() ) );
+ aNotificationParams.Append(info);
+ }
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText(
+ _L( "ChspsMaintenanceHandler::RemovePluginFromAppConfsL(): plugin uninstalled notifications sent to SAPI for all instances" )
+ );
+ }
+#endif
+ }
+ } // instance count > 0
+ else
+ {
+ if ( activeAppConfUid == appOdt->ThemeUid() )
+ {
+ // Notify active application configuration which had no plugin instances
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent( EhspsClean ),
+ appOdt->RootUid(),
+ appOdt->ThemeUid(),
+ 0, //=Any file
+ appOdt->ProviderUid(),
+ aOdt.RootUid(),
+ aOdt.ProviderUid(),
+ aOdt.ThemeUid(),
+ 0,
+ ETrue,
+ aOdt.ThemeFullName(),
+ (TLanguage)( aOdt.OdtLanguage() ) );
+ aNotificationParams.Append(info);
+ }
+ }
+
+ pluginIds.Close();
+ CleanupStack::PopAndDestroy( 2, appOdt ); // appOdt, pluginIds
+ appOdt = NULL;
+
+ } // app configuration
+
+ } // header loop
+
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL
+// -----------------------------------------------------------------------------
+TBool ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(
+ ChspsODT& aAppODT,
+ const TInt aPluginUid,
+ const RArray<TInt>& aPluginIds )
+ {
+ // Should be already locked by hspsRemoveThemeL()
+ __ASSERT_DEBUG( iDefinitionRepository.Locked(), User::Leave( KErrGeneral ) );
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(): - Before Error state updates:") );
+ ChspsOdtDump::Dump( aAppODT, *iLogBus );
+ }
+#endif
+
+ TInt processedCount = 0;
+ for( TInt idIndex = 0; idIndex < aPluginIds.Count(); idIndex++ )
+ {
+ const TInt pluginId( aPluginIds[idIndex] );
+
+ // If full DOM/application configuration hasn't been generated yet (plugin IDs are unset)
+ if ( pluginId > 0 )
+ {
+ ChspsDomNode *pluginNode = hspsServerUtil::FindPluginNodeL( aAppODT, pluginId );
+ __ASSERT_DEBUG( pluginNode, User::Leave( KErrArgument) );
+ if ( pluginNode )
+ {
+ ChspsDomNode* confNode = (ChspsDomNode *)pluginNode->ChildNodes().Item( 0 );
+ __ASSERT_DEBUG( confNode, User::Leave( KErrArgument) );
+ if ( confNode )
+ {
+ // Indicate that the configuration is in error state
+ // Should be changed to "uninstalled" when Homescreen supports it silently
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrState, KConfStateError );
+ processedCount++;
+ }
+ }
+ }
+ }
+
+ if ( processedCount )
+ {
+ // Remove uninstalled resources from the server (copies will remain in client's private directory)
+ RemovePluginResourcesL( aAppODT, aPluginUid );
+
+ // Store changes
+ User::LeaveIfError( iDefinitionRepository.SetOdtL( aAppODT ) );
+ }
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ if ( processedCount > 0 )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(): - Error states updated") );
+ ChspsOdtDump::Dump( aAppODT, *iLogBus );
+ }
+ else
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(): - Error states were not added") );
+ }
+ }
+#endif
+
+ return ( processedCount > 0 );
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsPluginUpdateL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsPluginUpdateL( const ChspsODT& aOdt )
+ {
+ ThspsServiceCompletedMessage ret( EhspsUpdatePluginFailed );
+
+ if( !iDefinitionRepository.Locked() )
+ {
+ iDefinitionRepository.Lock();
+
+ // In case of error. repository is unlocked
+ CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
+
+ // set the default response
+ ret = EhspsUpdatePluginSuccess;
+
+ TInt errorCode( KErrNone );
+
+ //create whole pluginOdt aOdt is only header for pluginOdt
+ ChspsODT* odt = ChspsODT::NewL();
+ CleanupStack::PushL( odt );
+ odt->SetRootUid( aOdt.RootUid() );
+ odt->SetThemeUid( aOdt.ThemeUid() );
+ odt->SetConfigurationType( aOdt.ConfigurationType() );
+ odt->SetRootUid( aOdt.RootUid() );
+ odt->SetProviderUid( aOdt.ProviderUid() );
+ odt->SetThemeUid( aOdt.ThemeUid() );
+ odt->SetProviderNameL( aOdt.ProviderName() );
+ odt->SetThemeFullNameL( aOdt.ThemeFullName() );
+ odt->SetThemeShortNameL( aOdt.ThemeShortName() );
+ odt->SetThemeVersionL( aOdt.ThemeVersion() );
+ odt->SetFlags( aOdt.Flags() );
+ odt->SetMultiInstance( aOdt.MultiInstance() );
+ User::LeaveIfError( iDefinitionRepository.GetOdtL( *odt ) );
+
+ RArray<ThspsRepositoryInfo> notifParams;
+
+ TRAP( errorCode, UpdatePluginFromAppConfsL( *odt, notifParams ));
+
+ if( errorCode )
+ {
+ ret = EhspsUpdatePluginFailed;
+ }
+
+ iDefinitionRepository.Unlock();
+ CleanupStack::Pop( &iDefinitionRepository );
+
+ if( ret == EhspsUpdatePluginSuccess )
+ {
+ if(notifParams.Count() > 0 )
+ {
+ //There is active app&appconfs to notify
+
+
+ for( TInt i=0; i < notifParams.Count(); i++ )
+ {
+ iDefinitionRepository.RegisterNotification( notifParams[i] );
+ }
+ }
+
+ }
+ notifParams.Close();
+
+ CleanupStack::PopAndDestroy( odt );
+ }
+
+ return ret;
+ }
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::UpdatePluginFromAppConfsL
+// (other items were commented in a header).
+//---------------------------------------------------------------------
+void ChspsMaintenanceHandler::UpdatePluginFromAppConfsL( ChspsODT& aOdt,
+ RArray<ThspsRepositoryInfo>& aNotificationParams )
+ {
+
+ if ( iHeaderListCache.Length() > 0 )
+ {
+ TInt count = iHeaderListCache.Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+ ChspsODT* header = iHeaderListCache.At(i);
+ if ( header->ConfigurationType() == EhspsAppConfiguration )
+ {
+ ChspsODT* odt = ChspsODT::NewL();
+ CleanupStack::PushL( odt );
+ odt->SetRootUid( header->RootUid() );
+ odt->SetThemeUid( header->ThemeUid() );
+ odt->SetConfigurationType( header->ConfigurationType() );
+ odt->SetRootUid( header->RootUid() );
+ odt->SetProviderUid( header->ProviderUid() );
+ odt->SetThemeUid( header->ThemeUid() );
+ odt->SetProviderNameL( header->ProviderName() );
+ odt->SetThemeFullNameL( header->ThemeFullName() );
+ odt->SetThemeShortNameL( header->ThemeShortName() );
+ odt->SetThemeVersionL( header->ThemeVersion() );
+ odt->SetFlags( header->Flags() );
+ odt->SetMultiInstance( header->MultiInstance() );
+ User::LeaveIfError( iDefinitionRepository.GetOdtL( *odt ) );
+
+
+ RArray<TInt> pluginIds;
+
+ hspsServerUtil::GetPluginIdsByUidL( *odt,
+ TUid::Uid( aOdt.ThemeUid() ),
+ pluginIds );
+
+
+ if ( pluginIds.Count() > 0 )
+ {
+
+
+ TInt err = UpdatePluginConfigurationL(
+ *odt,
+ aOdt,
+ pluginIds );
+
+ User::LeaveIfError( iDefinitionRepository.SetOdtL( *odt ) );
+
+
+
+ TBool status = EFalse;
+ for(TInt i = 0; i < pluginIds.Count(); i++ )
+ {
+ if( i == pluginIds.Count() - 1 )
+ {
+ status = ETrue;
+ }
+ ThspsRepositoryInfo info(
+ ThspsRepositoryEvent( EhspsODTUpdated ),
+ odt->RootUid(),
+ odt->ThemeUid(),
+ 0, //=Any file
+ 0,
+ aOdt.RootUid(),
+ aOdt.ProviderUid(),
+ aOdt.ThemeUid(),
+ pluginIds[i],
+ status,
+ aOdt.ThemeFullName(),
+ (TLanguage)( aOdt.OdtLanguage() ) );
+ aNotificationParams.Append(info);
+ }
+ }
+
+
+
+ pluginIds.Close();
+
+ CleanupStack::PopAndDestroy( odt );
+
+ }
+ }
+
+ }
+ }
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::UpdatePluginConfigurationL
+// Not supported
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::UpdatePluginConfigurationL(
+ ChspsODT& aOdt,
+ ChspsODT& aPluginOdt,
+ RArray<TInt>& aPluginIds )
+ {
+ TInt err(KErrNone);
+
+ // remove old resources
+ err = RemovePluginResourcesL( aOdt, aPluginOdt.ThemeUid() );
+
+ if( err )
+ {
+ return err;
+ }
+
+ ChspsDomNode* pluginNode = NULL;
+ ChspsDomNode* configNode = NULL;
+ for(TInt i = 0; i < aPluginIds.Count() && err == KErrNone; i++ )
+ {
+ pluginNode =
+ hspsServerUtil::FindPluginNodeL( aOdt, aPluginIds[i] );
+ TInt index = 0;
+
+ configNode =
+ hspsServerUtil::FindChildNodeByTagL( KConfigurationElement, *pluginNode, index );
+
+ if( configNode )
+ {
+ TInt id = hspsServerUtil::DecString2Int(
+ configNode->AttributeValue(KConfigurationAttrId));
+ hspsServerUtil::AddAttributeNumericL( *aPluginOdt.DomDocument().RootNode(), KConfigurationAttrId, id );
+
+ pluginNode->ReplaceChildL(configNode,aPluginOdt.DomDocument().RootNode());
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+
+ }
+ if( err )
+ {
+ return err;
+ }
+
+ _LIT(KSourcesFolder, "\\sources\\");
+ _LIT(KLocalesFolder, "\\locales\\");
+ // Add plugin resources
+ TInt resourceCount = aPluginOdt.ResourceCount();
+ for ( TInt index=0; index < resourceCount; index++ )
+ {
+ ChspsResource& pluginResource = aPluginOdt.ResourceL(index);
+ // Add only those that are located under the sources folder
+ if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
+ || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
+ {
+ ChspsResource* r = pluginResource.CloneL();
+ CleanupStack::PushL( r );
+ aOdt.AddResourceL( r );
+ CleanupStack::Pop( r );
+ }
+ }
+
+ return err;
+ }
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsGetListHeaders()
+// Not supported
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsGetListHeaders(const ChspsODT& /*aSearchMask*/,
+ CArrayPtrFlat<ChspsODT>& /*aHeaderList*/)
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsSetActiveTheme()
+// Not supported
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetActiveTheme(const TDesC8& /*aSetMaskData*/,
+ TDes8& /*aHeaderData*/)
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsAddPlugin()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsAddPlugin(
+ const TInt /*aAppUid*/,
+ const TInt /*aParentPluginId*/,
+ const TInt /*aPluginUid*/,
+ const TInt /*aPosition*/,
+ TInt& /*aAddedPluginId*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsRemovePlugin()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRemovePlugin(
+ const TInt /*aAppUid*/,
+ const TInt /*aPluginId*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsSetActivePlugin()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetActivePlugin(
+ const TInt /*aAppUid*/,
+ const TInt /*aPluginId*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsReplacePlugin()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsReplacePlugin(
+ const TInt /*aAppUid*/,
+ const TInt /*aPluginId*/,
+ const TInt /*aConfUid*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsSetPluginSettings()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetPluginSettings(
+ const ChspsODT& /*aHeader*/,
+ const TInt /*aPluginId*/,
+ ChspsDomDocument& /*aDom*/,
+ const TBool /*aPluginStoringStatus*/)
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsMovePluginsL()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsMovePluginsL(
+ const TInt /*aAppUid*/,
+ const TInt /*aConfId*/,
+ const CArrayFixFlat<TInt>& /*aPluginIdList*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsSetConfState()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetConfState(
+ const TInt /*aAppUid*/,
+ const TInt /*aConfId*/,
+ const ThspsConfigurationState /*aState*/,
+ const ThspsConfStateChangeFilter /*aFilter*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsRestoreActiveAppConf()
+// Not supported - inherited from an interface and not used.
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRestoreActiveAppConf(
+ const TInt /*aAppUid*/,
+ const TInt /*aConfUid*/ )
+ {
+ return EhspsServiceNotSupported;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::hspsCancelGetListHeaders()
+// Cancels the GetListHeaders request
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsCancelGetListHeaders()
+ {
+ if ( IsActive() )
+ {
+ Cancel();
+ }
+ iHeaderDataList->ResetAndDestroy(); // no headers
+ iDeliveryCount = 0; // no delivered headers
+ iSubscription = EFalse; // no subscription
+ CompleteRequest( EhspsServiceRequestCanceled, iMessagePtr );
+ // return with cancellation confirm
+ return EhspsServiceRequestCanceled;
+ }
+// -----------------------------------------------------------------------------
+// ChspsClientRequestHandler::HandleDefinitionRespositoryEvent()
+// Handles events coming from hspsDefinitionRepository.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool ChspsMaintenanceHandler::HandleDefinitionRespositoryEvent( ThspsRepositoryInfo aRepositoryInfo )
+ {
+ TInt errorCode = KErrNone;
+ TBool status(EFalse);
+ TRAP( errorCode, status = HandleDefinitionRespositoryEventL( aRepositoryInfo ) );
+ if( errorCode != KErrNone )
+ {
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsClientRequestHandler::HandleDefinitionRespositoryEvent(): - Error occured in HandleDefinitionRespositoryEventL" ) );
+ }
+#endif
+ }
+ return status;
+ }
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::HandleDefinitionRespositoryEvent()
+// Handles events coming from hspsDefinitionRepository.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool ChspsMaintenanceHandler::HandleDefinitionRespositoryEventL( ThspsRepositoryInfo aRepositoryInfo )
+ {
+ // is there any changes in cache
+ if ( ( aRepositoryInfo.iEventType & EhspsCacheUpdate ) && !iDefinitionRepository.Locked() && iSubscription && !iMessagePtr.IsNull() )
+ {
+ // cache changed, check if there is any changes when comparing to the local list
+ // and what kind of change there is
+ iCompletedMessage = GetHeaderListUpdateL();
+ // is there headers to deliver
+ if ( iCompletedMessage == EhspsGetListHeadersRestart )
+ {
+ if (iHeaderDataList->Count())
+ {
+ // at least one header on the list
+ iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
+ // add list count
+ iDeliveryCount++;
+ // delivery of the first header
+ }
+ CompleteRequest( EhspsGetListHeadersRestart, iMessagePtr );
+ }
+ else if ( iCompletedMessage == EhspsGetListHeadersUpdate )
+ {
+ // return list update, count continues from where it was
+ iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
+ // add list count
+ iDeliveryCount++;
+ // deliver a list item
+ CompleteRequest( EhspsGetListHeadersUpdate, iMessagePtr );
+ }
+ else if (iCompletedMessage == EhspsGetListHeadersEmpty)
+ {
+ CompleteRequest( EhspsGetListHeadersEmpty, iMessagePtr );
+ // no list update available at the moment, continue the polling for list updates
+ }
+ }
+ else if ( ( aRepositoryInfo.iEventType & EhspsCacheUpdate ) && iDefinitionRepository.Locked()
+ && !IsActive() && iSubscription )
+ {
+ After(KHeaderListUpdatePollingTimeSpan);
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::DoCancel()
+// Not implemented yet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::DoCancel()
+ {
+ // no need to implement
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::CompleteRequest()
+// Completes client request
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::CompleteRequest(const ThspsServiceCompletedMessage aReturnMessage,
+ RMessagePtr2& aMessagePtr, const TDesC8& /*aHeaderData*/ )
+ {
+ TInt errorCode = KErrNone;
+ RDesWriteStream writeBuf( iResultData );
+
+ TRAP( errorCode, iResult->ExternalizeL( writeBuf ));
+
+ writeBuf.Close();
+
+ if ( !aMessagePtr.IsNull() )
+ {
+ if ( errorCode )
+ {
+ TRAP_IGNORE( aMessagePtr.WriteL( 0, KNullDesC8, 0 ));
+ }
+ else
+ {
+ TRAP_IGNORE( aMessagePtr.WriteL( 0, iResultData, 0 ));
+ }
+ aMessagePtr.Complete( aReturnMessage );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::RunError
+// From CActive. Called when error occurred in asynchronous request
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt ChspsMaintenanceHandler::RunError( TInt aError )
+ {
+ iResult->iSystemError = aError;
+ iResult->iXuikonError = aError;
+
+#ifdef HSPS_LOG_ACTIVE
+ if( iLogBus )
+ {
+ iLogBus->LogText( _L( "ChspsMaintenanceHandler::RunError(): - error %d" ),
+ aError );
+ }
+#endif
+
+ CompleteRequest( EhspsGetListHeadersFailed, iMessagePtr );
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::RunL()
+// Handles header list polling
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::RunL()
+ {
+ if ( !iDefinitionRepository.Locked() && !iMessagePtr.IsNull() )
+ {
+ // cache changed, check if there is any changes when comparring to the local list
+ // and what kind of change there is
+ iCompletedMessage = GetHeaderListUpdateL();
+ // is there headers to deliver
+ if ( iCompletedMessage == EhspsGetListHeadersRestart)
+ {
+ if (iHeaderDataList->Count())
+ {
+ // at least one header on the list
+ iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
+ // add list count
+ iDeliveryCount++;
+ // delivery of the first header
+ }
+ CompleteRequest( EhspsGetListHeadersRestart, iMessagePtr );
+ }
+ else if ( iCompletedMessage == EhspsGetListHeadersUpdate )
+ {
+ // return list update, count continues from where it was
+ iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
+ // add list count
+ iDeliveryCount++;
+ // deliver a list item
+ CompleteRequest( EhspsGetListHeadersUpdate, iMessagePtr );
+ }
+ else if (iCompletedMessage == EhspsGetListHeadersEmpty)
+ {
+ CompleteRequest( EhspsGetListHeadersEmpty, iMessagePtr );
+ // no list update available at the moment, continue the polling for list updates
+ }
+ }
+ else if ( !IsActive() )
+ {
+ After(KHeaderListUpdatePollingTimeSpan);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::GetHeaderListUpdateL
+// Checks if the header list has changed and returns the appropriate
+// ThspsServiceCompletedMessage answer.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+ThspsServiceCompletedMessage ChspsMaintenanceHandler::GetHeaderListUpdateL()
+ {
+ ThspsServiceCompletedMessage ret = EhspsGetListHeadersNoChange;
+
+ // chech if repository have a cache update available
+ TInt oldcount = iHeaderDataList->Count();
+ CArrayPtrSeg<HBufC8>* newheaderDataList = new( ELeave ) CArrayPtrSeg<HBufC8>
+ (KHeaderListGranularity);
+ CleanupStack::PushL( TCleanupItem( ResetAndDestroyArray, newheaderDataList ) );
+
+ GetHeaderListL( *newheaderDataList, *iSearchMask );
+ if ( newheaderDataList->Count() )
+ {
+ TBool reset = EFalse;
+ TBool found = EFalse;
+ TInt newcount = newheaderDataList->Count();
+ // cases:
+ // 0. both lists are empty => no change
+ if (!oldcount && !newcount)
+ {
+ ret = EhspsGetListHeadersNoChange;
+ }
+ else
+ // 1. new list has members but old list is empty => just add new headers on old list
+ // => restart anyway
+ if (!oldcount && newcount)
+ {
+ for (TInt k=0;k<newheaderDataList->Count();k++)
+ {
+ HBufC8* l = newheaderDataList->At(k)->AllocL();
+ if (l != NULL)
+ {
+ CleanupStack::PushL(l);
+ iHeaderDataList->AppendL(l);
+ CleanupStack::Pop(l);
+ }
+ }
+ ret = EhspsGetListHeadersRestart; // start from begin
+ }
+ // 2. new list is empty and old has members => empty old list too => empty the list
+ else if (!newcount && oldcount)
+ {
+ // must fetch whole list again
+ iHeaderDataList->ResetAndDestroy();
+ iDeliveryCount = 0;
+ ret = EhspsGetListHeadersEmpty; // empty the list
+ }
+ // 3. old list and new list both have members, newcount < oldcount => reset
+ else if (newcount < oldcount)
+ {
+ // must fetch whole list again
+ iHeaderDataList->ResetAndDestroy();
+ iDeliveryCount = 0;
+ GetHeaderListL( *iHeaderDataList, *iSearchMask );
+ ret = EhspsGetListHeadersRestart;
+ }
+ // 4. old list and new list both have members => examine next cases
+ else
+ {
+ TInt j=0;
+ for ( TInt i=0; i<iHeaderDataList->Count();i++ )
+ {
+ HBufC8* old = iHeaderDataList->At(i);
+ if (old != NULL)
+ {
+ while ( j < newheaderDataList->Count() )
+ {
+ HBufC8* cand = newheaderDataList->At(j);
+
+ if (cand != NULL)
+ {
+ if (CompareHeadersL(*old, *cand)) // is it there
+ {
+ // delete existing from the new list
+ newheaderDataList->Delete(j);
+ delete cand; //free allocated memory
+ found = ETrue;
+ break; // take next i in for for-loop
+ }
+ else
+ {
+ // not found at this round, let see will the next one be a hit
+ j++; // next j
+ }
+ }
+ else
+ {
+ // not found at this round, let see will the next one be a hit
+ j++; // next j
+ }
+ } // while
+ }
+ // did it found a match for entry i on iHeaderDataList
+ if (!found)
+ {
+ // lists do not match
+ reset = ETrue;
+ break;
+ }
+ } // for
+ if ( reset || newheaderDataList->Count() )
+ {
+ // must fetch whole list again
+ iHeaderDataList->ResetAndDestroy();
+ iDeliveryCount = 0;
+ GetHeaderListL( *iHeaderDataList, *iSearchMask );
+ ret = EhspsGetListHeadersRestart;
+ }
+ else
+ {
+ iDeliveryCount = 0;
+ ret = EhspsGetListHeadersNoChange;
+ }
+ }
+ }
+ else // no headers found => list must be emptied
+ {
+ // reset the list
+ iHeaderDataList->ResetAndDestroy();
+ iDeliveryCount = 0;
+ ret = EhspsGetListHeadersEmpty;
+ }
+ CleanupStack::Pop( newheaderDataList );
+ if ( newheaderDataList )
+ {
+ newheaderDataList->ResetAndDestroy();
+ delete newheaderDataList;
+ newheaderDataList = NULL;
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::GetHeaderListL
+// Fills aHeaderDataList with headers and sets the appropriate flag for active theme
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::GetHeaderListL(
+ CArrayPtrSeg<HBufC8>& aHeaderDataList,
+ const ChspsODT& aSearchMask )
+ {
+ HBufC8* headerBuf = aSearchMask.MarshalHeaderL();
+ if ( !headerBuf )
+ {
+ User::Leave(KErrGeneral);
+ }
+ CleanupStack::PushL( headerBuf );
+ ChspsODT* searchOdt = ChspsODT::UnMarshalHeaderLC( *headerBuf );
+
+ // Reset search results
+ aHeaderDataList.ResetAndDestroy();
+
+ for ( TInt i = 0; i < iHeaderListCache.Count(); i++ )
+ {
+ ChspsODT* header = iHeaderListCache.At( i );
+
+ // Check whether the header matches the search criteria
+ if ( FilterHeader( *searchOdt, *header ) )
+ {
+ // Append to the search results
+ HBufC8* data = header->MarshalHeaderL();
+ if ( data )
+ {
+ CleanupStack::PushL( data );
+ aHeaderDataList.AppendL( data );
+ CleanupStack::Pop( data );
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2, headerBuf ); // searchOdt, headerBuf
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::RestoredDefaultL
+// Goes through the themes for the application in order to find the Licensee
+// Default theme to restore.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::RestoredDefaultL( const ChspsODT& aSetMask, ChspsODT& aHeader )
+ {
+ TBool found = EFalse;
+ TUint mask = 0;
+ TUint rootUid = aSetMask.RootUid();
+ ChspsODT* odt;
+
+ if ( aSetMask.Flags() & EhspsThemeStatusOperatorDefault )
+ {
+ mask = EhspsThemeStatusOperatorDefault;
+ }
+ else if ( aSetMask.Flags() & EhspsThemeStatusUserDefault )
+ {
+ mask = EhspsThemeStatusUserDefault;
+ }
+
+ // If all but ROM based configurations should be removed
+ if ( aSetMask.Flags() & EhspsThemeStatusClean )
+ {
+ for( TInt i = 0; i < iHeaderListCache.Count(); i++) // delete themes from c:
+ {
+ odt = iHeaderListCache.At(i);
+
+ // Remove specific application configurations which are not matching the mask and
+ // the licencee default flag
+ if ( rootUid == odt->RootUid()
+ && !( (odt->Flags() & mask) && (aSetMask.Flags() & mask) )
+ && !( odt->Flags() & EhspsThemeStatusLicenceeDefault ) )
+ {
+ // do not care about possible error
+ TRAP_IGNORE( RemoveThemeL( *odt ) );
+ }
+ }
+ // update cache after deletion
+ iThemeServer.UpdateHeaderListCacheL();
+ }
+
+ // Try activating the first licencee restorable configuration in the cache
+ for( TInt i = 0; i < iHeaderListCache.Count() && !found; i++ )
+ {
+ odt = iHeaderListCache.At(i);
+ if( rootUid == odt->RootUid() && odt->Flags() & EhspsThemeStatusLicenceeRestorable )
+ {
+ if ( iThemeServer.ActivateThemeL( *odt, aHeader ) == KErrNone )
+ {
+ found = ETrue;
+ }
+ }
+ }
+ // any default will do, depends on restoration level
+ // this is safe because the default theme could be updated only with other default theme
+ mask = EhspsThemeStatusLicenceeDefault + EhspsThemeStatusOperatorDefault + EhspsThemeStatusUserDefault;
+
+ // If no luck so far, try activating a "default" configuration with the new mask
+ for( TInt i = 0; i < iHeaderListCache.Count() && !found; i++ )
+ {
+ odt = iHeaderListCache.At(i);
+
+ if( rootUid == odt->RootUid() && odt->Flags() & mask )
+ {
+ if ( iThemeServer.ActivateThemeL( *odt, aHeader ) == KErrNone )
+ {
+ found = ETrue;
+ }
+ }
+ }
+
+ // If still no success, just select the first one in the cache
+ if( !found )
+ { // should not get here
+ for( TInt i = 0; i < iHeaderListCache.Count() && !found; i++ ) // licensee default not found, activate some other theme
+ {
+ odt = iHeaderListCache.At(i);
+ if( rootUid == odt->RootUid() )
+ {
+ if ( iThemeServer.ActivateThemeL( *odt, aHeader ) == KErrNone )
+ {
+ found = ETrue;
+ }
+ }
+ }
+ }
+
+ // If there were no application specific configurations, give up
+ if( !found )
+ {
+ // should not get here
+ User::Leave( KErrNotFound );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::RemoveThemeL
+// Removes given theme from repository. If theme is in use (KErrInUse), then the theme
+// is added on cleanup list.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::RemoveThemeL( const ChspsODT& aSetMask )
+ {
+ // do not even try to delete a theme licencee default theme as it is located in rom
+ if( !( aSetMask.Flags() & EhspsThemeStatusLicenceeDefault ) )
+ {
+ iDefinitionRepository.RemoveThemeL( aSetMask );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::CompareHeadersL
+// Compares the two theme headers and returns ETrue if they are the same
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool ChspsMaintenanceHandler::CompareHeadersL(const TDesC8& aOldHeaderData, const TDesC8&
+ aNewHeaderData)
+ {
+ TBool ret;
+ ChspsODT* old = ChspsODT::UnMarshalHeaderLC(aOldHeaderData);
+ ChspsODT* cand= ChspsODT::UnMarshalHeaderLC(aNewHeaderData);
+ if ( old->RootUid() == cand->RootUid()
+ && old->ProviderUid() == cand->ProviderUid()
+ && old->ThemeUid() == cand->ThemeUid()
+ && !old->ThemeVersion().Compare(cand->ThemeVersion())
+ && old->Flags() == cand->Flags()
+ )
+ {
+ ret = ETrue;
+ }
+ else
+ {
+ ret = EFalse;
+ }
+ CleanupStack::PopAndDestroy( cand );
+ CleanupStack::PopAndDestroy( old );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::ComparePaths
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool ChspsMaintenanceHandler::ComparePaths(const ChspsODT& aOldHeader, const ChspsODT& aNewHeader)
+ {
+ TBool ret;
+ if ( aOldHeader.RootUid() == aNewHeader.RootUid()
+ && aOldHeader.ProviderUid() == aNewHeader.ProviderUid()
+ && aOldHeader.ThemeUid() == aNewHeader.ThemeUid()
+ && !aOldHeader.ThemeVersion().Compare(aNewHeader.ThemeVersion()) )
+ {
+ ret = ETrue;
+ }
+ else
+ {
+ ret = EFalse;
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::FilterHeader
+// Compares the header and mask and returns true if the mask doesn't have any different
+// values than the header (missing values are OK).
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool ChspsMaintenanceHandler::FilterHeader(
+ const ChspsODT& aMask,
+ const ChspsODT& aHeader )
+ {
+ TBool ret( EFalse );
+ if (
+ ( // 0 is not valid when comparing
+ (aMask.RootUid() && aMask.RootUid() == aHeader.RootUid())
+ ||
+ // 0 is OK in mask when aHeader is valid
+ (!aMask.RootUid() && aHeader.RootUid())
+ )
+ &&
+ (
+ (aMask.ProviderUid() && aMask.ProviderUid() == aHeader.ProviderUid())
+ ||
+ (!aMask.ProviderUid() && aHeader.ProviderUid())
+ )
+ &&
+ (
+ (aMask.ThemeUid() && aMask.ThemeUid() == aHeader.ThemeUid())
+ ||
+ (!aMask.ThemeUid() && aHeader.ThemeUid())
+ )
+ &&
+ (
+ (aMask.ThemeVersion().Length() && !aMask.ThemeVersion().Compare(
+ aHeader.ThemeVersion()))
+ ||
+ (!aMask.ThemeVersion().Length() && aHeader.ThemeVersion().Length())
+ )
+ &&
+ (
+ ( aMask.ConfigurationType() && aMask.ConfigurationType() == aHeader.ConfigurationType() )
+ ||
+ ( !aMask.ConfigurationType() )
+ )
+ &&
+ // Show widgets designed for the active resolution or scalable
+ ( ( aHeader.Family() & aMask.Family() ) || aHeader.Family() == 0 )
+ )
+ {
+ ret = ETrue;
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::RestoreDefaultAppConfL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::RestoreDefaultAppConfL(
+ ChspsODT*& aHeader,
+ ChspsODT& aOdt)
+ {
+
+ if ( aHeader->Flags() & EhspsThemeStatusLicenceeRestorable )
+ {
+ // Licensee restorable configuration active -> Reinstall configuration
+ iThemeServer.ReinstallConfL( aHeader->RootUid(), aHeader->ThemeUid() );
+ }
+ else
+ {
+ // Get licensee restorable configuation
+ ChspsODT* searchMask = ChspsODT::NewL();
+ CleanupStack::PushL( searchMask );
+ searchMask->SetRootUid( aHeader->RootUid() );
+ searchMask->SetFlags( EhspsThemeStatusLicenceeRestorable );
+ TInt pos( 0 );
+ iThemeServer.GetConfigurationHeader( *searchMask, aHeader, pos );
+ if ( aHeader )
+ {
+ // Activate licensee restorable configuration
+ iThemeServer.ActivateThemeL( *aHeader, aOdt );
+ ThspsRepositoryInfo info( EhspsODTActivated );
+ iDefinitionRepository.RegisterNotification( info );
+ }
+ else
+ {
+ // Licensee restorable configuration not found
+ // There must be at least one licensee restorable configuration
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::PopAndDestroy( searchMask );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// ChspsMaintenanceHandler::AddErrorConfigurationL()
+// -----------------------------------------------------------------------------
+//
+void ChspsMaintenanceHandler::AddErrorConfigurationL(
+ ChspsDomDocument& aAppDom,
+ ChspsDomNode& aMissingPluginNode,
+ const TInt aPluginUid
+ )
+ {
+ // Create a new dummy configuration element
+ ChspsDomNode* confNode = aAppDom.CreateElementNSL(
+ KConfigurationElement,
+ aMissingPluginNode.Namespace()
+ );
+ CleanupStack::PushL( confNode );
+
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrType, KConfTypeWidget );
+ _LIT8( KUnknown, "unknown" );
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrInterface, KUnknown );
+ hspsServerUtil::AddAttributeNumericL( *confNode, KConfigurationAttrUid, aPluginUid, EHex );
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrName, KUnknown );
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrNameEntity, KUnknown );
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrVersion, KUnknown );
+ hspsServerUtil::AddAttributeNumericL( *confNode, KConfigurationAttrMaxChild, 0, EDecimal );
+
+ // Indicate that the configuration is in error state
+ hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrState, KConfStateError );
+
+ // Set parent node
+ aMissingPluginNode.AddChildL( confNode );
+ CleanupStack::Pop( confNode );
+
+ confNode->SetParent( &aMissingPluginNode );
+
+ // Mandatory configuration-control node
+ ChspsDomNode* controlNode = aAppDom.CreateElementNSL(
+ KControlElement,
+ confNode->Namespace()
+ );
+ CleanupStack::PushL( controlNode );
+ confNode->AddChildL( controlNode );
+ CleanupStack::Pop( controlNode );
+
+ controlNode->SetParent( confNode );
+
+ // Mandatory configuration-control-settings node
+ ChspsDomNode* settingsNode = aAppDom.CreateElementNSL(
+ KSettingsElement,
+ controlNode->Namespace()
+ );
+ CleanupStack::PushL( settingsNode );
+ controlNode->AddChildL( settingsNode );
+ CleanupStack::Pop( settingsNode );
+ settingsNode->SetParent( controlNode );
+
+
+ // Mandatory configuration-resources node
+ ChspsDomNode* resourcesNode = aAppDom.CreateElementNSL(
+ KResourcesElement,
+ confNode->Namespace()
+ );
+ CleanupStack::PushL( resourcesNode );
+ confNode->AddChildL( resourcesNode );
+ CleanupStack::Pop( resourcesNode );
+ resourcesNode->SetParent( confNode );
+
+ }
+
+// end of file