--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IMPSengine/engsrv/src/impsorphans.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,558 @@
+/*
+* Copyright (c) 2004 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 for imps oprhan manage.
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <e32base.h>
+#include "ImpsOrphans.h"
+#include "impsfields.h"
+#include "impsdataaccessor.h"
+#include "impssdatautils.h"
+#include "impskey.h"
+
+// MACROS
+#ifndef _DEBUG
+#define _NO_IMPS_LOGGING_
+#endif
+
+// constant
+_LIT( KDefaultApplicationID, "Default" );
+static const TInt KDefaultQueueCapacity = 10; //The capacity of the orphan queue
+static const TInt KDefaultOrphanValidity = 3600;
+
+//**********************************
+// CImpsOrphans
+//**********************************
+CImpsOrphans::CImpsOrphans( )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::ConstructL
+// 2nd phase constructor
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::ConstructL()
+ {
+ iOrphanQueue = new( ELeave ) COrphanQueue( KDefaultQueueCapacity );
+ iLauncherProxy = CImpsAppLauncherProxy::NewL( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::NewL
+//
+// -----------------------------------------------------------------------------
+//
+CImpsOrphans* CImpsOrphans::NewL()
+ {
+ // Perform the construction.
+ CImpsOrphans* self = new ( ELeave ) CImpsOrphans( );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+//
+// -----------------------------------------------------------------------------
+//
+CImpsOrphans::~CImpsOrphans()
+ {
+ delete iLauncherProxy;
+ delete iOrphanQueue;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::NewOrphanL
+// Creates a new oprhan message and tries to launch the receiving application
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::NewOrphanL( CImpsFields* aMsg, TImpsSessIdent aCspId )
+ {
+ // Handle only NewMessage & Invitation
+ if ( ( aMsg->MessageType() != EImpsNewMessage ) &&
+ ( aMsg->MessageType() != EImpsInviteUserReq ) )
+ {
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: Orphan filtered out %d" ), aMsg->MessageType() );
+#endif
+ // Do not delete aMsg immediately but leave. This is because of
+ // CImpsCSPSession::CreateSapResponse still has references
+ // to CImpsFields entity used after this method call.
+ User::Leave( KErrNotSupported );
+ return;
+ }
+
+ TImpsEventType eventType( ServiceType( ( TImpsMessageType )aMsg->MessageType() ) );
+ COrphan* orphan = AddOrphanL( aMsg, eventType, aCspId ); // the ownership is in the iOrphanList
+ // Call application launcher
+ TInt err( iLauncherProxy->LaunchApplicationL( orphan->ApplicationId(), *( orphan->iSap ), *( orphan->iUserId ) ) );
+ if ( err != KErrNone )
+ {
+ // Application starting failed
+ // Orphaned message is kept in the queue until it expires or it is overwritten
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: Starting failed %d." ), err );
+#endif
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::NextOrphanLC
+// Transfers the next orphan message from the queue for handling
+// -----------------------------------------------------------------------------
+//
+CImpsFields* CImpsOrphans::NextOrphanLC( const TDesC& aCID,
+ TImpsEventType aServiceType,
+ TImpsSessIdent aCspId )
+ {
+ if ( ( aServiceType == EImpsEventMessage ) ||
+ ( aServiceType == EImpsEventCommon ) )
+ {
+ return iOrphanQueue->OrphanMessageLC( aCID, aServiceType, aCspId );
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::CheckExpiryL
+// Deletes the expired orphan messages
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::CheckExpiryL( )
+ {
+
+ TTime myExpiry;
+ myExpiry.HomeTime();
+
+ iOrphanQueue->DiscardExpired( myExpiry );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::Stop
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::Stop( )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::HandleAppLaunchL
+// Handles the application launch
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::HandleAppLaunch( const TDesC& /*aApplicationId*/, TInt aStatus )
+ {
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: HandleAppLaunchL status %d" ), aStatus );
+#endif
+
+ // removing the warning
+ aStatus++;
+ }
+// -----------------------------------------------------------------------------
+// CImpsOrphans::AddOrphanL
+// Creates and adds an orphan message to queue
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+COrphan* CImpsOrphans::AddOrphanL( CImpsFields *aFields,
+ TImpsEventType aServiceType,
+ TImpsSessIdent aCspId )
+ {
+ // Get the ClientID, SessionID
+ TPtrC sessionID = aFields->SessionIdL();
+ TPtrC applicationID;
+
+ TImpsDataAccessor myAc( aFields );
+ TImpsSDataUtils::GetApplicationIDL( &myAc, applicationID );
+ // Get the Validity time from message: relative time
+ TTimeIntervalSeconds validity;
+ GetValidityFromMessageL( myAc, validity );
+
+ if ( applicationID.Length() == 0 )
+ {
+ applicationID.Set( KDefaultApplicationID );
+ }
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: NewOrphan(appID: %S, servType: %u, SAP: %S, user: %S)" ), &applicationID, aServiceType, &aCspId.SAP(), &aCspId.UserId() );
+#endif
+
+ // Set the validity as absolute time
+ TTime myTime;
+ myTime.HomeTime();
+ myTime += validity;
+
+#ifndef _NO_IMPS_LOGGING_
+ _LIT( KDateString5, "%-B%:0%J%:1%T%:2%S%:3%+B" );
+ TBuf<30> dateString;
+ myTime.FormatL( dateString, KDateString5 );
+ CImpsClientLogger::Log( _L( "CImpsOrphans: NewOrphan valid till %S" ), &dateString );
+#endif
+
+ COrphan* orphan = COrphan::NewL( applicationID,
+ sessionID,
+ aServiceType,
+ aCspId.SAP(),
+ aCspId.UserId(),
+ myTime,
+ aFields );
+ iOrphanQueue->Add( *orphan );
+ return orphan;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::GetValidityFromMessage
+// Retrieves the message validity from the instant message. The validity is in
+// seconds. If the message did not contain the validity then the default
+// validity is returned.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::GetValidityFromMessageL( MImpsDataAccessor& aAc,
+ TTimeIntervalSeconds& aValidity )
+ {
+ TInt validity;
+ CImpsKey* myKey = CImpsKey::NewLC();
+ myKey->AddL( CREATEKEY( EImpsKeySession, 0 ) );
+ myKey->AddL( CREATEKEY( EImpsKeyTransaction, 0 ) );
+ myKey->AddL( CREATEKEY( EImpsKeyTransactionContent, 0 ) );
+ myKey->AddL( CREATEKEY( EImpsKeyNewMessage, 0 ) );
+ myKey->AddL( CREATEKEY( EImpsKeyMessageInfo, 0 ) );
+ myKey->AddL( CREATEKEY( EImpsKeyValidity, 0 ) );
+ if ( aAc.RestoreIntegerL( myKey, validity ) )
+ {
+ aValidity = validity;
+ }
+ else
+ {
+ aValidity = KDefaultOrphanValidity;
+ }
+ CleanupStack::PopAndDestroy( ); //myKey
+ }
+
+
+TImpsEventType CImpsOrphans::ServiceType( TImpsMessageType aMessageType )
+ {
+ TImpsEventType event( EImpsEventNone );
+
+ switch ( aMessageType )
+ {
+ // IM
+ case EImpsNewMessage:
+ event = EImpsEventMessage;
+ break;
+ // Fundamental
+ case EImpsInviteUserReq:
+ event = EImpsEventCommon;
+ break;
+ default:
+ event = EImpsEventNone;
+ }
+ return event;
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
+// COrphanQueue::COrphanQueue
+// Constructor
+// -----------------------------------------------------------------------------
+//
+COrphanQueue::COrphanQueue( TInt aCapacity ):
+ iOrphanList( _FOFF( COrphan, iLink ) ), //lint !e413
+ iCapacity( aCapacity ),
+ iSize( 0 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::~COrphanQueue
+// Destructor
+// -----------------------------------------------------------------------------
+//
+COrphanQueue::~COrphanQueue()
+ {
+ TDblQueIter<COrphan> iter ( iOrphanList );
+ iter.SetToFirst();
+
+ while ( iter )
+ {
+ COrphan* orphan = iter;
+ iter++;
+ orphan->Destroy();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::SetLength
+// Sets the new capacity of the queue
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::SetLength( TInt aNewCapacity )
+ {
+ iCapacity = aNewCapacity;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::Add
+// Adds a new orphan message to the queue
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::Add( COrphan& aOrphan )
+ {
+ // Check the capacity
+ __ASSERT_DEBUG( iCapacity, User::Panic( KImpsPanicCategory, EImpsCorrupted ) );
+ if ( iSize < iCapacity )
+ {
+ // Simply add to the end
+ iOrphanList.AddLast( aOrphan );
+ ++iSize;
+ }
+ else
+ {
+ // Remove the 1st and add to the last
+ COrphan* orphan = iOrphanList.First();
+ orphan->Destroy();
+ iOrphanList.AddLast( aOrphan );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::OrphanMessage
+// Returns the orphan message with the given client ID and removes it from the
+// queue. NULL is returned if not found.
+// -----------------------------------------------------------------------------
+//
+CImpsFields* COrphanQueue::OrphanMessageLC( const TDesC& aApplicationId,
+ TImpsEventType aServiceType,
+ TImpsSessIdent aCspId )
+ {
+ TPtrC applicationId;
+ aApplicationId.Length() ? applicationId.Set( aApplicationId ) : applicationId.Set( KDefaultApplicationID );
+
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: NextOrphanLC(appID: %S, servType: %u, SAP: %S, user: %S)" ), &applicationId, aServiceType, &aCspId.SAP(), &aCspId.UserId() );
+#endif
+
+ TDblQueIter<COrphan> iter ( iOrphanList );
+ iter.SetToFirst();
+
+ while ( iter )
+ {
+ COrphan* orphan = iter;
+ iter++;
+ // Find the given ClientID, Service Type, SAP and UserId
+ if ( ( !applicationId.Compare( orphan->ApplicationId() ) ) &&
+ ( aServiceType == orphan->iServiceType ) &&
+ ( !orphan->iSap->CompareF( aCspId.SAP() ) ) &&
+ ( !orphan->iUserId->CompareF( aCspId.UserId() ) ) )
+ {
+ // found
+ // transfer the ownership to the caller
+ CImpsFields* impsFields = orphan->Message();
+ orphan->RemoveOwnership();
+ orphan->Destroy();
+ --iSize;
+ CleanupStack::PushL( impsFields );
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: NextOrphanLC(): Found! " ) );
+#endif
+ return impsFields;
+ }
+ }
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: NextOrphanLC() Not found!" ) );
+#endif
+
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::DestroyOrphans
+// Deletes all orphan messages which have the give ClientID
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::DestroyOrphans( TDesC& aApplicationId )
+ {
+ TDblQueIter<COrphan> iter ( iOrphanList );
+ iter.SetToFirst();
+
+ while ( iter )
+ {
+ COrphan* orphan = iter;
+ iter++;
+ if ( !aApplicationId.Compare( orphan->ApplicationId() ) )
+ {
+ orphan->Destroy();
+ --iSize;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::DiscardExpired
+// Deletes all orphan messages which are expired
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::DiscardExpired( TTime aExpiry )
+ {
+
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: Check expired" ) );
+#endif
+
+ TDblQueIter<COrphan> iter ( iOrphanList );
+ iter.SetToFirst();
+
+ while ( iter )
+ {
+ COrphan* orphan = iter;
+ iter++;
+ // Check the validity
+
+ if ( orphan->Expiry() < aExpiry )
+ {
+#ifndef _NO_IMPS_LOGGING_
+ CImpsClientLogger::Log( _L( "CImpsOrphans: Expired discarded" ) );
+#endif
+ orphan->Destroy();
+ --iSize;
+ }
+ }
+
+
+ }
+//////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// COrphan::COrphan
+// -----------------------------------------------------------------------------
+
+COrphan::COrphan(
+ const TDesC& aApplicationID,
+ const TDesC& aSessionId,
+ TImpsEventType aServiceType,
+ TTime aValidity,
+ CImpsFields* aFields ) :
+ iServiceType( aServiceType ),
+ iFields ( aFields ),
+ iExpiry( aValidity )
+ {
+ iCID = aApplicationID;
+ iSessionId = aSessionId;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphan::ConstructL
+// -----------------------------------------------------------------------------
+void COrphan::ConstructL(
+ const TDesC& aSap,
+ const TDesC& aUserId )
+ {
+ iSap = aSap.AllocL();
+ iUserId = aUserId.AllocL();
+ }
+
+// -----------------------------------------------------------------------------
+// COrphan::NewL
+// -----------------------------------------------------------------------------
+COrphan* COrphan::NewL(
+ const TDesC& aCID,
+ const TDesC& aSessionId,
+ TImpsEventType aServiceType,
+ const TDesC& aSap,
+ const TDesC& aUserId,
+ TTime aValidity,
+ CImpsFields* aFields )
+ {
+ COrphan* self = new ( ELeave ) COrphan( aCID, aSessionId, aServiceType, aValidity, aFields );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aSap, aUserId );
+ CleanupStack::Pop();
+
+ return self;
+
+ }
+// -----------------------------------------------------------------------------
+// COrphan::~COrphan
+// -----------------------------------------------------------------------------
+COrphan::~COrphan()
+ {
+ delete iSap;
+ delete iUserId;
+ } //lint !e1540 iFields freed in Destroy
+
+// -----------------------------------------------------------------------------
+// COrphan::Destroy
+// -----------------------------------------------------------------------------
+void COrphan::Destroy()
+ {
+ iLink.Deque();
+ delete iFields;
+ iFields = NULL;
+ delete this;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphan::ClientId
+// -----------------------------------------------------------------------------
+TDesC& COrphan::ApplicationId()
+ {
+ return iCID;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphan::Message
+// -----------------------------------------------------------------------------
+CImpsFields* COrphan::Message()
+ {
+ return iFields;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphan::Expiry
+// -----------------------------------------------------------------------------
+TTime COrphan::Expiry()
+ {
+ return iExpiry;
+ }
+
+// -----------------------------------------------------------------------------
+// COrphan::RemoveOwnership
+// -----------------------------------------------------------------------------
+void COrphan::RemoveOwnership()
+ {
+ iFields = NULL;
+ }
+
+// End of File