--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/ccapplication/ccapp/ccaclient/src/ccaconnection.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,361 @@
+/*
+* 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 <e32std.h>
+#include <s32mem.h>
+#include <aknappui.h>
+
+#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<CCCAParameter*>( &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;
+ }
+
+ //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 );
+ }
+
+ iClosePending = EFalse;
+ 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