diff -r fd64c38c277d -r b46a585f6909 phonebookengines_old/contactsmodel/cntsrv/src/CIniFileManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines_old/contactsmodel/cntsrv/src/CIniFileManager.cpp Fri Jun 11 13:29:23 2010 +0300 @@ -0,0 +1,440 @@ +// Copyright (c) 2005-2009 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: +// + +/** + @file + @internalComponent + @released +*/ + + +#include "CIniFileManager.h" +#include "CCntDbManagerController.h" +#include "CCntBackupRestoreAgent.h" +#include "CntCurrentItemMap.h" +#include "CntSpeedDials.h" + +// uncomment this for debug logging +//#define INIFILE_DEBUG_LOG + + + +const TUid KContactsIniUid = { 0x10009099 }; +const TUid KContactsCurrentDatabaseUid = { 0x1000909A }; +const TUid KUidContactsDefaultDatabaseLocation = { 0x1020380A }; + +const TInt KIniFileSaveDelay = 100000; + +/** +First phase constructor. +*/ +CIniFileManager::CIniFileManager(RFs& aFs, CCntDbManagerController& aDbMgrCtrlr) + : CTimer(CActive::EPriorityStandard), iFs(aFs), iDbMgrCtrlr(aDbMgrCtrlr), iBackupFlag(ENoSaveRestore) + { + CActiveScheduler::Add(this); + } + + +/** +Object factory method. +*/ +CIniFileManager* CIniFileManager::NewL(RFs& aFs, CCntDbManagerController& aDbMgrCtrlr) + { + CIniFileManager* IniFileManager = new (ELeave) CIniFileManager(aFs, aDbMgrCtrlr); + CleanupStack::PushL(IniFileManager); + IniFileManager->ConstructL(); + CleanupStack::Pop(IniFileManager); + return IniFileManager; + } + + +/** +Second phase constructor. +*/ +void CIniFileManager::ConstructL() + { + CTimer::ConstructL(); + iSpeedDialManager = new(ELeave) CCntServerSpeedDialManager(); + iCurrentItemMap = new(ELeave) CCntServerCurrentItemMap(); + iCurrentDb = KNullDesC; + // Restore the current database if possible. If this fails, the + // current database is set to KNullDesC (i.e. zero'd) + RequestRestoreIniFileSettingsL(); + } + + +CIniFileManager::~CIniFileManager() + { + if (iFs.Handle()!=0) + { + TRAP_IGNORE(SaveIniFileSettingsL(ESaveAll,EFalse)); + } + delete iSpeedDialManager; + delete iCurrentItemMap; + } + + +/** +Update/create a map entry for the current item associated with a database file. +*/ +void CIniFileManager::SetCurrentItemForDatabaseL(const TDesC& aDatabase, TContactItemId aContactId) + { + // Does the specified database contain a current item already? + TInt index = KErrNotFound; + if (iCurrentItemMap->EntryAvailable(aDatabase, index)) + { + // Yes, already exists, so update it.... + iCurrentItemMap->UpdateEntryL(index, aContactId); + } + else + { + // No, so create a new entry to represent this database + iCurrentItemMap->AddEntryL(aDatabase, aContactId); + } + } + + +void CIniFileManager::RemoveCurrentItemL(const TDesC& aDatabase) + { + SetCurrentItemForDatabaseL(aDatabase, KNullContactId); + } + + +void CIniFileManager::SetCurrentItemL(const TDesC& aDatabase, TContactItemId aNewCurrentItem) + { + SetCurrentItemForDatabaseL(aDatabase, aNewCurrentItem); + } + + +/** +Returns the current item associated with the specified database. +*/ +TContactItemId CIniFileManager::CurrentItem(const TDesC& aDatabase) const + { + return iCurrentItemMap->CurrentItem(aDatabase); + } + + +const TDesC& CIniFileManager::CurrentDb() const + { + return iCurrentDb; + } + + +void CIniFileManager::SetCurrentDb(const TDesC& aDb) + { + iCurrentDb = aDb; + } + + +CCntServerSpeedDialManager& CIniFileManager::SpeedDialManager() + { + return *iSpeedDialManager; + } + + +void CIniFileManager::ScheduleSaveIniFileSettings(TInt aSaveFlags, TBool aReplace) + { + // make sure all requested writes are saved + iSaveType |= aSaveFlags; + iReplace = aReplace; + + // make sure change isn't due to Internalize + if (iBackupFlag != EIsRestoring) + { + iBackupFlag = ERequestSave; + //iNumberOfAttemptedRetries = 0; + + // set the time to RunL if not already set to run + // check that no Backup or Restore is in progress, + // For Backup And Restore + if (!(iDbMgrCtrlr.BackupRestoreAgent().BackupInProgress()) && + !(iDbMgrCtrlr.BackupRestoreAgent().RestoreInProgress())) + { + if (!IsActive()) + { +#ifdef INIFILE_DEBUG_LOG + RDebug::Print(_L("\n[CNTMODEL] CIniFileManager::ScheduleSaveIniFileSettings(aSaveFlags = %i, aReplace %i)\r\n"),aSaveFlags, aReplace); +#endif + After(KIniFileSaveDelay); + } + } + } + } + + +void CIniFileManager::SaveIniFileSettingsIfRequestedL() + { + if (iBackupFlag == ERequestSave) + { + // Don't RunL + Cancel(); + + SaveIniFileSettingsL(iSaveType, iReplace); + iBackupFlag = ENoSaveRestore; + } + } + + +void CIniFileManager::RequestRestoreIniFileSettingsL() + { + if (!(iDbMgrCtrlr.BackupRestoreAgent().RestoreInProgress())) + { + TInt ret = StartRestoreIniFileSettings(); + switch (ret) + { + case KErrNone: + break; + // If file does not exist create ini file immediately. + case KErrPathNotFound: + SaveIniFileSettingsL(ESaveAll, EFalse); + break; + // If file is damaged replace ini file. + case KErrEof: + SaveIniFileSettingsL(ESaveAll, ETrue); + break; + default: +#if defined(_DEBUG) + User::Leave(KErrNotSupported); +#endif + break; //Would not build in UREL without it + } + } + } + + +TInt CIniFileManager::StartRestoreIniFileSettings() + { + iBackupFlag = EIsRestoring; + TInt err; + TRAP(err,RestoreIniFileSettingsL()); + iBackupFlag = ENoSaveRestore; + return err ; + } + + +void CIniFileManager::GetIniFileNameL(TDes& aFileName, TBool aIncPrivatePath) + { + if (aIncPrivatePath) + { + User::LeaveIfError(iFs.PrivatePath(aFileName)); + } + // Drive name goes before the path. + aFileName.Insert(0,TDriveUnit(EDriveC).Name()); + // Filename goes after the path. + aFileName.Append(KContactsIniFileName); + } + + +/** +Restore server-wide settings from the contacts ini file. +*/ +void CIniFileManager::RestoreIniFileSettingsL() + { + // Initial location for Default database + SetDefaultDatabaseDrive(TDriveUnit(EDriveC),EFalse); + + TFileName iniFile; + GetIniFileNameL(iniFile); + CDictionaryFileStore* iniStore = IniFileStoreLC(iniFile); + + // Load settings + iCurrentItemMap->RestoreL(*iniStore); + iSpeedDialManager->RestoreL(*iniStore); + + // Current database + RestoreCurrentDatabaseL(*iniStore); + + // Default database location + RestoreDefaultDbDriveL(*iniStore); + + // Tidy up + CleanupStack::PopAndDestroy(iniStore); + } + + +void CIniFileManager::SetDefaultDatabaseDrive(TDriveUnit aDriveUnit, TBool aDriveSet) + { + iDefaultDriveUnit = aDriveUnit; + iDatabaseDriveSet = aDriveSet; + } + + +/** +Restore the current database filename from the ini file. +*/ +void CIniFileManager::RestoreCurrentDatabaseL(CDictionaryFileStore& aStore) + { + if (aStore.IsPresentL(KContactsCurrentDatabaseUid)) + { + RDictionaryReadStream stream; + stream.OpenLC(aStore, KContactsCurrentDatabaseUid); + stream >> iCurrentDb; + CleanupStack::PopAndDestroy(); // stream + } + } + + +/** +Restore the current database filename from the ini file. +*/ +void CIniFileManager::RestoreDefaultDbDriveL(CDictionaryFileStore& aStore) + { + if (aStore.IsPresentL(KUidContactsDefaultDatabaseLocation)) + { + TDriveUnit driveUnit; + RDictionaryReadStream stream; + + stream.OpenLC(aStore, KUidContactsDefaultDatabaseLocation); + driveUnit = stream.ReadInt32L(); + CleanupStack::PopAndDestroy(); // stream + + SetDefaultDatabaseDrive(driveUnit); + iDbMgrCtrlr.RestoreDatabaseDrive(driveUnit); // restore drive setting in DBManagerController + } + } + + +void CIniFileManager::RetryStoreOperation() + { + if (iBackupFlag == ERequestSave && !IsActive()) + { + // can RunL now + After(0); + } + } + + +void CIniFileManager::RunL() + { + const TInt error = iStatus.Int(); + +#ifdef INIFILE_DEBUG_LOG + RDebug::Print(_L("[CNTMODEL] CIniFileManager::RunL() - error %i, iBackupFlag %i\r\n"), error, iBackupFlag); +#endif + + // operation isn't cancelled + if (error == KErrNone && iBackupFlag == ERequestSave) + { + SaveIniFileSettingsL(iSaveType, iReplace); + iBackupFlag = ENoSaveRestore; + } + } + + +TInt CIniFileManager::RunError(TInt aError) + { +#ifdef INIFILE_DEBUG_LOG + RDebug::Print(_L("[CNTMODEL] CIniFileManager::RunError(aError = %i)\r\n"), aError); +#else + aError = aError; // remove compiler warning for unreferenced parameter +#endif + // cannot do anything about the error + // - unless it occurred during a Backup, when it will already be retried + + return KErrNone; + } + + +/** +Save server-wide settings to the contacts model ini file. +*/ +void CIniFileManager::SaveIniFileSettingsL(TInt aSaveFlags, TBool aReplace) + { + TFileName iniFile; + GetIniFileNameL(iniFile); + iFs.MkDirAll(iniFile); + + if (aReplace) + { + iFs.Delete(iniFile); + } + + // Get the ini store + CDictionaryFileStore* iniStore = IniFileStoreLC(iniFile); + + // Save settings + if ((aSaveFlags & ESaveCurrentItem) && iCurrentItemMap) + { + iCurrentItemMap->StoreL(*iniStore); + } + + if ((aSaveFlags & ESaveSpeedDials) && iSpeedDialManager) + { + iSpeedDialManager->StoreL(*iniStore); + } + + // Current database + if (aSaveFlags & ESaveCurrentDatabase) + { + StoreCurrentDatabaseL(*iniStore); + } + + // Default database location + if (aSaveFlags & ESaveDefaultDbDrive) + { + StoreDefaultDbDriveL(*iniStore); + } + + // Commit + iniStore->CommitL(); + + // Tidy up + CleanupStack::PopAndDestroy(); // iniStore + } + + +/** +Return a pointer to the contacts ini file. +*/ +CDictionaryFileStore* CIniFileManager::IniFileStoreLC(TFileName& aIniFile) + { + return CDictionaryFileStore::OpenLC(iFs, aIniFile, KContactsIniUid); + } + + +/** +Save the current database filename to the ini file. +*/ +void CIniFileManager::StoreCurrentDatabaseL(CDictionaryFileStore& aStore) + { + RDictionaryWriteStream stream; + stream.AssignLC(aStore, KContactsCurrentDatabaseUid); + stream << iCurrentDb; + stream.CommitL(); + CleanupStack::PopAndDestroy(); // stream + } + + +/** +Save the default database drive to the ini file. +*/ +void CIniFileManager::StoreDefaultDbDriveL(CDictionaryFileStore& aStore) + { + if (iDatabaseDriveSet) + { + RDictionaryWriteStream stream; + stream.AssignLC(aStore, KUidContactsDefaultDatabaseLocation); + stream.WriteInt32L(iDefaultDriveUnit); + stream.CommitL(); + CleanupStack::PopAndDestroy(); // stream + } + } + + +TBool& CIniFileManager::DatabaseDriveSet() + { + return iDatabaseDriveSet; + }