diff -r ebe688cedc25 -r 7fdbb852d323 messagingappbase/msgerrorwatcher/src/MsgSentItemsObserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingappbase/msgerrorwatcher/src/MsgSentItemsObserver.cpp Wed Sep 01 12:31:54 2010 +0100 @@ -0,0 +1,362 @@ +/* +* Copyright (c) 2002 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: +* CMsgSentItemsObserver implementation file +* +*/ + + + +// INCLUDE FILES +#include +#include + +#include // link against centralrepository.lib +#include // link against CenRepNotifHandler.lib +#include // for Central Repository keys + +#include "MsgSentItemsObserver.h" + +#ifdef USE_LOGGER +#include "MsgErrorWatcherLogging.h" +#endif + +// CONSTANTS +//const TUid KUidMceApp = { 0x100058C5 }; //needed to request shared data notifications +const TMsvId KWatcherSentFolderId = KMsvSentEntryIdValue; +const TUint KMaxRetries = 3; +const TInt KMaxNumOfItems = 20; //Deafult value in case of error reading CommsDb +//const TInt KMsgErrorDiskSpaceForDelete = ( 5 * 1024 ); // minimum disk space needed when deleting messages +//_LIT( KSentItemsInUseOff, "0" ); + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CMsgSentItemsObserver::NewL +// +// Two-phased constructor. +// --------------------------------------------------------- +// +CMsgSentItemsObserver* CMsgSentItemsObserver::NewL( + CMsgErrorWatcher* aWatcher, + CMsvSession* aSession ) + { + CMsgSentItemsObserver* self = new ( ELeave ) + CMsgSentItemsObserver( aWatcher, aSession ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::CMsgSentItemsObserver +// +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------- +// +CMsgSentItemsObserver::CMsgSentItemsObserver( CMsgErrorWatcher* aWatcher, CMsvSession* aSession ) + : CActive( EPriorityStandard ), + iWatcher( aWatcher ), + iSession( aSession ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::~CMsgSentItemsObserver +// +// Destructor +// --------------------------------------------------------- +// +CMsgSentItemsObserver::~CMsgSentItemsObserver() + { + Cancel(); + if ( iNotifyHandler ) + { + iNotifyHandler->StopListening(); + } + delete iNotifyHandler; + delete iRepository; + if( iCleanupFlags & ESentItemsFolderObserverAdded ) + { + iSentItemsFolder->RemoveObserver( *this ); + } + delete iSentItemsFolder; + delete iEntry; + delete iOp; + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::ConstructL +// +// Symbian OS default constructor can leave. +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::ConstructL() + { +#ifdef USE_LOGGER + MEWLOGGER_ENTERFN( "SentItems: ConstructL" ); +#endif + //iMsgStoreDrive = MessageServer::CurrentDriveL( iSession->FileSession() ); + //register as observer of sent items folder + TMsvSelectionOrdering sort( KMsvNoGrouping, EMsvSortByDateReverse ); + iSentItemsFolder = CMsvEntry::NewL( *iSession, KWatcherSentFolderId, sort ); + iSentItemsFolder->AddObserverL( *this ); + iCleanupFlags |= ESentItemsFolderObserverAdded; + + //register as observer of user settings for sent folder + + // Central Repository + iRepository = CRepository::NewL( KCRUidMuiuSettings ); + iNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iRepository ); + iNotifyHandler->StartListeningL(); + +#ifdef USE_LOGGER + MEWLOGGER_LEAVEFN( "SentItems: ConstructL" ); +#endif + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::RunL +// +// Will only run when messages have been deleted +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::RunL() + { + //iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive ); +#ifdef USE_LOGGER + if( iStatus==KErrNone ) + { + MEWLOGGER_WRITE( "SentItems: deletion successful" ); + } + else + { + MEWLOGGER_WRITEF( _L("SentItems: deletion error %d"), iStatus.Int() ); + } +#endif + //Check if new messages have appeared into Sent Items while deleting + //the previous one(s). +#ifdef USE_LOGGER + MEWLOGGER_WRITEF( _L("SentItems: Retries: %d"), iRetryCounter ); +#endif + if ( iRetryCounter < KMaxRetries ) + { + iRetryCounter++; + TRAP_IGNORE( DeleteOldMessagesFromSentFolderL() ); + } + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::DoCancel +// +// From active object framework +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::DoCancel() + { + //iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive ); + if ( iOp ) + { + iOp->Cancel(); + } + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::HandleNotifyInt +// +// Notification from central repository +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::HandleNotifyInt( TUint32 aId, TInt aNewValue ) + { + if ( ( aId == KMuiuSentItemsInUse && aNewValue != 0 ) || + ( aId == KMuiuSentItemsCount && SentFolderIsBeingUsed() ) ) + { + iRetryCounter = 0; + //This is non-leaving function... + TRAPD( dummy, DeleteOldMessagesFromSentFolderL() ); + dummy=dummy; //Prevent arm5 build warning + } + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::HandleNotifyGeneric +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::HandleNotifyGeneric( TUint32 /*aId*/ ) + { + //Nothing. + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::HandleNotifyError +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::HandleNotifyError( TUint32 /*aId*/, TInt /*error*/, CCenRepNotifyHandler* /*aHandler*/ ) + { + //Nothing. + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::HandleEntryEventL +// +// Call back from msg that the sent items folder has changed +// so check if messages need to be deleted. +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::HandleEntryEventL( TMsvEntryEvent aEvent, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/ ) + { + switch( aEvent ) + { + case EMsvNewChildren: + { + if( !SentFolderIsBeingUsed() ) + { + //not taking ownership + CMsvEntrySelection* selection = + static_cast( aArg1 ); + iRetryCounter = 0; + DeleteMessagesFromSentFolderL( selection ); + return; + } + if( iSentItemsFolder->Count() > SentFolderUpperLimit() ) + { + iRetryCounter = 0; + DeleteOldMessagesFromSentFolderL(); + return; + } + } + break; + case EMsvEntryChanged: + case EMsvDeletedChildren: + case EMsvChildrenChanged: + case EMsvEntryDeleted: + case EMsvContextInvalid: + case EMsvChildrenMissing: + case EMsvChildrenInvalid: + case EMsvEntryMoved: + default: + break; + } + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::SentFolderIsBeingUsed +// +// Returns the user setting for use of the sent folder. If there +// is an error then the default value of ON (i.e ETrue) will +// be returned. +// --------------------------------------------------------- +// +TBool CMsgSentItemsObserver::SentFolderIsBeingUsed() + { + TInt isUsed = 1; + iRepository->Get( KMuiuSentItemsInUse, isUsed ); + return isUsed; + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::SentFolderUpperLimit +// +// Returns the user setting for max limit to the number of messages +// in the sent folder. If there is an error then the default value of +// KMaxNumOfItems will be returned +// --------------------------------------------------------- +// +TInt CMsgSentItemsObserver::SentFolderUpperLimit() + { + TInt numItems = KMaxNumOfItems; + iRepository->Get( KMuiuSentItemsCount, numItems ); + return numItems; + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::DeleteOldMessagesFromSentFolderL +// +// If there are more messages in the sent folder than the upper +// limit set by the user then delete the oldest messages. +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::DeleteOldMessagesFromSentFolderL() + { + CMsvEntrySelection* children = iSentItemsFolder->ChildrenL(); + CleanupStack::PushL( children ); + TInt limit = SentFolderUpperLimit(); + TInt sentMessageCount = children->Count(); + if( sentMessageCount <= limit ) + { + CleanupStack::PopAndDestroy( children ); + return; + } + CMsvEntrySelection* messagesToBeDeleted = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( messagesToBeDeleted ); + //oldest messages are at the end of the array + for( TInt index = sentMessageCount - 1; index >= limit; index-- ) + { + messagesToBeDeleted->AppendL( children->At( index ) ); + } + DeleteMessagesFromSentFolderL( messagesToBeDeleted ); + CleanupStack::PopAndDestroy( messagesToBeDeleted ); + CleanupStack::PopAndDestroy( children ); + } + +// --------------------------------------------------------- +// CMsgSentItemsObserver::DeleteMessagesFromSentFolderL +// +// Delete the messages specified by aSelection +// --------------------------------------------------------- +// +void CMsgSentItemsObserver::DeleteMessagesFromSentFolderL( CMsvEntrySelection* aSelection ) + { + if ( !IsActive() ) + { +#ifdef USE_LOGGER + MEWLOGGER_WRITEF( _L("SentItems: deleting %d messages from sent folder"), aSelection->Count() ); +#endif + const TMsvId id = aSelection->At( 0 ); + delete iEntry; + iEntry = 0; + iEntry = iSession->GetEntryL( id ); + iEntry->SetEntryL( iEntry->Entry().Parent() ); + + //if ( iSession->FileSession().ReserveDriveSpace( iMsgStoreDrive, KMsgErrorDiskSpaceForDelete ) == KErrNone ) + // { + // iSession->FileSession().GetReserveAccess( iMsgStoreDrive ); + // } + + delete iOp; + iOp = 0; + //TRAPD( err, + // { + iOp = iEntry->DeleteL( *aSelection, iStatus ); //delete acts on returned CMsvOperation* + // } ); + //if ( err ) + // { + // iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive ); + // User::Leave( err ); + // } + //else + // { + SetActive(); + // } + } + } + +// End of File +