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