diff -r 000000000000 -r 8466d47a6819 emailservices/emailserver/cmailhandlerplugin/src/fsmailmtmhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailservices/emailserver/cmailhandlerplugin/src/fsmailmtmhandler.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,424 @@ +/* +* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class to handle mail led turning on. +* +*/ + + +// +#include "emailtrace.h" +#include "CFSMailClient.h" +// +#include // needed because of the following hrh +#include // KDC_MTM_INFO_FILE_DIR +#include +#include +#include +// +#include "cfsclientmtm.h" +#include "fsmtmsconstants.h" +// +#include + +#include "fsmailmtmhandler.h" + + +// FREESTYLE EMAIL FRAMEWORK INCLUDES +// +#include "CFSMailClient.h" +#include "MFSMailBrandManager.h" +// + + +#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0]) + +_LIT( KMessageServerProcessIdentifier, "MSEXE*" ); + + +CFSMailMtmHandler* CFSMailMtmHandler::NewL( + MFSNotificationHandlerMgr& aOwner ) + { + FUNC_LOG; + CFSMailMtmHandler* self = + new (ELeave) CFSMailMtmHandler( aOwner ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +CFSMailMtmHandler::CFSMailMtmHandler( + MFSNotificationHandlerMgr& aOwner ) : + CFSNotificationHandlerBase( aOwner ), + iStartingUp( ETrue ) + { + FUNC_LOG; + } + +void CFSMailMtmHandler::ConstructL() + { + FUNC_LOG; + CFSNotificationHandlerBase::ConstructL(); + + TRAPD( installError, InstallMtmL() ); + if ( installError != KErrNone ) + { + User::Leave( installError ); + } + + CFSMailClient* mail = CFSMailClient::NewL(); + + RPointerArray mailBoxes; + mailBoxes.Reset(); + + TFSMailMsgId plugin; + mail->ListMailBoxes(plugin,mailBoxes); + + RArray mailBoxIds; + + for(int i=0; iGetName() ); + TDesC& ownAddress( mailBoxes[i]->OwnMailAddress().GetEmailAddress() ); + TRAPD(createError, iMtmClient->CreateAccountL( name, ownAddress, mailBoxes[i]->GetId() )); + if(createError != KErrNone) + { + // Error + } + mailBoxIds.Append(mailBoxes[i]->GetId()); + } + // Remove rendundant accounts + TRAPD(removeRedundantError, iMtmClient->RemoveRedundantAccountsL( mailBoxIds )); + if(removeRedundantError != KErrNone) + { + } + + + mailBoxIds.Close(); + mailBoxes.ResetAndDestroy(); + mailBoxes.Close(); + + mail->Close(); + + } + +CFSMailMtmHandler::~CFSMailMtmHandler() + { + FUNC_LOG; + UninstallMtm(); + } + +// --------------------------------------------------------------------------- +// This is here just to absorb callbacks. +// --------------------------------------------------------------------------- +// +void CFSMailMtmHandler::HandleSessionEventL( + TMsvSessionEvent aEvent, + TAny* /*aArg1*/, + TAny* aArg2, + TAny* /*aArg3*/) + { + FUNC_LOG; + + // Just being really really sure that the mtm client is created only + // when we are in the start up phase. + if ( iStartingUp ) + { + // Normally this would have been done after the registry creation. + // If NewMtmL is called immediately after registry creation, + // it seems to cause panic when active scheduler is started. + // This seems to be because the previous DeInstallMtmGroup and + // InstallMtmGroup get done only after active scheduler is started. + // If they are done at that point, the CFsMtmClient is already + // created and the DeInstallMtmGroup seem to cause panic. + // The panic is avoided by first waiting for that the deinstall and + // install are done before creating the CFsMtmClient. + if ( aEvent == EMsvMtmGroupInstalled && + KUidMsgValTypeFsMtmVal == *static_cast(aArg2) ) + { + } + } + } + +TBool CFSMailMtmHandler::CapabilitiesToContinueL( + TFSMailEvent /*aEvent*/, + TFSMailMsgId aMailbox, + TAny* /*aParam1*/, + TAny* /*aParam2*/, + TAny* /*aParam3*/ ) const + { + FUNC_LOG; + CFSMailBox* mailBox( MailClient().GetMailBoxByUidL( aMailbox ) ); + if ( mailBox == NULL ) + { + User::Leave( KErrArgument ); + } + + if ( mailBox->HasCapability( EFSMBoxCapaSymbianMsgIntegration ) ) + { + delete mailBox; + return EFalse; + } + else + { + delete mailBox; + return ETrue; + } + } + +void CFSMailMtmHandler::HandleEventL( + TFSMailEvent aEvent, + TFSMailMsgId aMailbox, + TAny* /*aParam1*/, + TAny* /*aParam2*/, + TAny* /*aParam3*/ ) + { + FUNC_LOG; + switch ( aEvent ) + { + case TFSEventMailboxSettingsChanged: + { + // At the moment this event is only for handling the case when + // Email address of the mailbox has been changed + CFSMailBox* mailBox( MailClient().GetMailBoxByUidL( aMailbox ) ); + User::LeaveIfNull( mailBox ); + CleanupStack::PushL( mailBox ); + TDesC& ownAddress( mailBox->OwnMailAddress().GetEmailAddress() ); + User::LeaveIfError( + iMtmClient->RenameAccountL( KNullDesC, ownAddress, aMailbox ) ); + CleanupStack::PopAndDestroy( mailBox ); + break; + } + case TFSEventNewMailbox: + { + CFSMailBox* mailBox( + MailClient().GetMailBoxByUidL( aMailbox ) ); + User::LeaveIfNull( mailBox ); + CleanupStack::PushL( mailBox ); + + // Branded mailbox name is nowadays set in new mailbox event + // handling, so we don't need to use brand manager here anymore. + + TDesC& name( mailBox->GetName() ); + TDesC& ownAddress( mailBox->OwnMailAddress().GetEmailAddress() ); + + User::LeaveIfError( + iMtmClient->CreateAccountL( name, ownAddress, aMailbox ) ); + + CleanupStack::PopAndDestroy( mailBox ); + break; + } + case TFSEventMailboxDeleted: + { + + // Entry details cannot necessarily be fetched anymore as the + // entry might be deleted from the Message Server. + User::LeaveIfError( + iMtmClient->DeleteAccountL( KNullDesC, aMailbox ) ); + + break; + } + case TFSEventMailboxRenamed: + { + CFSMailBox* mailBox( + MailClient().GetMailBoxByUidL( aMailbox ) ); + User::LeaveIfNull( mailBox ); + CleanupStack::PushL( mailBox ); + TDesC& name( mailBox->GetName() ); + TDesC& ownAddress( mailBox->OwnMailAddress().GetEmailAddress() ); + + User::LeaveIfError( + iMtmClient->RenameAccountL( name, ownAddress, aMailbox ) ); + + CleanupStack::PopAndDestroy( mailBox ); + break; + } + case TFSMailboxAvailable: // Flow through + case TFSMailboxUnavailable: // Flow through + { + break; + } + default: + { + break; + } + } + } + +void CFSMailMtmHandler::InstallMtmL() + { + FUNC_LOG; + iMsvSession = CMsvSession::OpenSyncL( *this ); + + //Construct the path information for the Installation file. + TFileName resourceFileName = InstallationFilenameL(); + + + //Install MTMs. + TInt err = iMsvSession->InstallMtmGroup( resourceFileName ); + if( err!=KErrNone && err!=KErrAlreadyExists ) + { + User::LeaveIfError( err ); + } + + + // Create client side mtm account. + iMtmRegistry = CClientMtmRegistry::NewL( *iMsvSession ); + + + //Jagan: 19th Oct - Added this by looking at TxtMTM Example + if( !iMtmRegistry->IsPresent( KUidMsgValTypeFsMtmVal ) ) + { + //Freestyle not present in Client MTM Registry + User::Leave( KErrNotFound ); + } + + TRAPD( creationError, iMtmClient = + (CFsMtmClient*) iMtmRegistry->NewMtmL( + KUidMsgValTypeFsMtmVal ); ) + if ( creationError != KErrNone ) + { + User::Leave( creationError ); + } + iStartingUp = EFalse; + // We are now ready to observe mail events + SetObserving( ETrue ); + } + +void CFSMailMtmHandler::UninstallMtm() + { + FUNC_LOG; + delete iMtmClient; + iMtmClient = NULL; + + delete iMtmRegistry; + iMtmRegistry = NULL; + + // KILL THE MESSAGE SERVER PROCESS + KillProcess( KMessageServerProcessIdentifier ); + User::After( KOneSecond ); + + // UNINSTALL THE MTM + + TInt err; + + //Construct the path information for the Installation file. + TFileName resourceFileName; + TRAP( err, resourceFileName = InstallationFilenameL() ); + + if ( err == KErrNone && iMsvSession ) + { + // Uninstall the MTMs. + TInt retryCount = 0; + do + { + err = iMsvSession->DeInstallMtmGroup( resourceFileName ); + if ( err == KErrNone ) + { + // success + } + else if ( err == KErrInUse ) + { + // MTMs in use, killing apps and retry + TRAP_IGNORE( KillAppsL() ); + //wait one second + User::After( KOneSecond ); + } + else + { + // failure + } + } while ( err == KErrInUse && retryCount++ < KMAxRetry ); + } + else + { + // Cannot define the filename or session not created. + // Just continue with the session deletion. + + // Notice: Although deinstallation would fail + // (and installation was done earlier) it seems that + // crash does not occur even if we continue onwards. + } + + delete iMsvSession; + iMsvSession = NULL; + } + +TFileName CFSMailMtmHandler::InstallationFilenameL() + { + FUNC_LOG; + //Construct the path information for the Installation file. + TFileName fileName; + + TFindFile finder( CCoeEnv::Static()->FsSession() ); + User::LeaveIfError( + finder.FindByDir( KFsMtmDirAndFile, KDC_MTM_INFO_FILE_DIR ) ); + fileName = finder.File(); + + return fileName; + } + +void CFSMailMtmHandler::KillProcess( const TDesC& aName ) + { + FUNC_LOG; + TFullName name; + TFindProcess find( aName ); + RProcess process; + + while ( find.Next( name ) == KErrNone ) + { + if ( process.Open( find ) == KErrNone ) + { + process.Kill( KErrGeneral ); + process.Close(); + } + } // end while + } + +void CFSMailMtmHandler::KillAppsL() + { + FUNC_LOG; + RWsSession session; + User::LeaveIfError( session.Connect() ); + CleanupClosePushL( session ); + + TInt appCount = ARRAY_SIZE( KAppsToKill ); + + TApaTaskList taskList( session ); + + for ( int i = 0 ; i < appCount ; i++ ) + { + TApaTask task = taskList.FindApp( KAppsToKill[i] ); + if ( task.Exists() ) + { + task.EndTask(); + } + } + CleanupStack::PopAndDestroy( &session ); + } + +void CFSMailMtmHandler::TurnNotificationOn() + { + FUNC_LOG; + // This is not used. Instead CFsMtmClient is used + // directly in HandleEventL. + } + +void CFSMailMtmHandler::TurnNotificationOff() + { + FUNC_LOG; + // This is not used. Instead CFsMtmClient is used + // directly in HandleEventL. + } +