emailservices/emailserver/cmailhandlerplugin/src/fsmailmtmhandler.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
--- /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.
+*
+*/
+
+
+//<cmail>
+#include "emailtrace.h"
+#include "CFSMailClient.h"
+//</cmail>
+#include <e32base.h> // needed because of the following hrh
+#include <data_caging_path_literals.hrh> // KDC_MTM_INFO_FILE_DIR
+#include <mtclreg.h>
+#include <w32std.h>
+#include <apgtask.h>
+//<cmail>
+#include "cfsclientmtm.h"
+#include "fsmtmsconstants.h"
+//</cmail>
+#include <coemain.h>
+
+#include "fsmailmtmhandler.h"
+
+
+// FREESTYLE EMAIL FRAMEWORK INCLUDES
+//<cmail>
+#include "CFSMailClient.h"
+#include "MFSMailBrandManager.h"
+//</cmail>
+
+
+#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<CFSMailBox> mailBoxes;
+    mailBoxes.Reset();
+
+    TFSMailMsgId plugin;
+    mail->ListMailBoxes(plugin,mailBoxes);
+    
+    RArray<TFSMailMsgId> mailBoxIds;
+    
+    for(int i=0; i<mailBoxes.Count(); i++)
+    	{
+    	TDesC& name( mailBoxes[i]->GetName() );
+    	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<TUid*>(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.
+    }
+