diff -r 5b6f26637ad3 -r f4a778e096c2 phonebookui/Phonebook2/ccapplication/ccapp/ccaclient/src/ccaconnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/ccapplication/ccapp/ccaclient/src/ccaconnection.cpp Wed Sep 01 12:29:52 2010 +0100 @@ -0,0 +1,363 @@ +/* +* Copyright (c) 2007 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: CCA client's connecting class. +* +*/ + +#include +#include +#include + +#include "ccaclientheaders.h" + +/// Unnamed namespace for local definitions +namespace { + +const TInt KCCAStreamBufferSize = 256; +const TInt KCCAConnectionMaxRetriesForLaunchKErrInUse = 5; +const TInt KCCAConnectionRelaunchDelay = 0.2 * 1000000;// 0.2 sec + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPreCond_DoLaunchL = 1, + EPanicPreCond_DoLaunchL2, + EPanicPreCond_DoLaunchL3 + }; + +void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CCCAConnection"); + User::Panic(KPanicText, aReason); + } +#endif // _DEBUG + +} /// namespace + + + +// ================= MEMBER FUNCTIONS ======================= +// + +// ---------------------------------------------------------- +// CCCAConnection::NewL +// ---------------------------------------------------------- +// +CCCAConnection* CCCAConnection::NewL() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::NewL")); + + CCCAConnection* self = new (ELeave) CCCAConnection(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------- +// CCCAConnection::CCCAConnection +// ---------------------------------------------------------- +// +CCCAConnection::CCCAConnection() : + CActive( EPriorityStandard ), + iAppStatus( EAppClosed ), + iMsgStreamPtr( NULL, 0 ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::CCCAConnection")); + CActiveScheduler::Add( this ); + } + +// ---------------------------------------------------------- +// CCCAConnection::ConstructL +// ---------------------------------------------------------- +// +void CCCAConnection::ConstructL() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::ConstructL")); + iSchedulerWait = new ( ELeave ) CActiveSchedulerWait(); + } + +// ---------------------------------------------------------- +// CCCAConnection::~CCCAConnection +// ---------------------------------------------------------- +// +CCCAConnection::~CCCAConnection() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::~CCCAConnection")); + + Cancel(); + delete iSchedulerWait; + delete iMsgStream; + DisconnectServerApplication(); + CloseParameter(); + } + +// ---------------------------------------------------------- +// CCCAConnection::Close +// ---------------------------------------------------------- +// +void CCCAConnection::Close() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::Close")); + delete this; + } + +// -------------------------------------------------------------------------- +// CCCAConnection::RunL +// -------------------------------------------------------------------------- +// +void CCCAConnection::RunL() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::RunL: iStatus: %d"), iStatus.Int()); + if ( iSchedulerWait->IsStarted() ) + { + iSchedulerWait->AsyncStop(); + } + } + +// -------------------------------------------------------------------------- +// CCCAConnection::DoCancel +// -------------------------------------------------------------------------- +// +void CCCAConnection::DoCancel() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::DoCancel")); + if ( iSchedulerWait->IsStarted() ) + { + iSchedulerWait->AsyncStop(); + } + } + +// ---------------------------------------------------------- +// CCCAConnection::LaunchApplicationL +// ---------------------------------------------------------- +// +void CCCAConnection::LaunchApplicationL( MCCAParameter& aParameter ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "->CCCAConnection::LaunchApplicationL")); + + //Only one active connection per time + __ASSERT_ALWAYS( iAppStatus == EAppClosed, User::Leave( KErrAlreadyExists )); + + iAppStatus = EAppLaunching; + + //PERFORMANCE LOGGING: 1. Starting AppServer (StartPoint) + WriteToPerfLog(); + WriteToPerfLaunchLog(_L(" CCA launched")); + + // Need to trap, because consumer freezes if ConnectL function leaves. + // Reason for the freeze is that connection stays open. + TRAPD( error, ConnectServerApplicationL() ); + if ( KErrNone != error ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "::LaunchApplicationL: Error connect: %d"), error); + DisconnectServerApplication(); + User::Leave( error ); + } + + DoLaunchL( aParameter ); + SetActive(); + iSchedulerWait->Start(); + + error = iStatus.Int(); + if ( KErrNone != error ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "::LaunchApplicationL: Error launch: %d"), error); + DisconnectServerApplication(); + User::Leave( error ); + } + + iAppStatus = EAppRunning; + + CCA_DP(KCCAClientLoggerFile, CCA_L( "<-CCCAConnection::LaunchApplicationL")); + } + +// ---------------------------------------------------------- +// CCCAConnection::LaunchAppL +// ---------------------------------------------------------- +// +void CCCAConnection::LaunchAppL( + MCCAParameter& aParameter, + MCCAObserver* aObserver ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "->CCCAConnection::LaunchAppL")); + + if (iAppStatus == EAppClosed) + { + LaunchApplicationL( aParameter ); + + CloseParameter(); + iParameter = static_cast( &aParameter ); + iObserver = aObserver; + } + + CCA_DP(KCCAClientLoggerFile, CCA_L( "<-CCCAConnection::LaunchAppL")); + } + +// -------------------------------------------------------------------------- +// CCCAConnection::CloseAppL +// -------------------------------------------------------------------------- +// +void CCCAConnection::CloseAppL() + { + if ( !iClosePending ) //To protect from duplicate close attempts + { + iAppService.DoCloseApplication(); + iClosePending = ETrue; + } + } + +// -------------------------------------------------------------------------- +// CCCAConnection::HandleServerAppExit +// -------------------------------------------------------------------------- +// +void CCCAConnection::HandleServerAppExit( TInt aReason ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "->CCCAConnection::HandleServerAppExit")); + CCA_DP(KCCAClientLoggerFile, CCA_L( "::HandleServerAppExit: aReason: %d"), aReason); + + DisconnectServerApplication(); + + TInt flags(0); + if(iParameter) + { + flags = iParameter->ConnectionFlag(); + } + + if ( iObserver ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "::HandleServerAppExit - informing observer about exit")); + CloseParameter(); + TRAP_IGNORE( iObserver->CCASimpleNotifyL( MCCAObserver::EExitEvent, aReason )); + iObserver = NULL; + } + + iClosePending = EFalse; + + //Kill us if not soft exit requested + if(!(flags & MCCAParameter::ESoftExit)) + { + //Kill this process, i.e. the application running ccaclient + // Following call ends application if aReason == EAknCmdExit (and does nothing else) + MAknServerAppExitObserver::HandleServerAppExit( aReason ); + } + + + CCA_DP(KCCAClientLoggerFile, CCA_L( "<-CCCAConnection::HandleServerAppExit")); + } + +// -------------------------------------------------------------------------- +// CCCAConnection::DisconnectServerApplication +// -------------------------------------------------------------------------- +// +void CCCAConnection::DisconnectServerApplication() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "->CCCAConnection::DisconnectServerApplication")); + + delete iMonitor; + iMonitor = NULL; + iAppService.Close(); + iAppStatus = EAppClosed; + + CCA_DP(KCCAClientLoggerFile, CCA_L( "<-CCCAConnection::DisconnectServerApplication")); + } + +// -------------------------------------------------------------------------- +// CCCAConnection::ConnectServerApplicationL +// -------------------------------------------------------------------------- +// +void CCCAConnection::ConnectServerApplicationL() + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "->CCCAConnection::ConnectServerApplicationL")); + + /* + * In cases when the CCApplication is running on background and connection + * is closed and reopened instantly, the opening of connection returns + * sometimes KErrInUse. One solution could be to arrange Rendezvous-signals + * between processes, but to keep implementation somewhat simple, launch is + * now just tried again couple of times with small delay between. + */ + TInt error = KErrInUse; + for ( TInt i = 0; i < KCCAConnectionMaxRetriesForLaunchKErrInUse && + (KErrNotFound == error || KErrInUse == error); i++ ) + { + TRAP( error, iAppService.DoConnectL()); + CCA_DP(KCCAClientLoggerFile, CCA_L( "::ConnectServerApplicationL: error: %d i: %d"), error, i ); + if ( KErrInUse == error && + i < KCCAConnectionMaxRetriesForLaunchKErrInUse - 1 ) + { + User::After( KCCAConnectionRelaunchDelay ); + } + } + User::LeaveIfError( error ); + + delete iMonitor; + iMonitor = NULL; + iMonitor = CApaServerAppExitMonitor::NewL( + iAppService, *this, CActive::EPriorityStandard ); + + CCA_DP(KCCAClientLoggerFile, CCA_L( "<-CCCAConnection::ConnectServerApplicationL")); + } + +// -------------------------------------------------------------------------- +// CCCAConnection::DoLaunchL +// -------------------------------------------------------------------------- +// +void CCCAConnection::DoLaunchL( MCCAParameter& aParameter ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "->CCCAConnection::DoLaunchL")); + __ASSERT_DEBUG( &aParameter, Panic(EPanicPreCond_DoLaunchL) ); + + CCCAParameter& param = STATIC_CAST(CCCAParameter&, aParameter); + CBufSeg* buf1 = CBufSeg::NewL( KCCAStreamBufferSize ); + CleanupStack::PushL( buf1 ); + + RBufWriteStream writeStream( *buf1 ); + CleanupClosePushL( writeStream ); + param.ExternalizeL( writeStream ); + writeStream.CommitL(); + + delete iMsgStream; + iMsgStream = NULL; + iMsgStreamPtr.Set( NULL, 0, 0 ); + + const TInt neededSize = buf1->Size(); + iMsgStream = HBufC8::NewL( neededSize ); + iMsgStreamPtr.Set( iMsgStream->Des() ); + buf1->Read( 0, iMsgStreamPtr, neededSize ); + CleanupStack::PopAndDestroy(2); //buf1, writeStream + + __ASSERT_DEBUG( 0 < iMsgStreamPtr.Size(), Panic(EPanicPreCond_DoLaunchL3) ); + + iStatus = KRequestPending; + iAppService.DoLaunch( iStatus, iMsgStreamPtr ); + + CCA_DP(KCCAClientLoggerFile, CCA_L( "<-CCCAConnection::DoLaunchL")); + } + +// ---------------------------------------------------------- +// CCCAConnection::CloseParameter +// ---------------------------------------------------------- +// +void CCCAConnection::CloseParameter( ) + { + CCA_DP(KCCAClientLoggerFile, CCA_L( "CCCAConnection::CloseParameter")); + if ( iParameter ) + { + iParameter->Close(); + iParameter = NULL; + } + } + +// End of file