messagingappbase/msgerrorwatcher/src/MsgSentItemsObserver.cpp
changeset 0 72b543305e3a
child 77 da6ac9d688df
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *       CMsgSentItemsObserver implementation file
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <watcher.h>
       
    23 #include <msvids.h>
       
    24 
       
    25 #include <centralrepository.h>    // link against centralrepository.lib
       
    26 #include <cenrepnotifyhandler.h>  // link against CenRepNotifHandler.lib
       
    27 #include <messaginginternalcrkeys.h> // for Central Repository keys
       
    28 
       
    29 #include "MsgSentItemsObserver.h"
       
    30 
       
    31 #ifdef USE_LOGGER
       
    32 #include "MsgErrorWatcherLogging.h"
       
    33 #endif
       
    34 
       
    35 // CONSTANTS
       
    36 //const TUid KUidMceApp = { 0x100058C5 }; //needed to request shared data notifications
       
    37 const TMsvId KWatcherSentFolderId = KMsvSentEntryIdValue;
       
    38 const TUint KMaxRetries = 3;
       
    39 const TInt KMaxNumOfItems = 20; //Deafult value in case of error reading CommsDb
       
    40 //const TInt KMsgErrorDiskSpaceForDelete = ( 5 * 1024 ); // minimum disk space needed when deleting messages
       
    41 //_LIT( KSentItemsInUseOff, "0" );
       
    42 
       
    43 
       
    44 // ================= MEMBER FUNCTIONS =======================
       
    45 
       
    46 // ---------------------------------------------------------
       
    47 // CMsgSentItemsObserver::NewL
       
    48 //
       
    49 // Two-phased constructor.
       
    50 // ---------------------------------------------------------
       
    51 //
       
    52 CMsgSentItemsObserver* CMsgSentItemsObserver::NewL( 
       
    53         CMsgErrorWatcher* aWatcher, 
       
    54         CMsvSession* aSession )
       
    55     {
       
    56     CMsgSentItemsObserver* self = new ( ELeave )
       
    57         CMsgSentItemsObserver( aWatcher, aSession );
       
    58 
       
    59     CleanupStack::PushL( self );
       
    60     self->ConstructL();
       
    61     CleanupStack::Pop( self );
       
    62     return self;
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------
       
    66 // CMsgSentItemsObserver::CMsgSentItemsObserver
       
    67 //
       
    68 // C++ default constructor can NOT contain any code, that
       
    69 // might leave.
       
    70 // ---------------------------------------------------------
       
    71 //
       
    72 CMsgSentItemsObserver::CMsgSentItemsObserver( CMsgErrorWatcher* aWatcher, CMsvSession* aSession )
       
    73     : CActive( EPriorityStandard ),
       
    74     iWatcher( aWatcher ),
       
    75     iSession( aSession )
       
    76     {
       
    77     CActiveScheduler::Add( this );
       
    78     }
       
    79 
       
    80 // ---------------------------------------------------------
       
    81 // CMsgSentItemsObserver::~CMsgSentItemsObserver
       
    82 //
       
    83 // Destructor
       
    84 // ---------------------------------------------------------
       
    85 //
       
    86 CMsgSentItemsObserver::~CMsgSentItemsObserver()
       
    87     {
       
    88     Cancel();
       
    89     if ( iNotifyHandler )
       
    90         {        
       
    91         iNotifyHandler->StopListening();
       
    92         }
       
    93     delete iNotifyHandler;
       
    94     delete iRepository;
       
    95     if( iCleanupFlags & ESentItemsFolderObserverAdded )
       
    96         {
       
    97         iSentItemsFolder->RemoveObserver( *this );
       
    98         }
       
    99     delete iSentItemsFolder;
       
   100     delete iEntry;
       
   101     delete iOp;
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------
       
   105 // CMsgSentItemsObserver::ConstructL
       
   106 //
       
   107 // Symbian OS default constructor can leave.
       
   108 // ---------------------------------------------------------
       
   109 //
       
   110 void CMsgSentItemsObserver::ConstructL()
       
   111     {
       
   112 #ifdef USE_LOGGER
       
   113     MEWLOGGER_ENTERFN( "SentItems: ConstructL" );
       
   114 #endif
       
   115     //iMsgStoreDrive = MessageServer::CurrentDriveL( iSession->FileSession() );
       
   116     //register as observer of sent items folder
       
   117     TMsvSelectionOrdering sort( KMsvNoGrouping, EMsvSortByDateReverse );
       
   118     iSentItemsFolder = CMsvEntry::NewL( *iSession, KWatcherSentFolderId, sort );
       
   119     iSentItemsFolder->AddObserverL( *this );
       
   120     iCleanupFlags |= ESentItemsFolderObserverAdded;
       
   121     
       
   122     //register as observer of user settings for sent folder
       
   123 
       
   124     // Central Repository
       
   125     iRepository = CRepository::NewL( KCRUidMuiuSettings );
       
   126     iNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iRepository );
       
   127     iNotifyHandler->StartListeningL();
       
   128 
       
   129 #ifdef USE_LOGGER
       
   130     MEWLOGGER_LEAVEFN( "SentItems: ConstructL" );
       
   131 #endif
       
   132     }
       
   133 
       
   134 // ---------------------------------------------------------
       
   135 // CMsgSentItemsObserver::RunL
       
   136 //
       
   137 // Will only run when messages have been deleted
       
   138 // ---------------------------------------------------------
       
   139 //
       
   140 void CMsgSentItemsObserver::RunL()
       
   141     {
       
   142     //iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive );
       
   143 #ifdef USE_LOGGER
       
   144     if( iStatus==KErrNone )
       
   145         {
       
   146         MEWLOGGER_WRITE( "SentItems: deletion successful" );
       
   147         }
       
   148     else
       
   149         {
       
   150         MEWLOGGER_WRITEF( _L("SentItems: deletion error %d"), iStatus.Int() );
       
   151         } 
       
   152 #endif
       
   153     //Check if new messages have appeared into Sent Items while deleting
       
   154     //the previous one(s).
       
   155 #ifdef USE_LOGGER
       
   156     MEWLOGGER_WRITEF( _L("SentItems: Retries: %d"), iRetryCounter );
       
   157 #endif
       
   158     if ( iRetryCounter < KMaxRetries )
       
   159         {
       
   160         iRetryCounter++;
       
   161         TRAP_IGNORE( DeleteOldMessagesFromSentFolderL() );
       
   162         }
       
   163     }
       
   164 
       
   165 // ---------------------------------------------------------
       
   166 // CMsgSentItemsObserver::DoCancel
       
   167 //
       
   168 // From active object framework
       
   169 // ---------------------------------------------------------
       
   170 //
       
   171 void CMsgSentItemsObserver::DoCancel()
       
   172     {
       
   173     //iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive );
       
   174     if ( iOp )
       
   175         {
       
   176         iOp->Cancel();
       
   177         }
       
   178     }
       
   179 
       
   180 // ---------------------------------------------------------
       
   181 // CMsgSentItemsObserver::HandleNotifyInt
       
   182 //
       
   183 // Notification from central repository
       
   184 // ---------------------------------------------------------
       
   185 //
       
   186 void CMsgSentItemsObserver::HandleNotifyInt( TUint32 aId, TInt aNewValue )
       
   187     {    
       
   188     if ( ( aId == KMuiuSentItemsInUse && aNewValue != 0 ) ||
       
   189          ( aId == KMuiuSentItemsCount && SentFolderIsBeingUsed() ) )
       
   190         {
       
   191         iRetryCounter = 0;
       
   192         //This is non-leaving function...
       
   193         TRAPD( dummy, DeleteOldMessagesFromSentFolderL() );
       
   194         dummy=dummy; //Prevent arm5 build warning
       
   195         }
       
   196     }
       
   197 
       
   198 // ---------------------------------------------------------
       
   199 // CMsgSentItemsObserver::HandleNotifyGeneric
       
   200 // ---------------------------------------------------------
       
   201 //
       
   202 void CMsgSentItemsObserver::HandleNotifyGeneric( TUint32 /*aId*/ )
       
   203     {
       
   204     //Nothing.
       
   205     }
       
   206     
       
   207 // ---------------------------------------------------------
       
   208 // CMsgSentItemsObserver::HandleNotifyError
       
   209 // ---------------------------------------------------------
       
   210 //
       
   211 void CMsgSentItemsObserver::HandleNotifyError( TUint32 /*aId*/, TInt /*error*/, CCenRepNotifyHandler* /*aHandler*/ )
       
   212     {
       
   213     //Nothing.
       
   214     }
       
   215   
       
   216 // ---------------------------------------------------------
       
   217 // CMsgSentItemsObserver::HandleEntryEventL
       
   218 //
       
   219 // Call back from msg that the sent items folder has changed
       
   220 // so check if messages need to be deleted.
       
   221 // ---------------------------------------------------------
       
   222 //
       
   223 void CMsgSentItemsObserver::HandleEntryEventL( TMsvEntryEvent aEvent, TAny* aArg1, TAny* /*aArg2*/, TAny* /*aArg3*/ )
       
   224     {   
       
   225     switch( aEvent )
       
   226         {
       
   227         case EMsvNewChildren:
       
   228             {
       
   229             if( !SentFolderIsBeingUsed() )
       
   230                 {
       
   231                 //not taking ownership
       
   232                 CMsvEntrySelection* selection =
       
   233                     static_cast<CMsvEntrySelection*>( aArg1 );
       
   234                 iRetryCounter = 0;
       
   235                 DeleteMessagesFromSentFolderL( selection );
       
   236                 return;
       
   237                 }
       
   238             if( iSentItemsFolder->Count() > SentFolderUpperLimit() )
       
   239                 {
       
   240                 iRetryCounter = 0;
       
   241                 DeleteOldMessagesFromSentFolderL();
       
   242                 return;
       
   243                 }
       
   244             }
       
   245             break;
       
   246         case EMsvEntryChanged:
       
   247         case EMsvDeletedChildren:
       
   248         case EMsvChildrenChanged:
       
   249         case EMsvEntryDeleted:
       
   250         case EMsvContextInvalid:
       
   251         case EMsvChildrenMissing:
       
   252         case EMsvChildrenInvalid:
       
   253         case EMsvEntryMoved:
       
   254         default:
       
   255             break;
       
   256         }
       
   257     }
       
   258 
       
   259 // ---------------------------------------------------------
       
   260 // CMsgSentItemsObserver::SentFolderIsBeingUsed
       
   261 //
       
   262 // Returns the user setting for use of the sent folder. If there
       
   263 // is an error then the default value of ON (i.e ETrue) will
       
   264 // be returned.
       
   265 // ---------------------------------------------------------
       
   266 //
       
   267 TBool CMsgSentItemsObserver::SentFolderIsBeingUsed()
       
   268     {
       
   269     TInt isUsed = 1;
       
   270    	iRepository->Get( KMuiuSentItemsInUse, isUsed );
       
   271     return isUsed;
       
   272     }
       
   273 
       
   274 // ---------------------------------------------------------
       
   275 // CMsgSentItemsObserver::SentFolderUpperLimit
       
   276 //
       
   277 // Returns the user setting for max limit to the number of messages
       
   278 // in the sent folder. If there is an error then the default value of
       
   279 // KMaxNumOfItems will be returned
       
   280 // ---------------------------------------------------------
       
   281 //
       
   282 TInt CMsgSentItemsObserver::SentFolderUpperLimit()
       
   283     {
       
   284     TInt numItems = KMaxNumOfItems;
       
   285    	iRepository->Get( KMuiuSentItemsCount, numItems );
       
   286     return numItems;
       
   287     }
       
   288 
       
   289 // ---------------------------------------------------------
       
   290 // CMsgSentItemsObserver::DeleteOldMessagesFromSentFolderL
       
   291 //
       
   292 // If there are more messages in the sent folder than the upper
       
   293 // limit set by the user then delete the oldest messages.
       
   294 // ---------------------------------------------------------
       
   295 //
       
   296 void CMsgSentItemsObserver::DeleteOldMessagesFromSentFolderL()
       
   297     {
       
   298     CMsvEntrySelection* children = iSentItemsFolder->ChildrenL();
       
   299     CleanupStack::PushL( children );
       
   300     TInt limit = SentFolderUpperLimit();
       
   301     TInt sentMessageCount = children->Count();
       
   302     if( sentMessageCount <= limit )
       
   303         {
       
   304         CleanupStack::PopAndDestroy( children );
       
   305         return;
       
   306         }
       
   307     CMsvEntrySelection* messagesToBeDeleted = new ( ELeave ) CMsvEntrySelection;
       
   308     CleanupStack::PushL( messagesToBeDeleted );
       
   309     //oldest messages are at the end of the array
       
   310     for( TInt index = sentMessageCount - 1; index >= limit; index-- )
       
   311         {
       
   312         messagesToBeDeleted->AppendL( children->At( index ) );
       
   313         }
       
   314     DeleteMessagesFromSentFolderL( messagesToBeDeleted );
       
   315     CleanupStack::PopAndDestroy( messagesToBeDeleted  ); 
       
   316     CleanupStack::PopAndDestroy( children );
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------
       
   320 // CMsgSentItemsObserver::DeleteMessagesFromSentFolderL
       
   321 //
       
   322 // Delete the messages specified by aSelection
       
   323 // ---------------------------------------------------------
       
   324 //
       
   325 void CMsgSentItemsObserver::DeleteMessagesFromSentFolderL( CMsvEntrySelection* aSelection )
       
   326     {
       
   327     if ( !IsActive() )
       
   328         {
       
   329 #ifdef USE_LOGGER
       
   330         MEWLOGGER_WRITEF( _L("SentItems: deleting %d messages from sent folder"), aSelection->Count() );
       
   331 #endif
       
   332         const TMsvId id = aSelection->At( 0 );
       
   333         delete iEntry;
       
   334         iEntry = 0;
       
   335         iEntry = iSession->GetEntryL( id );
       
   336         iEntry->SetEntryL( iEntry->Entry().Parent() );
       
   337 
       
   338         //if ( iSession->FileSession().ReserveDriveSpace( iMsgStoreDrive, KMsgErrorDiskSpaceForDelete ) == KErrNone )
       
   339         //    {
       
   340         //    iSession->FileSession().GetReserveAccess( iMsgStoreDrive );
       
   341         //    }
       
   342 
       
   343         delete iOp;
       
   344         iOp = 0;
       
   345         //TRAPD( err,
       
   346         //    {
       
   347             iOp = iEntry->DeleteL( *aSelection, iStatus ); //delete acts on returned CMsvOperation*
       
   348         //    } );
       
   349         //if ( err )
       
   350         //    {
       
   351         //    iSession->FileSession().ReleaseReserveAccess( iMsgStoreDrive );
       
   352         //    User::Leave( err );
       
   353         //    }
       
   354         //else
       
   355         //    {
       
   356             SetActive();
       
   357         //    }
       
   358         }
       
   359     }
       
   360 
       
   361 //  End of File  
       
   362