messagingappbase/ncnlist/src/CNcnNotifApiObserver.cpp
changeset 0 72b543305e3a
child 14 c6838af47512
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2004 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:   The purpose of this class is to observe if there are messages
       
    15 *                in the Email.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <e32base.h>
       
    23 #include <MuiuMsvUiServiceUtilities.h>  // MsvUiServiceUtilities
       
    24 #include <msvstd.hrh>
       
    25 #include <mtclreg.h>                    // For CClientMtmRegistry
       
    26 #include <miuthdr.h>
       
    27 #include <ImumInternalApi.h>            // CImumInternalApi
       
    28 #include <ImumInSettingsKeys.h>         // TImumInSettings
       
    29 #include <ImumInSettingsData.h>         // CImumSettingsData
       
    30 
       
    31 #include <muiuemailtools.h>
       
    32 #include <SendUiConsts.h>   // KSenduiMtmSyncMLEmailUid 
       
    33 
       
    34 #include "CNcnNotifApiObserver.h"
       
    35 #include "NcnModelBase.h"
       
    36 #include "CNcnMsvSessionHandler.h"
       
    37 #include "NcnTimer.h"
       
    38 #include <NcnListInternalCRKeys.h>
       
    39 #include <muiumsvuiserviceutilitiesinternal.h> // Messaging utilites
       
    40 #include <messaginginternalcrkeys.h>
       
    41 
       
    42 
       
    43 // ================= LOCAL CONSTANTS =======================
       
    44 namespace
       
    45     {
       
    46     // Timer iteration delay in microseconds
       
    47     const TUint KTimerIterationDelay = 1 * 1000 * 1000;
       
    48     
       
    49     // Mail technology type
       
    50     const TUid KMailTechnologyTypeUid = { 0x10001671 };
       
    51     }
       
    52 
       
    53 // ======================== INTERNAL HELPER CLASS ==============================
       
    54 
       
    55 CNcnNotifApiObserver::TNcnMailBoxStatus::TNcnMailBoxStatus( 
       
    56     TMsvId aMailBox )
       
    57     : iMailBox( aMailBox ),
       
    58       iMTMType( KNullUid ),
       
    59       iMailBoxTechnologyType( KNullUid),
       
    60       iPublishedNewEmailCount( 0 ),
       
    61       iHighestEMailMsvId( 0 ),
       
    62       iHighestIMAPId(0),
       
    63       iLatestMessageArrival(0),
       
    64       iUnreadCheckpointMsvId( 0 ),
       
    65       iPublishedCheckpointMsvId( 0 ),
       
    66       iPublishedCheckpointIMAPId(0),
       
    67       iPublishedCheckpointTimeStamp(0),
       
    68       iNewMessageIds( 5 ),
       
    69       iNotified( ETrue ),
       
    70       iIcon(ETrue),
       
    71       iTone(ETrue),
       
    72       iNote(ETrue),
       
    73       iShowIcon(ETrue)
       
    74     {
       
    75     }
       
    76                 
       
    77 TInt CNcnNotifApiObserver::TNcnMailBoxStatus::Compare(
       
    78     const TNcnMailBoxStatus& aFirst, 
       
    79     const TNcnMailBoxStatus& aSecond )
       
    80     {
       
    81     if ( aFirst.iMailBox < aSecond.iMailBox )
       
    82         {
       
    83         return -1;
       
    84         }        
       
    85     else if ( aFirst.iMailBox > aSecond.iMailBox )
       
    86         {
       
    87         return 1;
       
    88         }
       
    89     else
       
    90         {
       
    91         return 0;
       
    92         }                        
       
    93     }
       
    94                                      
       
    95 TBool CNcnNotifApiObserver::TNcnMailBoxStatus::Match( 
       
    96     const TNcnMailBoxStatus& aFirst, 
       
    97     const TNcnMailBoxStatus& aSecond )
       
    98     {
       
    99     TBool ret = EFalse;
       
   100     
       
   101     if( aFirst.iMailBox == aSecond.iMailBox )
       
   102         {
       
   103         ret = ETrue;
       
   104         }
       
   105     
       
   106     return ret;
       
   107     }
       
   108 
       
   109 // ============================ MEMBER FUNCTIONS ===============================
       
   110 
       
   111 // ---------------------------------------------------------
       
   112 // CNcnNotifApiObserver default constructor
       
   113 // ---------------------------------------------------------
       
   114 //
       
   115 CNcnNotifApiObserver::CNcnNotifApiObserver( 
       
   116     CNcnModelBase& aModel )
       
   117     : iModel( aModel ),
       
   118       iMsvSession(NULL)
       
   119     {    
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------
       
   123 // CNcnNotifApiObserver::ConstructL
       
   124 // ---------------------------------------------------------
       
   125 //
       
   126 void CNcnNotifApiObserver::ConstructL()
       
   127     {
       
   128     NCN_RDEBUG( _L("CNcnNotifApiObserver::ConstructL - Entry") );    
       
   129 
       
   130     // listen to msv session handler
       
   131     iModel.MsvSessionHandler().AddObserverL( this );
       
   132     
       
   133     NCN_RDEBUG( _L("CNcnNotifApiObserver::ConstructL - Exit") );
       
   134     }
       
   135 
       
   136 
       
   137 // ---------------------------------------------------------
       
   138 // CNcnNotifApiObserver::NewL
       
   139 // ---------------------------------------------------------
       
   140 //
       
   141 CNcnNotifApiObserver* CNcnNotifApiObserver::NewL( 
       
   142     CNcnModelBase& aModel )
       
   143     {
       
   144     // Create the observer instance
       
   145     CNcnNotifApiObserver* self = 
       
   146         new (ELeave) CNcnNotifApiObserver( aModel );
       
   147 
       
   148     // Call the construct safely
       
   149     CleanupStack::PushL( self );
       
   150     self->ConstructL();
       
   151     CleanupStack::Pop();
       
   152         
       
   153     return self;
       
   154     }
       
   155 
       
   156 
       
   157 // ---------------------------------------------------------
       
   158 // CNcnNotifApiObserver::~CNcnNotifApiObserver
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 CNcnNotifApiObserver::~CNcnNotifApiObserver()
       
   162     {
       
   163     delete iTimer;
       
   164     
       
   165     iMailBoxStatusArray.Close();
       
   166 
       
   167     // stop listening to msv session handler
       
   168     iModel.MsvSessionHandler().RemoveObserver( this );
       
   169     }
       
   170 
       
   171 // ---------------------------------------------------------
       
   172 // CNcnNotifApiObserver::HandleMsvSessionReadyL
       
   173 // ---------------------------------------------------------
       
   174 //
       
   175 void CNcnNotifApiObserver::HandleMsvSessionReadyL( CMsvSession& aMsvSession )
       
   176     {
       
   177     // Load all mailboxes
       
   178     LoadMailboxesL( aMsvSession );
       
   179     
       
   180     //We take a pointer to msv session. Needed only in special circumstances
       
   181     iMsvSession = &aMsvSession;
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------
       
   185 // CNcnNotifApiObserver::HandleMsvSessionClosedL
       
   186 // ---------------------------------------------------------
       
   187 //    
       
   188 void CNcnNotifApiObserver::HandleMsvSessionClosedL()
       
   189     {
       
   190     NCN_RDEBUG( _L("CNcnNotifApiObserver::HandleMsvSessionClosedL") );
       
   191     iMailBoxStatusArray.Close();
       
   192     
       
   193     // Reset email counters
       
   194     iTotalNewMailCount = 0;
       
   195     iNotifiedNewMailCount = 0;    
       
   196                                 
       
   197     // Inform notifier
       
   198     iModel.NcnNotifier().SetNotification(
       
   199         MNcnNotifier::ENcnEmailNotification,
       
   200         iTotalNewMailCount );
       
   201     }
       
   202 
       
   203 // ---------------------------------------------------------
       
   204 // CNcnNotifApiObserver::HandleMsvEntryCreatedL
       
   205 // ---------------------------------------------------------
       
   206 //
       
   207 void CNcnNotifApiObserver::HandleMsvEntryCreatedL( const TMsvId& aMsvId )
       
   208     {
       
   209     //Get the atrrbiutes
       
   210     TUid aMtmType = KNullUid;
       
   211     TUid aTechnologyType = KNullUid;
       
   212     TInt error = GetMailBoxesAttributesL(aMsvId, aMtmType, aTechnologyType);
       
   213     
       
   214     // if entry is an email service entry
       
   215     if( error == KErrNone && IsMailTechnologyType( aTechnologyType ) )
       
   216         {
       
   217         // add mail box
       
   218         NCN_RDEBUG_INT2( _L("CNcnNotifApiObserver::HandleMsvEntryCreatedL - Box %d created with MTM %d"), aMsvId, aMtmType.iUid );
       
   219         AddMailBoxL( aMsvId, aMtmType, aTechnologyType );
       
   220         }
       
   221     // otherwise inspect the entry more carefully
       
   222     else
       
   223         {                
       
   224         CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL();
       
   225     
       
   226         // get service id and entry
       
   227         TMsvId serviceId;
       
   228         TMsvEntry entry;        
       
   229         TInt err = msvSession.GetEntry( aMsvId, serviceId, entry );
       
   230         
       
   231         // if entry was found
       
   232         if( err == KErrNone )
       
   233             {
       
   234             // if entry is an email
       
   235             if( IsEMailEntry( entry ) && ( entry.New() && entry.Unread() ) )
       
   236                 {
       
   237                 // handle new email
       
   238                 HandleNewEMailMsvEntryL( entry );
       
   239                 }    
       
   240             }            
       
   241         }
       
   242     }
       
   243 
       
   244 // ---------------------------------------------------------
       
   245 // CNcnNotifApiObserver::HandleMsvEntryDeletedL
       
   246 // ---------------------------------------------------------
       
   247 //    
       
   248 void CNcnNotifApiObserver::HandleMsvEntryDeletedL( const TMsvId& aMsvId )
       
   249     {
       
   250     // just try to remove mail box
       
   251     // invalid ids are ignored by the method
       
   252     RemoveMailBox( aMsvId );
       
   253     
       
   254     // Also try to delete email entry
       
   255     HandleDeletedEMailMsvEntryL( aMsvId );
       
   256     }
       
   257     
       
   258 // ---------------------------------------------------------
       
   259 // CNcnNotifApiObserver::HandleNewEMailMsvEntryL
       
   260 // ---------------------------------------------------------
       
   261 //
       
   262 void CNcnNotifApiObserver::HandleNewEMailMsvEntryL( const TMsvEntry& aEntry )
       
   263     {
       
   264     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::HandleNewEMailMsvEntryL - entry = %d\n"), aEntry.Id() );    
       
   265     
       
   266     // find the mailbox
       
   267     TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aEntry.iServiceId );
       
   268     
       
   269     // find entry in mailbox new email list
       
   270     TInt index = mailboxStatus.iNewMessageIds.Find( aEntry.Id() );
       
   271   
       
   272     // if there is no such entry in list yet 
       
   273     if( index == KErrNotFound )
       
   274         {
       
   275         //Some messages do not require notifications when they arrive (they are old messages)
       
   276         //In this method those messages are spotted
       
   277         if ( IsNotificationNeededForThisMessageL( mailboxStatus, aEntry ) == FALSE )
       
   278 	        {
       
   279 	        NCN_RDEBUG_INT( _L( "[ncnlist] CNcnNotifApiObserver::HandleNewEMailMsvEntryL - entry %d does not require notification!" ), aEntry.Id() );
       
   280 			return;
       
   281 	        }
       
   282 	        
       
   283         //Notification is needed, add it to our list
       
   284         NCN_RDEBUG_INT( _L( "[ncnlist] CNcnNotifApiObserver::HandleNewEMailMsvEntryL - entry %d added to list\n" ), aEntry.Id() );
       
   285         
       
   286         // append entry id to the list of new messages in box
       
   287         mailboxStatus.iNewMessageIds.Append( aEntry.Id() );
       
   288         
       
   289         //Email icon should be shown to indicate new email for this mailbox
       
   290         mailboxStatus.iShowIcon = ETrue;
       
   291         
       
   292         NCN_RDEBUG_INT2(
       
   293             _L( "CNcnNotifApiObserver::HandleNewEMailMsvEntryL - new messages in box %d: %d" ),
       
   294             mailboxStatus.iMailBox,
       
   295             mailboxStatus.iNewMessageIds.Count() );
       
   296         
       
   297         // update highest msv entry if needed
       
   298         if( aEntry.Id() > mailboxStatus.iHighestEMailMsvId )
       
   299             {
       
   300             mailboxStatus.iHighestEMailMsvId = aEntry.Id();
       
   301             }
       
   302             
       
   303         // update highest IMAP uid if needed
       
   304         NCN_RDEBUG(_L( "CNcnNotifApiObserver::HandleNewEMailMsvEntryL - Making an TMsvEmailEntry from TEntry" ) );
       
   305         TMsvEmailEntry emailEntry(aEntry);
       
   306 		NCN_RDEBUG_INT(_L( "CNcnNotifApiObserver::HandleNewEMailMsvEntryL - Messages IMAP UID %d" ), emailEntry.UID() );
       
   307         if( emailEntry.UID() > mailboxStatus.iHighestIMAPId  )
       
   308             {
       
   309             NCN_RDEBUG_INT( _L( "CNcnNotifApiObserver::HandleNewEMailMsvEntryL - Message has highest IMAP UID so far %d" ), emailEntry.UID() );
       
   310             mailboxStatus.iHighestIMAPId = emailEntry.UID();            	
       
   311             }
       
   312             
       
   313         // update latest message time if needed
       
   314 #ifdef _DEBUG
       
   315 		TBuf<50> 	tempTime;
       
   316 		_LIT(KBMDebugTimeFormat, "%-B%:0%J%:1%T%:2%S%.%*C4%:3%+B");		
       
   317 
       
   318 		aEntry.iDate.FormatL(tempTime, KBMDebugTimeFormat);
       
   319 		NCN_RDEBUG_INT( _L("CNcnNotifApiObserver::HandleNewEMailMsvEntryL messages time stamp: %S"), &tempTime);
       
   320 #endif
       
   321         if( aEntry.iDate > mailboxStatus.iLatestMessageArrival )
       
   322             {
       
   323             NCN_RDEBUG( _L( "CNcnNotifApiObserver::HandleNewEMailMsvEntryL - Message has latest arrival time" ) );
       
   324             mailboxStatus.iLatestMessageArrival = aEntry.iDate;
       
   325             }
       
   326             
       
   327         }
       
   328     // entry exists in the list
       
   329     else
       
   330         {
       
   331         NCN_RDEBUG_INT( _L( "[ncnlist] CNcnNotifApiObserver::HandleNewEMailMsvEntryL - entry %d already in list\n" ), aEntry.Id() );
       
   332         }
       
   333     }
       
   334     
       
   335 // ---------------------------------------------------------
       
   336 // CNcnNotifApiObserver::HandleDeletedEMailMsvEntryL
       
   337 // ---------------------------------------------------------
       
   338 //
       
   339 void CNcnNotifApiObserver::HandleDeletedEMailMsvEntryL( const TMsvId& aEntryId )
       
   340     {
       
   341     NCN_RDEBUG( _L( "CNcnNotifApiObserver::HandleDeletedEMailMsvEntryL - deleted email entry" ) );
       
   342     
       
   343     TInt count( iMailBoxStatusArray.Count() );
       
   344 
       
   345     // Run all boxes through
       
   346     while( count > 0)
       
   347         {
       
   348         // decrease count
       
   349         count--;
       
   350         
       
   351         // get reference to mailbox
       
   352         TNcnMailBoxStatus& mailboxStatus = iMailBoxStatusArray[count];
       
   353         
       
   354         // try to find the id in boxes new message id list
       
   355         TInt index = mailboxStatus.iNewMessageIds.Find( aEntryId );
       
   356         
       
   357         // if entry was found
       
   358         if( index != KErrNotFound )
       
   359             {
       
   360             // remove entry id
       
   361             mailboxStatus.iNewMessageIds.Remove( index );
       
   362             
       
   363             NCN_RDEBUG_INT2(
       
   364                 _L( "CNcnNotifApiObserver::HandleDeletedEMailMsvEntryL - new messages in box %d: %d" ),
       
   365                 mailboxStatus.iMailBox,
       
   366                 mailboxStatus.iNewMessageIds.Count() );
       
   367             
       
   368             // and if id is less than equal to last published it
       
   369             // affects the amount of published new emails
       
   370             if( aEntryId <= mailboxStatus.iPublishedCheckpointMsvId )
       
   371                 {
       
   372                 // decrease amount of published new emails
       
   373                 mailboxStatus.iPublishedNewEmailCount--;
       
   374                 
       
   375                 NCN_RDEBUG_INT2(
       
   376                     _L( "CNcnNotifApiObserver::HandleDeletedEMailMsvEntryL - published new messages in box %d: %d" ),
       
   377                     mailboxStatus.iMailBox,
       
   378                     mailboxStatus.iPublishedNewEmailCount );
       
   379                 
       
   380                 // update notification, it might not be valid anymore if
       
   381                 // published emails have been deleted
       
   382                 UpdateNotification( EFalse, mailboxStatus.iIcon, mailboxStatus.iTone, mailboxStatus.iNote );
       
   383                 }
       
   384 
       
   385            // and finally we must update the boxes highest values, they might have changed			
       
   386 			NCN_RDEBUG( _L( "CNcnNotifApiObserver::HandleDeletedEMailMsvEntryL - Updating new 'highest' values" ));                     
       
   387             FindHighest_MsvId_ImapId_LatestTime(mailboxStatus.iMailBox,
       
   388             									mailboxStatus.iHighestEMailMsvId ,
       
   389             									mailboxStatus.iHighestIMAPId,
       
   390             									mailboxStatus.iLatestMessageArrival);       
       
   391             }
       
   392         } 
       
   393     }
       
   394     
       
   395 // ---------------------------------------------------------
       
   396 // CNcnNotifApiObserver::HandleMsvMediaChangedL
       
   397 // ---------------------------------------------------------
       
   398 //    
       
   399 #ifdef _DEBUG
       
   400 void CNcnNotifApiObserver::HandleMsvMediaChangedL( const TDriveNumber& aDriveNumber )
       
   401 #else
       
   402 void CNcnNotifApiObserver::HandleMsvMediaChangedL( const TDriveNumber& /*aDriveNumber */)
       
   403 #endif
       
   404 	{
       
   405     //The entrys that we have in the iMailBoxStatusArray are no longer valid
       
   406     //the array must be rebuild.   
       
   407     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::HandleMsvMediaChangedL - Media changed to drive: %d"), aDriveNumber );
       
   408     
       
   409     //Reset the mail box array
       
   410     iMailBoxStatusArray.Reset();
       
   411     
       
   412     // Reset email counters
       
   413     iTotalNewMailCount = 0;
       
   414     iNotifiedNewMailCount = 0;    
       
   415                                 
       
   416     // Inform notifier
       
   417     iModel.NcnNotifier().SetNotification( MNcnNotifier::ENcnEmailNotification, iTotalNewMailCount );
       
   418         
       
   419     //Load the mail boxes. Old MsvSession is still valid after media changes
       
   420     if( iMsvSession != NULL )
       
   421 	    {
       
   422 	    LoadMailboxesL( *iMsvSession );	
       
   423 	    }
       
   424 	}
       
   425 
       
   426 // ---------------------------------------------------------
       
   427 // CNcnNotifApiObserver::HandleMsvMediaAvailableL
       
   428 // ---------------------------------------------------------
       
   429 //    
       
   430 #ifdef _DEBUG
       
   431 void CNcnNotifApiObserver::HandleMsvMediaAvailableL( const TDriveNumber& aDriveNumber )
       
   432 #else
       
   433 void CNcnNotifApiObserver::HandleMsvMediaAvailableL( const TDriveNumber& /*aDriveNumber*/ )
       
   434 #endif
       
   435 	{
       
   436 	//Clean up message store from unhealthy mail boxes
       
   437     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::HandleMsvMediaAvailableL - Media available in drive: %d"), aDriveNumber );
       
   438 
       
   439     // Create interface object
       
   440     CIMAEmailApi* api = CreateEmailApiLC( iMsvSession );
       
   441     
       
   442     // Force message store cleanup
       
   443     NCN_RDEBUG( _L("[ncnlist] CNcnNotifApiObserver::HandleMsvMediaAvailableL - Cleanup unhealthy mailboxes") );
       
   444     api->HealthServicesL().CleanupUnhealthyMailboxes();
       
   445     CleanupStack::PopAndDestroy( api );
       
   446     api = NULL;
       
   447 
       
   448 	}
       
   449 
       
   450 // ---------------------------------------------------------
       
   451 // CNcnNotifApiObserver::HandleMsvMediaAvailableL
       
   452 // Media Unavailable Check if current drive is Not C 
       
   453 // then set it back to Phone memory.
       
   454 // ---------------------------------------------------------
       
   455 //    
       
   456 
       
   457 void CNcnNotifApiObserver::HandleMsvMediaUnavailableL( )
       
   458 	{
       
   459 		
       
   460 		NCN_RDEBUG( _L("[ncnlist] CNcnNotifApiObserver::HandleMsvMediaUnavailable - Media Unavailable") );
       
   461 
       
   462 		// get session
       
   463 		CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL(); 
       
   464 		NCN_RDEBUG( _L( "CNcnMsvSessionHandler::HandleSessionEventL - EMsvMediaUnavailable, Check Current message store drive." ));
       
   465 		TInt CurrentDrive = TInt(msvSession.CurrentDriveL());
       
   466 		RFs fs;	
       
   467 		User::LeaveIfError(fs.Connect());
       
   468 		CleanupClosePushL(fs);
       
   469 		TDriveNumber SystemDrive = fs.GetSystemDrive();	
       
   470 		CleanupStack::PopAndDestroy();//fs
       
   471 		if(CurrentDrive != SystemDrive)
       
   472 		   MsvUiServiceUtilitiesInternal::ChangeMessageStoreToPhoneL(*iMsvSession);
       
   473 	}
       
   474 
       
   475 // ---------------------------------------------------------
       
   476 // CNcnNotifApiObserver::MarkUnread
       
   477 // ---------------------------------------------------------
       
   478 //
       
   479 void CNcnNotifApiObserver::MarkUnreadL( const TMsvId& aId )
       
   480     {
       
   481     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::MarkUnreadL - box %d marked unread."), aId );
       
   482     
       
   483     // find the mailbox
       
   484     TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aId );
       
   485         
       
   486     // reset amounts    
       
   487     mailboxStatus.iPublishedNewEmailCount = 0;
       
   488     
       
   489     // clear new message ids
       
   490     mailboxStatus.iNewMessageIds.Reset();
       
   491     mailboxStatus.iNewMessageIds.Compress();
       
   492     
       
   493     // move unread checkpoint to the highest id
       
   494     mailboxStatus.iUnreadCheckpointMsvId = mailboxStatus.iHighestEMailMsvId;
       
   495     }
       
   496 
       
   497 // ---------------------------------------------------------
       
   498 // CNcnNotifApiObserver::PublishNewMessages
       
   499 // ---------------------------------------------------------
       
   500 //    
       
   501 void CNcnNotifApiObserver::PublishNewMessagesL( const TMsvId& aId )
       
   502     {
       
   503     // find the mailbox
       
   504     TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aId );
       
   505     // clear notification flag
       
   506     mailboxStatus.iNotified = EFalse;
       
   507     mailboxStatus.iRefreshRequested = ETrue;
       
   508         
       
   509     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::PublishNewMessagesL Initializing counter for box %d."),
       
   510         mailboxStatus.iMailBox );
       
   511     
       
   512     // if timer is not already spawned
       
   513     if( !iTimer )
       
   514         {
       
   515         iTimer = CNcnTimer::NewL( *this );
       
   516         iTimer->After( KTimerIterationDelay );
       
   517         }
       
   518     else
       
   519     	{
       
   520     	iTimer->Cancel();
       
   521     	iTimer->After( KTimerIterationDelay );
       
   522     	}
       
   523     }
       
   524 
       
   525 // ---------------------------------------------------------
       
   526 // CNcnNotifApiObserver::SpawnTimer
       
   527 // ---------------------------------------------------------
       
   528 //    
       
   529 void CNcnNotifApiObserver::NcnTimerCompleted()
       
   530     {
       
   531     TInt count( iMailBoxStatusArray.Count() );
       
   532     
       
   533     NCN_RDEBUG( _L("[ncnlist] CNcnNotifApiObserver::NcnTimerCompleted called." ) );
       
   534     
       
   535     // Run all boxes through
       
   536     while( count-- )
       
   537         {        
       
   538         // get mailbox status
       
   539         TNcnMailBoxStatus& mailboxStatus = iMailBoxStatusArray[count];
       
   540         
       
   541         if ( mailboxStatus.iRefreshRequested )
       
   542         	{
       
   543         	NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::NcnTimerCompleted Refresh requested for box %d "),
       
   544         	            mailboxStatus.iMailBox );
       
   545         	        
       
   546         	// if published count differs from number of new emails
       
   547 	        if( mailboxStatus.iPublishedNewEmailCount != mailboxStatus.iNewMessageIds.Count() )
       
   548 	            {
       
   549 	            // all new messages are now published
       
   550 	            mailboxStatus.iPublishedNewEmailCount = mailboxStatus.iNewMessageIds.Count();                                            
       
   551 	            
       
   552 	            NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::NcnTimerCompleted published updated to %d."),
       
   553 	                mailboxStatus.iPublishedNewEmailCount );
       
   554 	        
       
   555 	            // move published checkpoints to new values
       
   556 	           	mailboxStatus.iPublishedCheckpointMsvId = mailboxStatus.iHighestEMailMsvId;
       
   557 	            mailboxStatus.iPublishedCheckpointIMAPId = mailboxStatus.iHighestIMAPId;
       
   558 				mailboxStatus.iPublishedCheckpointTimeStamp = mailboxStatus.iLatestMessageArrival;
       
   559 				NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::NcnTimerCompleted highest published iHighestEMailMsvId %d"),mailboxStatus.iHighestEMailMsvId);
       
   560 				NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::NcnTimerCompleted highest published iHighestIMAPId %d"),mailboxStatus.iHighestIMAPId);
       
   561 				NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::NcnTimerCompleted highest published iLatestMessageArrival(Int66) %d"),mailboxStatus.iLatestMessageArrival.Int64() );
       
   562 								                                
       
   563 	            // if box has not yet been notified of
       
   564 	            if( !mailboxStatus.iNotified )
       
   565 	                {
       
   566 	                NCN_RDEBUG_INT2( _L( "CNcnNotifApiObserver::NcnTimerCompleted - mailbox %d contains %d published unnotified emails." ),
       
   567 	                    mailboxStatus.iMailBox,
       
   568 	                    mailboxStatus.iPublishedNewEmailCount );
       
   569 	                    
       
   570 	                // we need to notify
       
   571 			        NCN_RDEBUG( _L( "CNcnNotifApiObserver::NcnTimerCompleted - notifying about new emails." ) );                
       
   572 			        UpdateNotification( EFalse, mailboxStatus.iIcon, mailboxStatus.iTone, mailboxStatus.iNote );
       
   573 	                
       
   574 	                // mailbox has been notified now
       
   575 	                mailboxStatus.iNotified = ETrue;
       
   576 	                }                
       
   577 	            }
       
   578 	        mailboxStatus.iRefreshRequested = EFalse;
       
   579         	}
       
   580         }
       
   581     // release timer
       
   582     delete iTimer;
       
   583     iTimer = NULL;
       
   584     }
       
   585 
       
   586 // ---------------------------------------------------------
       
   587 // CNcnNotifApiObserver::PublishAllNewMessages
       
   588 // ---------------------------------------------------------
       
   589 //      
       
   590 void CNcnNotifApiObserver::PublishAllNewMessages( )
       
   591     {
       
   592     TInt count( iMailBoxStatusArray.Count() );
       
   593 
       
   594     // Run all boxes through
       
   595     while( count > 0)
       
   596         {
       
   597         // decrease count
       
   598         count--;
       
   599         
       
   600 	    //S60 boxs need to have notification parameters fetched
       
   601 	   	TNcnMailBoxStatus& mailboxStatus = iMailBoxStatusArray[count];
       
   602 	   	
       
   603 	   	//ignore the error, ncnlist will use existing notification parameters
       
   604 	   	TRAP_IGNORE( UpdateS60MailBoxNotificationAttributesL(mailboxStatus) );
       
   605            	
       
   606         // publish message count in box
       
   607         TRAP_IGNORE( PublishNewMessagesL( mailboxStatus.iMailBox ) );
       
   608         }      
       
   609     }
       
   610 
       
   611 // ---------------------------------------------------------
       
   612 // CNcnNotifApiObserver::MarkAllUnread
       
   613 // ---------------------------------------------------------
       
   614 //       
       
   615 void CNcnNotifApiObserver::MarkAllUnread( )
       
   616     {
       
   617     TInt count( iMailBoxStatusArray.Count() );
       
   618 
       
   619     // Run all boxes through
       
   620     while( count > 0)
       
   621         {
       
   622         // decrease count
       
   623         count--;
       
   624         
       
   625         // mark box unread
       
   626         TRAP_IGNORE( MarkUnreadL( iMailBoxStatusArray[count].iMailBox ) );
       
   627         }  
       
   628     }
       
   629 
       
   630 // ---------------------------------------------------------
       
   631 // CNcnNotifApiObserver::FindHighest_MsvId_ImapId_LatestTime
       
   632 // ---------------------------------------------------------
       
   633 //    
       
   634 void CNcnNotifApiObserver::FindHighest_MsvId_ImapId_LatestTime(
       
   635 		const TMsvId& aId,
       
   636 		TMsvId& aHighestMsvId,
       
   637 		TUint32& aHighestImapId,
       
   638 		TTime& aLatestTimeStamp )
       
   639     {
       
   640    // Return parameters default to 0
       
   641     aHighestMsvId = 0;
       
   642 	aHighestImapId = 0;
       
   643     aLatestTimeStamp = 0; 
       
   644     
       
   645     // get highest values and trap leave
       
   646     TRAP_IGNORE( FindHighest_MsvId_ImapId_LatestTimeL(	aId,
       
   647     													aHighestMsvId,
       
   648     													aHighestImapId,
       
   649 														aLatestTimeStamp ) );
       
   650 														
       
   651 	NCN_RDEBUG( _L("[ncnlist] CNcnNotifApiObserver::FindHighest_MsvId_ImapId_LatestTime") );
       
   652 	NCN_RDEBUG_INT( _L("[ncnlist] Highest MsvId is: %d"), aHighestMsvId );
       
   653 	NCN_RDEBUG_INT( _L("[ncnlist] Highest ImapId is: %d"), aHighestImapId );
       
   654 	NCN_RDEBUG_INT( _L("[ncnlist] Latest time stamp(int64) is: %d"), aLatestTimeStamp.Int64()  );
       
   655     }
       
   656     
       
   657 // ---------------------------------------------------------
       
   658 // CNcnNotifApiObserver::FindHighest_MsvId_ImapId_LatestTimeL
       
   659 // ---------------------------------------------------------
       
   660 //    
       
   661 void CNcnNotifApiObserver::FindHighest_MsvId_ImapId_LatestTimeL( 
       
   662 		const TMsvId& aId,
       
   663 		TMsvId& aHighestMsvId,
       
   664 		TUint32& aHighestImapId,
       
   665 		TTime& aLatestTimeStamp )
       
   666 		
       
   667     {
       
   668     // get msv session handler from model
       
   669     CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL();
       
   670     
       
   671     // get entry pointer
       
   672     CMsvEntry* mainEntryPtr = msvSession.GetEntryL( aId );
       
   673     CleanupStack::PushL( mainEntryPtr );
       
   674         
       
   675     // Count the items in selected entry
       
   676     TInt items = mainEntryPtr->Count();
       
   677 
       
   678     // Search through all items in folder
       
   679     while( items > 0)
       
   680         {
       
   681         // decrement items
       
   682         items--;
       
   683         
       
   684         // Create entry from the item
       
   685         const TMsvEntry& entry = (*mainEntryPtr)[items];       
       
   686         
       
   687         // entry in this iteration
       
   688         TMsvId msvId = 0;
       
   689     	TUint32 imapId = 0;
       
   690     	TTime latestTime = 0;
       
   691     	
       
   692         // determine entry type    
       
   693         switch( entry.iType.iUid )
       
   694             {
       
   695             // folder
       
   696             case KUidMsvFolderEntryValue:
       
   697                 {
       
   698                 // find highest entry recursively
       
   699                 TRAP_IGNORE( FindHighest_MsvId_ImapId_LatestTimeL(	entry.Id(),
       
   700                 													aHighestMsvId,
       
   701                 													aHighestImapId,
       
   702                 													aLatestTimeStamp ) );
       
   703                 
       
   704                 break;
       
   705                 }
       
   706             // message
       
   707             case KUidMsvMessageEntryValue:
       
   708                 { 
       
   709                 //Get entry's MsvId
       
   710                 msvId = entry.Id();
       
   711                 
       
   712                 //Get entry's imapId        
       
   713                 TMsvEmailEntry emailEntry(entry);                
       
   714 	            imapId = emailEntry.UID();
       
   715 	            
       
   716 	            //Get entry's time
       
   717 	            latestTime = entry.iDate;
       
   718                 
       
   719 		        // Compare this entry's values and set them as highest if they are so.  
       
   720 		        if(  msvId > aHighestMsvId )
       
   721 		            {
       
   722 		            aHighestMsvId = msvId;
       
   723 		            }
       
   724 		        if(  imapId > aHighestImapId )
       
   725 		            {
       
   726 		            aHighestImapId = imapId;
       
   727 		            }
       
   728 		        if(  latestTime > aLatestTimeStamp )
       
   729 		            {
       
   730 		            aLatestTimeStamp = latestTime;
       
   731 		            }
       
   732 		        break;                  
       
   733                 }
       
   734             // default
       
   735             default:
       
   736                 {
       
   737                 // do nothing
       
   738                 break;
       
   739                 }                
       
   740             }
       
   741         }
       
   742         
       
   743     CleanupStack::PopAndDestroy( mainEntryPtr );
       
   744     }
       
   745 
       
   746 // ---------------------------------------------------------
       
   747 // CNcnNotifApiObserver::HandleNewInternalMessagesL
       
   748 // ---------------------------------------------------------
       
   749 //
       
   750 void CNcnNotifApiObserver::HandleNewInternalMessagesL(
       
   751     const TNcnNotifMessageType aType )
       
   752     {    
       
   753     
       
   754     // determine message type
       
   755     switch( aType )
       
   756         {
       
   757         // email message
       
   758         case EMailMessage:
       
   759             {
       
   760             PublishAllNewMessages();
       
   761             break;
       
   762             }
       
   763         // inbox message
       
   764         case EInboxMessage:
       
   765             {
       
   766             // Not supported
       
   767             User::Leave( KErrNotSupported );
       
   768             break;
       
   769             }
       
   770         // IM message
       
   771         case EIMMessage:
       
   772             {
       
   773             // Not supported
       
   774             User::Leave( KErrNotSupported );
       
   775             break;
       
   776             }
       
   777         // default case (unknown)    
       
   778         default:
       
   779             {
       
   780             User::Leave( KErrNotSupported );
       
   781             break;
       
   782             }
       
   783         }
       
   784     }
       
   785   
       
   786 // ---------------------------------------------------------
       
   787 // CNcnNotifApiObserver::HandleNewInternalMessagesL
       
   788 // ---------------------------------------------------------
       
   789 //    
       
   790 void CNcnNotifApiObserver::HandleNewInternalMessagesL(
       
   791     const TNcnNotifMessageType aType,
       
   792     const TMsvId& aMailBox,
       
   793     const MDesCArray& /*aInfo*/ )
       
   794     {
       
   795         
       
   796     // determine message type
       
   797     switch( aType )
       
   798         {
       
   799         // email message
       
   800         case EMailMessage:
       
   801             {
       
   802             NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::HandleNewInternalMessagesL Publishing box %d."),
       
   803                 aMailBox );
       
   804             
       
   805            	// mailboxes need to have notification parameters fetched
       
   806            	TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aMailBox );
       
   807            	
       
   808            	//ignore the error, ncnlist will use existing notification parameters
       
   809            	TRAP_IGNORE( UpdateS60MailBoxNotificationAttributesL(mailboxStatus) );
       
   810 
       
   811             PublishNewMessagesL( aMailBox );
       
   812             break;
       
   813             }
       
   814         // inbox message
       
   815         case EInboxMessage:
       
   816             {
       
   817             // Not supported
       
   818             User::Leave( KErrNotSupported );
       
   819             break;
       
   820             }
       
   821         // IM message
       
   822         case EIMMessage:
       
   823             {
       
   824             // Not supported
       
   825             User::Leave( KErrNotSupported );
       
   826             break;
       
   827             }
       
   828         // default case (unknown)    
       
   829         default:
       
   830             {
       
   831             User::Leave( KErrNotSupported );
       
   832             break;
       
   833             }
       
   834         }
       
   835     }
       
   836 
       
   837 // ---------------------------------------------------------
       
   838 // CNcnNotifApiObserver::HandleInternalMarkUnreadL
       
   839 // ---------------------------------------------------------
       
   840 //    
       
   841 void CNcnNotifApiObserver::HandleInternalMarkUnreadL(
       
   842     const TNcnUnreadRequestType aRequest )
       
   843     {
       
   844     
       
   845     // determine request type
       
   846     switch( aRequest )
       
   847         {
       
   848             // email request
       
   849             case EIndexMailBox:
       
   850                 {
       
   851                 MarkAllUnread();
       
   852                 UpdateNotification( ETrue ); //Force update
       
   853                 break;
       
   854                 }
       
   855             // inbox request
       
   856             case EIndexInbox:
       
   857                 {
       
   858                 // Not supported
       
   859                 User::Leave( KErrNotSupported );
       
   860                 break;
       
   861                 }
       
   862             // MCE request
       
   863             case EIndexMCE:
       
   864                 {
       
   865                 // Not supported
       
   866                 User::Leave( KErrNotSupported );
       
   867                 break;
       
   868                 }
       
   869             // default case (unknown)
       
   870             default:
       
   871                 {
       
   872                 // Not supported
       
   873                 User::Leave( KErrNotSupported );
       
   874                 break;
       
   875                 }
       
   876                 
       
   877         }
       
   878     }
       
   879 
       
   880 // ---------------------------------------------------------
       
   881 // CNcnNotifApiObserver::HandleInternalMarkUnreadL
       
   882 // ---------------------------------------------------------
       
   883 //    
       
   884 void CNcnNotifApiObserver::HandleInternalMarkUnreadL(
       
   885     const TNcnUnreadRequestType aRequest,
       
   886     const TMsvId& aMailbox )
       
   887     {
       
   888     // determine request type
       
   889     switch( aRequest )
       
   890         {
       
   891             // email request
       
   892             case EIndexMailBox:
       
   893                 {
       
   894             // find the mailbox
       
   895             TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aMailbox );
       
   896 
       
   897             // MailBox is Opened so don't show Icon, even if user has not read any new/unread mails 
       
   898             // Publish new email count will be zero.
       
   899             mailboxStatus.iShowIcon = EFalse;
       
   900             mailboxStatus.iPublishedNewEmailCount = 0;
       
   901                 MarkUnreadL( aMailbox );
       
   902             UpdateNotification( ETrue );
       
   903             mailboxStatus.iShowIcon = ETrue;
       
   904 				break;
       
   905                 }
       
   906             // inbox request
       
   907             case EIndexInbox:
       
   908                 {
       
   909                 // Not supported
       
   910                 User::Leave( KErrNotSupported );
       
   911                 break;
       
   912                 }
       
   913             // MCE request
       
   914             case EIndexMCE:
       
   915                 {
       
   916                 // Not supported
       
   917                 User::Leave( KErrNotSupported );
       
   918                 break;
       
   919                 }
       
   920             // default case (unknown)
       
   921             default:
       
   922                 {
       
   923                 // Not supported
       
   924                 User::Leave( KErrNotSupported );
       
   925                 break;
       
   926                 }                
       
   927         }                   
       
   928     }
       
   929 
       
   930 // ---------------------------------------------------------
       
   931 // CNcnNotifApiObserver::HandleNewMessagesL
       
   932 // ---------------------------------------------------------
       
   933 //    
       
   934 void CNcnNotifApiObserver::HandleNewMessagesL(
       
   935     const TMsvId& aMailBox,
       
   936     const MNcnNotification::TIndicationType aIndicationType,
       
   937     const MDesCArray& /*aInfo*/ )
       
   938     {  
       
   939     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver::HandleNewMessagesL Publishing box %d."),
       
   940         aMailBox );
       
   941     
       
   942     //Get the box and set the notification parameters accordingly
       
   943     //This will leave if the system does not contain the wanted box
       
   944     TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aMailBox );
       
   945 	UpdateMailBoxesNotifications(mailboxStatus, aIndicationType );	  
       
   946 
       
   947     PublishNewMessagesL( aMailBox );    
       
   948     }
       
   949     
       
   950 // ---------------------------------------------------------
       
   951 // CNcnNotifApiObserver::HandleMarkUnreadL
       
   952 // ---------------------------------------------------------
       
   953 //  
       
   954 void CNcnNotifApiObserver::HandleMarkUnreadL( const TMsvId& aMailBox )
       
   955     {
       
   956     // find the mailbox
       
   957     TNcnMailBoxStatus& mailboxStatus = MailBoxStatusL( aMailBox );
       
   958     
       
   959     // MailBox is Opened so don't show Icon, even if user has not read any new/unread mails 
       
   960     // Publish new email count will be zero.
       
   961     mailboxStatus.iShowIcon = EFalse;
       
   962     mailboxStatus.iPublishedNewEmailCount = 0;
       
   963 
       
   964     MarkUnreadL( aMailBox );
       
   965     
       
   966     UpdateNotification( ETrue );
       
   967     mailboxStatus.iShowIcon = ETrue;
       
   968     
       
   969     }
       
   970 
       
   971 // ---------------------------------------------------------
       
   972 // CNcnNotifApiObserver::LoadMailboxesL
       
   973 // ---------------------------------------------------------
       
   974 //
       
   975 void CNcnNotifApiObserver::LoadMailboxesL( CMsvSession& aMsvSession )
       
   976     {
       
   977     // load client mtm registry
       
   978     CClientMtmRegistry* registry = CClientMtmRegistry::NewL( aMsvSession );
       
   979     CleanupStack::PushL( registry );
       
   980     
       
   981     // get number of registered MTMs
       
   982     TInt count = registry->NumRegisteredMtmDlls();
       
   983     
       
   984     // process each MTM
       
   985     while( count-- )
       
   986         {
       
   987         // get MTM type
       
   988         TUid mtmType = registry->MtmTypeUid( count );
       
   989         
       
   990         // get MTM technology type
       
   991         TUid technologyType = registry->TechnologyTypeUid( mtmType );
       
   992         
       
   993         // and if it is mail type
       
   994         if( IsMailTechnologyType( technologyType ) )
       
   995             {
       
   996             NCN_RDEBUG_INT( _L("CNcnNotifApiObserver::LoadMailboxesL - Loading all boxes with MTM %d"),
       
   997                 mtmType.iUid );
       
   998             
       
   999             // Add all boxes with specified MTM to array
       
  1000             AddBoxesToStatusArrayL( mtmType, technologyType, aMsvSession );                        
       
  1001             }
       
  1002         }
       
  1003     
       
  1004     // cleanup
       
  1005     CleanupStack::PopAndDestroy( registry );
       
  1006     }
       
  1007     
       
  1008 // ---------------------------------------------------------
       
  1009 // CNcnNotifApiObserver::AddBoxesToStatusArrayL
       
  1010 // ---------------------------------------------------------
       
  1011 //
       
  1012 void CNcnNotifApiObserver::AddBoxesToStatusArrayL(
       
  1013     const TUid& aMtmType,
       
  1014     const TUid& aTechnologyType,
       
  1015     CMsvSession& aMsvSession )
       
  1016     {
       
  1017     // Get the list of available email accounts
       
  1018     CMsvEntrySelection* sel =
       
  1019         MsvUiServiceUtilities::GetListOfAccountsWithMTML( aMsvSession,
       
  1020                                                           aMtmType );
       
  1021     CleanupStack::PushL( sel );
       
  1022 
       
  1023     // Count accounts
       
  1024     TInt accounts = sel->Count();
       
  1025 
       
  1026     // Go through all accounts
       
  1027     while( accounts-- )    
       
  1028         {
       
  1029         TMsvId msvId = sel->At( accounts );
       
  1030         
       
  1031         NCN_RDEBUG_INT2( _L("CNcnNotifApiObserver::AddBoxesToStatusArrayL - Loading box %d with MTM %d"),
       
  1032                 msvId, aMtmType.iUid );
       
  1033                     
       
  1034         AddMailBoxL( msvId, aMtmType, aTechnologyType );
       
  1035         }    
       
  1036     
       
  1037     CleanupStack::PopAndDestroy( sel );  // sel
       
  1038     }
       
  1039     
       
  1040 // ---------------------------------------------------------
       
  1041 // CNcnNotifApiObserver::AddMailBoxL
       
  1042 // ---------------------------------------------------------
       
  1043 //    
       
  1044 void CNcnNotifApiObserver::AddMailBoxL( const TMsvId& aMsvId, 
       
  1045 										const TUid& aMtmType, 
       
  1046 										const TUid& aTechnologyType)
       
  1047     {
       
  1048     TNcnMailBoxStatus mailbox( aMsvId );
       
  1049     
       
  1050     // if mail box is not already in status array
       
  1051     if ( iMailBoxStatusArray.Find( mailbox, 
       
  1052             TNcnMailBoxStatus::Match ) == KErrNotFound )
       
  1053         {                        
       
  1054         // set mailbox fields        
       
  1055         mailbox.iMTMType = aMtmType;
       
  1056         mailbox.iMailBoxTechnologyType = aTechnologyType;      
       
  1057         
       
  1058         // set the mailboxes 'highest' values
       
  1059         FindHighest_MsvId_ImapId_LatestTime(mailbox.iMailBox,
       
  1060         									mailbox.iHighestEMailMsvId ,
       
  1061         									mailbox.iHighestIMAPId,
       
  1062         									mailbox.iLatestMessageArrival);
       
  1063 		
       
  1064 		// set the rest of the values
       
  1065         mailbox.iUnreadCheckpointMsvId = mailbox.iHighestEMailMsvId;
       
  1066         mailbox.iPublishedCheckpointMsvId = mailbox.iHighestEMailMsvId;
       
  1067         mailbox.iPublishedCheckpointIMAPId = mailbox.iHighestIMAPId;
       
  1068         mailbox.iPublishedCheckpointTimeStamp = mailbox.iLatestMessageArrival;
       
  1069         mailbox.iPublishedNewEmailCount = 0;
       
  1070         mailbox.iShowIcon = ETrue;
       
  1071 		//In case the mailbox is IMAP/POP/SyncMl update the notifcation
       
  1072 		//parameters. 3rd party box's will give these in API
       
  1073 	    if(	mailbox.iMTMType.iUid == KSenduiMtmImap4UidValue ||
       
  1074 	    	mailbox.iMTMType.iUid == KSenduiMtmPop3UidValue	||  
       
  1075 	    	mailbox.iMTMType.iUid == KSenduiMtmSyncMLEmailUidValue )
       
  1076 			{
       
  1077 			//This should work, but just in case it does not
       
  1078 			//use default parameters
       
  1079 			TRAP_IGNORE(UpdateS60MailBoxNotificationAttributesL(mailbox));
       
  1080 			}
       
  1081 		
       
  1082         // and finally append mailbox status
       
  1083         iMailBoxStatusArray.AppendL( mailbox );
       
  1084         }
       
  1085     }
       
  1086 
       
  1087 // ---------------------------------------------------------
       
  1088 // CNcnNotifApiObserver::RemoveMailBoxL
       
  1089 // ---------------------------------------------------------
       
  1090 //
       
  1091 void CNcnNotifApiObserver::RemoveMailBox( const TMsvId& aMsvId )
       
  1092     {    
       
  1093     TNcnMailBoxStatus mailbox( aMsvId );
       
  1094     
       
  1095     TInt index = iMailBoxStatusArray.Find( mailbox, TNcnMailBoxStatus::Match );
       
  1096     
       
  1097     // if mail box is in status array
       
  1098     if( index != KErrNotFound )
       
  1099         {
       
  1100         // update notification
       
  1101 	    TNcnMailBoxStatus& mailboxStatus = iMailBoxStatusArray[index];
       
  1102 	    mailboxStatus.iPublishedNewEmailCount = 0;
       
  1103 	    UpdateNotification( EFalse, mailboxStatus.iIcon, mailboxStatus.iTone, mailboxStatus.iNote );
       
  1104 	    
       
  1105         // remove entry and compress array
       
  1106         iMailBoxStatusArray.Remove( index );
       
  1107         iMailBoxStatusArray.Compress();
       
  1108         }             
       
  1109     }
       
  1110 
       
  1111 // ---------------------------------------------------------
       
  1112 // CNcnNotifApiObserver::UpdateTotalNewEmails
       
  1113 // ---------------------------------------------------------
       
  1114 //
       
  1115 void CNcnNotifApiObserver::UpdateTotalNewEmails()
       
  1116     {
       
  1117     TInt count( iMailBoxStatusArray.Count() );
       
  1118     iTotalNewMailCount = 0;
       
  1119 
       
  1120     // Run all boxes through
       
  1121     while( count > 0)
       
  1122         {
       
  1123         // decrease count
       
  1124         count--;
       
  1125         
       
  1126         // get mailbox status
       
  1127         const TNcnMailBoxStatus& mailboxStatus = iMailBoxStatusArray[count];       
       
  1128         NCN_RDEBUG_INT2( _L( "CNcnNotifApiObserver::UpdateTotalNewEmailsL - Mail box %d has %d published new mails!"), mailboxStatus.iMailBox, mailboxStatus.iPublishedNewEmailCount);
       
  1129        
       
  1130         // count mailboxes published new emails
       
  1131         // The published "new" emails are those that have already been notified
       
  1132         // but which have not yet been viewed by the user. They are marked
       
  1133         // as "unread" when the user goes to the MCE or to the mailbox. 
       
  1134         // This might have not yet happened. When this happens the mailbox should
       
  1135         // call MarkUnread and the iPublishedNewEmailCount will get nulled
       
  1136         
       
  1137         // If user has opened the mailbox, IshowIcon for that mail box will be  set false
       
  1138         //User may have read all mails or may not
       
  1139         // but for that mail box, mail icon should not be set/shown.
       
  1140         if(mailboxStatus.iShowIcon)
       
  1141             iTotalNewMailCount += mailboxStatus.iPublishedNewEmailCount;
       
  1142         }
       
  1143         
       
  1144     NCN_RDEBUG_INT( _L( "CNcnNotifApiObserver::UpdateTotalNewEmailsL - new total %d "),
       
  1145         iTotalNewMailCount );
       
  1146     }
       
  1147 
       
  1148 // ---------------------------------------------------------
       
  1149 // CNcnNotifApiObserver::MailBoxStatusL
       
  1150 // ---------------------------------------------------------
       
  1151 //
       
  1152 CNcnNotifApiObserver::TNcnMailBoxStatus& CNcnNotifApiObserver::MailBoxStatusL( const TMsvId& aId )
       
  1153     {
       
  1154     // comparator
       
  1155     TNcnMailBoxStatus toBeFound( aId );
       
  1156     
       
  1157     // Leaves with KErrNotFound if aId is not a mailbox id in status array!
       
  1158     TInt index = iMailBoxStatusArray.FindL( toBeFound, 
       
  1159                                             TNcnMailBoxStatus::Match );
       
  1160     
       
  1161     // return mailbox
       
  1162     return iMailBoxStatusArray[index];
       
  1163     }
       
  1164 
       
  1165 // ---------------------------------------------------------
       
  1166 // CNcnNotifApiObserver::NewEmailIndicatorsSetL
       
  1167 // ---------------------------------------------------------
       
  1168 //
       
  1169 TBool CNcnNotifApiObserver::NewEmailIndicatorsSetL( const TNcnMailBoxStatus& aMailboxStatus )
       
  1170     {
       
  1171     NCN_RDEBUG( _L( "CNcnNotifApiObserver::NewEmailIndicatorsSetL") );  
       
  1172 	NCN_RDEBUG_INT( _L( "Checking indicator from CIMASettingsDataExtension for MTM box %d"), aMailboxStatus.iMTMType.iUid  );
       
  1173     
       
  1174     // Method is only valid for Imap, Pop3 and SyncMl boxes
       
  1175     if(	aMailboxStatus.iMTMType.iUid != KSenduiMtmImap4UidValue &&
       
  1176     	aMailboxStatus.iMTMType.iUid != KSenduiMtmPop3UidValue	&&   
       
  1177     	aMailboxStatus.iMTMType.iUid != KSenduiMtmSyncMLEmailUidValue )
       
  1178         {
       
  1179         NCN_RDEBUG( _L( "CNcnNotifApiObserver::NewEmailIndicatorsSetL Mail box not supported!") ); 
       
  1180         User::Leave( KErrNotSupported );
       
  1181         }
       
  1182             
       
  1183      //Get the service id    
       
  1184     const TMsvId serviceId = aMailboxStatus.iMailBox;
       
  1185     	
       
  1186     // get session
       
  1187     CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL();    
       
  1188 
       
  1189     // Prepare email API for settings loading
       
  1190     CImumInternalApi* emailApi = CreateEmailApiLC( &msvSession );
       
  1191     CImumInSettingsData* settings =
       
  1192         emailApi->MailboxServicesL().LoadMailboxSettingsL( serviceId );
       
  1193     CleanupStack::PushL( settings );        
       
  1194     
       
  1195     // Load settings for the indicator
       
  1196     TInt indicatorFlags = 0x00;
       
  1197     settings->GetAttr(
       
  1198         TImumDaSettings::EKeyEmailAlert,
       
  1199         indicatorFlags );
       
  1200 
       
  1201     // Cleanup
       
  1202     CleanupStack::PopAndDestroy( settings );
       
  1203     settings = NULL;
       
  1204     CleanupStack::PopAndDestroy( emailApi );
       
  1205     emailApi = NULL;
       
  1206 
       
  1207     NCN_RDEBUG_INT2( _L( "Indicator for MTM box %d is %d"), aMailboxStatus.iMTMType.iUid, indicatorFlags );
       
  1208 
       
  1209     // return
       
  1210     return ( indicatorFlags == TImumDaSettings::EFlagAlertSoftNote );
       
  1211     }
       
  1212 
       
  1213 // ---------------------------------------------------------
       
  1214 // CNcnNotifApiObserver::ServiceEntryL
       
  1215 // ---------------------------------------------------------
       
  1216 //    
       
  1217 CMsvEntry* CNcnNotifApiObserver::ServiceEntryL( const TMsvId& aServiceId )
       
  1218     {
       
  1219     // Get the entry from id
       
  1220     CMsvEntry* service = ServiceEntryLC( aServiceId );    
       
  1221     CleanupStack::Pop( service );
       
  1222     
       
  1223     return service;
       
  1224     }
       
  1225     
       
  1226 // ---------------------------------------------------------
       
  1227 // CNcnNotifApiObserver::ServiceEntryLC
       
  1228 // ---------------------------------------------------------
       
  1229 //    
       
  1230 CMsvEntry* CNcnNotifApiObserver::ServiceEntryLC( const TMsvId& aServiceId )
       
  1231     {
       
  1232     // get msv session handler from model
       
  1233     CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL();
       
  1234     
       
  1235     // Get the entry from id
       
  1236     CMsvEntry* service = msvSession.GetEntryL( aServiceId );        
       
  1237     CleanupStack::PushL( service );
       
  1238     
       
  1239     // get service entry
       
  1240     const TMsvEntry& serviceEntry = service->Entry();   
       
  1241     
       
  1242     // leave with KErrNotSupported if entry does not point to a service
       
  1243     if( serviceEntry.iType.iUid != KUidMsvServiceEntryValue )
       
  1244         {
       
  1245         User::Leave( KErrNotSupported );
       
  1246         }
       
  1247     
       
  1248     // return service
       
  1249     return service;
       
  1250     }
       
  1251 
       
  1252 // ---------------------------------------------------------
       
  1253 // CNcnNotifApiObserver::UpdateNotification
       
  1254 // ---------------------------------------------------------
       
  1255 //
       
  1256 void CNcnNotifApiObserver::UpdateNotification( 	TBool aForceUpdate,
       
  1257 										        TBool aIcon,
       
  1258 										        TBool aTone,
       
  1259 										        TBool aNote )
       
  1260     {
       
  1261     // update new email count
       
  1262     UpdateTotalNewEmails();
       
  1263 
       
  1264     NCN_RDEBUG_INT2( _L( "CNcnNotifApiObserver::UpdateNotificationL - previous total %d, new total %d" ),
       
  1265             iNotifiedNewMailCount,
       
  1266             iTotalNewMailCount );
       
  1267             
       
  1268     // actions only needed if new count differs from last notified
       
  1269     // or the action is forced
       
  1270     if( ((iTotalNewMailCount > 0)&& (iNotifiedNewMailCount != iTotalNewMailCount)) || aForceUpdate )        
       
  1271         {                
       
  1272         // count will be notified now
       
  1273         iNotifiedNewMailCount = iTotalNewMailCount;       
       
  1274                 
       
  1275         // Inform notifier of any changes
       
  1276         iModel.NcnNotifier().SetNotification(
       
  1277             MNcnNotifier::ENcnEmailNotification,
       
  1278             iTotalNewMailCount,
       
  1279             aIcon,
       
  1280             aTone,
       
  1281             aNote );
       
  1282         }
       
  1283     }
       
  1284 
       
  1285 // ---------------------------------------------------------
       
  1286 // CNcnNotifApiObserver::IsEMailEntry
       
  1287 // ---------------------------------------------------------
       
  1288 //
       
  1289 TBool CNcnNotifApiObserver::IsEMailEntry( const TMsvEntry& aEntry  )
       
  1290     {
       
  1291     TBool ret = EFalse;
       
  1292 
       
  1293     // if it is an entry    
       
  1294     if( aEntry.iType.iUid == KUidMsvMessageEntryValue )
       
  1295         {
       
  1296         // count mailboxes
       
  1297         TInt count( iMailBoxStatusArray.Count() );
       
  1298             
       
  1299         // check each box
       
  1300         while( count-- )
       
  1301             {        
       
  1302             // get mailbox status
       
  1303             const TNcnMailBoxStatus& mailboxStatus = iMailBoxStatusArray[count];
       
  1304             
       
  1305             // if mailboxes message server id matches with entrys service id
       
  1306             if( mailboxStatus.iMailBox == aEntry.iServiceId )
       
  1307                 {
       
  1308                 ret = ETrue;
       
  1309                 break;
       
  1310                 }
       
  1311             }
       
  1312         }
       
  1313                 
       
  1314     return ret;
       
  1315     }    
       
  1316     
       
  1317 // ---------------------------------------------------------
       
  1318 // CNcnNotifApiObserver::GetMailBoxesAttributesL
       
  1319 // ---------------------------------------------------------
       
  1320 //
       
  1321 TInt CNcnNotifApiObserver::GetMailBoxesAttributesL( 	const TMsvId& aMsvId, 
       
  1322 														TUid& aMtmType, 
       
  1323 														TUid& aTechnologyType )
       
  1324     {   
       
  1325     // get msv session reference
       
  1326     CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL();
       
  1327          
       
  1328     // service id and entry
       
  1329     TMsvId serviceId;
       
  1330     TMsvEntry entry;
       
  1331     
       
  1332     TInt error = msvSession.GetEntry( aMsvId, serviceId, entry );
       
  1333     
       
  1334     if( error == KErrNone )
       
  1335         {
       
  1336         // if entry is a service
       
  1337         if( entry.iType.iUid == KUidMsvServiceEntryValue )
       
  1338             {
       
  1339             // instantiate client mtm registry
       
  1340             CClientMtmRegistry* registry = CClientMtmRegistry::NewL( msvSession );
       
  1341             
       
  1342             // get MTM type
       
  1343             aMtmType = entry.iMtm;
       
  1344                         
       
  1345             // get technology type
       
  1346             aTechnologyType = registry->TechnologyTypeUid( entry.iMtm );
       
  1347  
       
  1348             // delete registry
       
  1349             delete registry;
       
  1350             }
       
  1351         }
       
  1352         
       
  1353     return error;
       
  1354     }
       
  1355         
       
  1356 // ---------------------------------------------------------
       
  1357 // CNcnNotifApiObserver::IsMailTechnologyType
       
  1358 // ---------------------------------------------------------
       
  1359 //
       
  1360 TBool CNcnNotifApiObserver::IsMailTechnologyType( const TUid& aTechnologyType )
       
  1361     {
       
  1362     return ( aTechnologyType == KMailTechnologyTypeUid );
       
  1363     }
       
  1364     
       
  1365 // ---------------------------------------------------------
       
  1366 // CNcnNotifApiObserver::IsNotificationNeededForThisMessageL
       
  1367 // ---------------------------------------------------------
       
  1368 //
       
  1369 TBool CNcnNotifApiObserver::IsNotificationNeededForThisMessageL( const TNcnMailBoxStatus& aMailbox, 
       
  1370 																const TMsvEntry& aEntry )
       
  1371 	{
       
  1372 	NCN_RDEBUG_INT2( _L( "CNcnNotifApiObserver::IsNotificationNeeded - Entry: %d in box: %d examined"), 
       
  1373 						aEntry.Id(), aMailbox.iMailBox  );
       
  1374 	
       
  1375 	//Check if this is an IMAP box. If it is we compare message id's
       
  1376 	if( aMailbox.iMTMType.iUid == KSenduiMtmImap4UidValue )
       
  1377 		{
       
  1378 		NCN_RDEBUG( _L( "CNcnNotifApiObserver::NotificationIsNeeded - Mail box is IMAP" ) );
       
  1379 		
       
  1380 		//Checking is done by using the IMAP id     
       
  1381         TMsvEmailEntry emailEntry(aEntry);   
       
  1382  	    NCN_RDEBUG_INT2( _L( "IMAP uid in this message is %d, last notified was %d" ), 
       
  1383  	    					emailEntry.UID(), aMailbox.iPublishedCheckpointIMAPId );
       
  1384 
       
  1385         //Check if the IMAP uid is higher or lower
       
  1386         if( emailEntry.UID() > aMailbox.iPublishedCheckpointIMAPId )
       
  1387 	        {
       
  1388 	        //This message has higher uid than the last notified had. Notify this.
       
  1389 	        NCN_RDEBUG( _L( "Notification is needed for this message!") );
       
  1390 	        return ETrue;	
       
  1391 	        }
       
  1392 	    else
       
  1393 	    	{
       
  1394 	        NCN_RDEBUG( _L( "Notification is NOT needed for this message!") );
       
  1395 	        return EFalse;		    		
       
  1396 	    	}
       
  1397 		}
       
  1398 	else if( aMailbox.iMTMType.iUid == KSenduiMtmSmtpUidValue )
       
  1399 	    {
       
  1400 	    NCN_RDEBUG( _L( "SMTP Entry, no notification!") );
       
  1401 	    return EFalse;
       
  1402 	    }
       
  1403 	//Not an IMAP box. POP, Syncml etc. Lets compare time stamps
       
  1404 	else
       
  1405 		{
       
  1406 		NCN_RDEBUG( _L( "CNcnNotifApiObserver::NotificationIsNeeded - Mail box is POP, Sync etc." ) );
       
  1407         
       
  1408         // Check if the message is new to the device
       
  1409 		NCN_RDEBUG_INT2( _L( "UId in this message is %d, last notified was %d" ), 
       
  1410 				aEntry.Id() , aMailbox.iPublishedCheckpointMsvId );
       
  1411 
       
  1412 		
       
  1413 		if ( aEntry.Id() > aMailbox.iPublishedCheckpointMsvId && !IsSyncMLEntryInSentFolderL( aEntry ))
       
  1414 			{
       
  1415 	        // Message is new to device. Notify this.
       
  1416 	        NCN_RDEBUG( _L( "Notification is needed for this message!") );
       
  1417 	        return ETrue;	
       
  1418 	        }
       
  1419 	    else
       
  1420 	    	{
       
  1421 	        NCN_RDEBUG( _L( "Notification is NOT needed for this message!!") );
       
  1422 	        return EFalse;		    		
       
  1423 	    	}
       
  1424 		}	
       
  1425 	}
       
  1426 
       
  1427 // ---------------------------------------------------------
       
  1428 // CNcnNotifApiObserver::IsSyncMLEntryInSentFolderL
       
  1429 // ---------------------------------------------------------
       
  1430 //
       
  1431 TBool CNcnNotifApiObserver::IsSyncMLEntryInSentFolderL( const TMsvEntry& aEntry  )
       
  1432 	{
       
  1433 	CMsvSession& msvSession = iModel.MsvSessionHandler().MsvSessionL();
       
  1434 	    
       
  1435 	// get service id and entry
       
  1436 	TMsvId serviceId;
       
  1437 	TMsvEntry entryParent;        
       
  1438 	TInt err = msvSession.GetEntry( aEntry.Parent(), serviceId, entryParent );
       
  1439 	
       
  1440 	if ( entryParent.iMtm == KSenduiMtmSyncMLEmailUid && entryParent.iRelatedId == KMsvSentEntryId )
       
  1441 		{
       
  1442 		return ETrue;
       
  1443 		}
       
  1444 	return EFalse;
       
  1445 	}
       
  1446 // ---------------------------------------------------------
       
  1447 // CNcnNotifApiObserver::UpdateS60MailBoxNotificationAttributesL
       
  1448 // ---------------------------------------------------------
       
  1449 //
       
  1450 void CNcnNotifApiObserver::UpdateS60MailBoxNotificationAttributesL( TNcnMailBoxStatus& aMailbox )
       
  1451 	{
       
  1452 	NCN_RDEBUG( _L( "CNcnNotifApiObserver::GetS60MailBoxNotificationAttributesL" ) );
       
  1453 	
       
  1454 	//Get the "new mail indicator" setting for this box
       
  1455 	TBool setting = NewEmailIndicatorsSetL(aMailbox);
       
  1456 	TInt desiredNotifications = MNcnNotification::EIndicationNormal;
       
  1457 	TInt status = KErrNone;
       
  1458 	
       
  1459 	//Get the notifications from CR key
       
  1460 	if( setting == TRUE )
       
  1461 		{
       
  1462 		status = iModel.GetCRInteger( KCRUidNcnList, KNcnMailNotificationIndicatorOn, desiredNotifications );	
       
  1463 		}
       
  1464 	else
       
  1465 		{	
       
  1466 		status = iModel.GetCRInteger( KCRUidNcnList, KNcnMailNotificationIndicatorOff, desiredNotifications );	
       
  1467 		}
       
  1468 		
       
  1469 	//Look at the value and see if it is OK
       
  1470 	if( status != KErrNone ||
       
  1471 		( desiredNotifications != MNcnNotification::EIndicationIcon &&
       
  1472 		  desiredNotifications != MNcnNotification::EIndicationToneAndIcon &&
       
  1473 		  desiredNotifications != MNcnNotification::EIndicationNormal ) ) 
       
  1474 		{
       
  1475 		NCN_RDEBUG_INT2(_L("Notification is erronous! Setting notifications to default! status: %d value: %d"), status, desiredNotifications );
       
  1476 		desiredNotifications = MNcnNotification::EIndicationNormal;	
       
  1477 		}
       
  1478 				
       
  1479 	//Set the values to mailbox	
       
  1480 	UpdateMailBoxesNotifications( aMailbox, desiredNotifications );		
       
  1481 	}
       
  1482 
       
  1483 // ---------------------------------------------------------
       
  1484 // CNcnNotifApiObserver::UpdateMailBoxesNotifications
       
  1485 // ---------------------------------------------------------
       
  1486 //
       
  1487 void CNcnNotifApiObserver::UpdateMailBoxesNotifications( 	
       
  1488 		TNcnMailBoxStatus& aMailbox, 
       
  1489 		const TInt& aIndicationType )
       
  1490 	{
       
  1491     NCN_RDEBUG( _L("[ncnlist] CNcnNotifApiObserver UpdateMailBoxesNotifications") );
       
  1492 
       
  1493     //Only icon is desired
       
  1494     if( aIndicationType == MNcnNotification::EIndicationIcon )
       
  1495 	    {
       
  1496 	    aMailbox.iIcon = ETrue;
       
  1497     	aMailbox.iTone = EFalse;
       
  1498     	aMailbox.iNote = EFalse;	    	
       
  1499 	    }
       
  1500 	//Icon and tone is desired
       
  1501 	else if( aIndicationType == MNcnNotification::EIndicationToneAndIcon  )	 
       
  1502 		{
       
  1503 	    aMailbox.iIcon = ETrue;
       
  1504     	aMailbox.iTone = ETrue;
       
  1505     	aMailbox.iNote = EFalse;	 			
       
  1506 		}
       
  1507 	//Default is all notifications
       
  1508 	else
       
  1509 		{
       
  1510 	    aMailbox.iIcon = ETrue;
       
  1511     	aMailbox.iTone = ETrue;
       
  1512     	aMailbox.iNote = ETrue;	 			
       
  1513 		}
       
  1514 		
       
  1515     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver Indicators - Icon: %d"), aMailbox.iIcon);
       
  1516     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver Indicators - Tone: %d"), aMailbox.iTone);  
       
  1517     NCN_RDEBUG_INT( _L("[ncnlist] CNcnNotifApiObserver Indicators - Note: %d"), aMailbox.iNote);      
       
  1518 	}
       
  1519 		           
       
  1520 //  End of File