diff -r 000000000000 -r ff3b6d0fd310 convergedcallengine/cce/src/ccceconferencecall.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/convergedcallengine/cce/src/ccceconferencecall.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,638 @@ +/* +* Copyright (c) 2006-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: Base class of conference call object +* +*/ + + +// INCLUDE FILES +#include "cconvergedcallprovider.h" +#include "ccceconferencecall.h" +#include "mccpconferencecall.h" +#include "mcceconferencecallobserver.h" +#include "cccepluginmanager.h" +#include "cccecallcontainer.h" +#include "cccecall.h" +#include "cccelogger.h" +#include "cccedurationtimer.h" + +// ======== MEMBER FUNCTIONS ======== +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CCCEConferenceCall::CCCEConferenceCall( + CCCECallContainer& aCallContainer, + CCCEPluginManager& aPluginManager ): + iPluginManager( aPluginManager ), + iCallContainer( aCallContainer ), + iCCEDurationTimer( NULL ) + { + } + +// --------------------------------------------------------------------------- +// Construct object +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::ConstructL() + { + iCallParameters = CCCECallParameters::NewL(); + iCCEDurationTimer = CCCEDurationTimer::NewL(); + Reset(); + } + +// --------------------------------------------------------------------------- +// Default Symbian constructor +// --------------------------------------------------------------------------- +// +CCCEConferenceCall* CCCEConferenceCall::NewL( + CCCECallContainer& aCallContainer, + CCCEPluginManager& aPluginManager ) + { + CCCEConferenceCall* self = new( ELeave ) CCCEConferenceCall( + aCallContainer, + aPluginManager ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CCCEConferenceCall::~CCCEConferenceCall() + { + Reset(); + delete iCCEDurationTimer; + delete iCallParameters; + } + +// --------------------------------------------------------------------------- +// SetObserver +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::SetObserver( + const MCCEConferenceCallObserver& aObserver ) + { + CCELOGSTRING("CCCEConferenceCall::SetObserver()"); + iObserver = const_cast( &aObserver ); + + if (iCCEDurationTimer) + { + iCCEDurationTimer->SetConferenceObserver(iObserver); + } + } + +// --------------------------------------------------------------------------- +// Release() +// +// Closes conference call +// --------------------------------------------------------------------------- +// +TInt CCCEConferenceCall::Release() + { + CCELOGSTRING("CCCEConferenceCall::Release()"); + + // Reset timer observer + iCCEDurationTimer->SetObserver( NULL ); + + Reset(); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Reset() +// +// Resets conference call +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::Reset() + { + CCELOGSTRING("CCCEConferenceCall::Reset()"); + iConferenceCaps = 1; + + iCallArray.Close(); + iState = MCCEConferenceCallObserver::ECCEConferenceIdle; + + if( iConferenceCall ) + { + TRAP_IGNORE(iPluginManager.GetPluginL( + iImplementationUid )->ReleaseConferenceCall( *iConferenceCall )); + iConferenceCall = NULL; + } + + iImplementationUid.iUid = 0; + + iCallParameters->SetServiceId( 0 ); + + if( iCCEDurationTimer ) + { + iCCEDurationTimer->Reset(); + } + } + +// --------------------------------------------------------------------------- +// State +// --------------------------------------------------------------------------- +// +MCCEConferenceCallObserver::TCCEConferenceCallState + CCCEConferenceCall::State() const + { + return iState; + } + +// --------------------------------------------------------------------------- +// ServiceId +// --------------------------------------------------------------------------- +// +TUint32 CCCEConferenceCall::ServiceId() const + { + return iCallParameters->ServiceId(); + } + +// --------------------------------------------------------------------------- +// ServiceId +// --------------------------------------------------------------------------- +// +TUid CCCEConferenceCall::ImplementationUid() const + { + return iImplementationUid; + } + +// --------------------------------------------------------------------------- +// AddCallL( const TName& aCallName ) +// +// Adds the single voice call to an existing conference call. +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::AddCallL( MCCECall& aCall ) + { + CCELOGSTRING("CCCEConferenceCall::AddCall()"); + CCCECall* call = static_cast( &aCall ); + + if( !iConferenceCall ) + { + iCallParameters->SetServiceId( call->ServiceId() ); + + //This is needed for ccecallcontainer to check conf call type + iCallParameters->SetCallType( call->CallType() ); + + iImplementationUid = call->ImplementationUid(); + + iConferenceCall = iPluginManager.GetPluginL( + call->ImplementationUid() )->NewConferenceL( ServiceId(), *this ); + + if(iConferenceCall) + { + iConferenceCall->AddCallL( &call->GetCCPCall() ); + } + else + { + User::Leave( KErrBadHandle ); + } + + } + else // Add call to current conferencecall if possible + { + iConferenceCall->AddCallL( &call->GetCCPCall() ); + } + + } + +// --------------------------------------------------------------------------- +// RemoveCallL( const TName& aCallName ) +// +// Removes the single voice call to an existing conference call. +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::RemoveCallL( MCCECall& aCall ) + { + CCELOGSTRING("CCCEConferenceCall::RemoveCallL()"); + CCCECall* call = static_cast( &aCall ); + + if( iConferenceCall ) + { + iConferenceCall->RemoveCallL( &call->GetCCPCall() ); + } + else + { + User::Leave( KErrBadHandle ); + } + + } +// --------------------------------------------------------------------------- +// IsPartOfConference() +// +// Returns ETrue if aCall is part of conference +// --------------------------------------------------------------------------- +// + +TBool CCCEConferenceCall::IsPartOfConference( CCCECall& aCall ) + { + CCELOGSTRING("CCCEConferenceCall::IsPartOfConference()"); + TBool ret = EFalse; + TInt index = iCallArray.FindInAddressOrder( &aCall ); + + if( index != KErrNotFound ) + { + ret = ETrue; + } + + return ret; + } + +// --------------------------------------------------------------------------- +// SetOngoingConferenceCall() +// +// Sets plugin created conference call +// --------------------------------------------------------------------------- +// +TInt CCCEConferenceCall::SetOngoingConferenceCall( + MCCPConferenceCall& aConferenceCall, + TUid aImplementationUid ) + { + CCELOGSTRING("CCCEConferenceCall::SetOngoingConferenceCall() IN"); + + TInt err(KErrInUse); + + if( !iConferenceCall ) + { + iConferenceCall = &aConferenceCall; + TRAP_IGNORE( iConferenceCall->AddObserverL( *this ) ); + + iConferenceCaps = + MCCEConferenceCallObserver::KCCECapsHangUp | + MCCEConferenceCallObserver::KCCECapsSwap; + + iImplementationUid = aImplementationUid; + + err = KErrNone; + + RPointerArray array; + iConferenceCall->GetCallArray( array ); + + for( TInt i = 0; i < array.Count(); i++ ) + { + const CCCECall* call = iCallContainer.GetCall( array[i] ); + + // Check if cce call matching to ccp call is available + iCallArray.Append( call ); + iCallParameters->SetServiceId( call->ServiceId() ); + + CCELOGSTRING("CCCEConferenceCall:: Call added to conferencecall"); + } + + TInt offset(0); + for (TInt a = 0; a < iCallArray.Count(); a++) + { + TInt beats = iCallArray[a]->CallDuration().Int(); + if (beats > offset) + { + offset = beats; + } + } + iCCEDurationTimer->Start(offset); + + array.Close(); + } + + CCELOGSTRING("CCCEConferenceCall::SetOngoingConferenceCall() OUT"); + return err; + } + +// --------------------------------------------------------------------------- +// EnumerateCalls() +// +// Returns the member count of the conference call. +// --------------------------------------------------------------------------- +// +TInt CCCEConferenceCall::EnumerateCalls() + { + CCELOGSTRING("CCCEConferenceCall::EnumerateCalls()"); + return iCallArray.Count(); + } + +// --------------------------------------------------------------------------- +// GetCaps() +// +// Gets the current capabilities of the conference call. +// --------------------------------------------------------------------------- +// +MCCEConferenceCallObserver::TCCEConferenceCallCaps CCCEConferenceCall::Caps() const + { + CCELOGSTRING("CCCEConferenceCall::GetCaps()"); + return (MCCEConferenceCallObserver::TCCEConferenceCallCaps)iConferenceCaps; + } + +// --------------------------------------------------------------------------- +// Parameters() const +// --------------------------------------------------------------------------- +// +const CCCPCallParameters& CCCEConferenceCall::Parameters() const + { + return *iCallParameters; + } + +// --------------------------------------------------------------------------- +// HangUp() +// +// Terminates the conference. +// --------------------------------------------------------------------------- +// +TInt CCCEConferenceCall::HangUp() + { + CCELOGSTRING("CCCEConferenceCall::HangUp()"); + iCCEDurationTimer->Stop(); + return iConferenceCall->HangUp(); + } + +// --------------------------------------------------------------------------- +// Swap() +// +// Allows a client to switch a conference call between "Active" +// and "Hold" states. +// --------------------------------------------------------------------------- +// +TInt CCCEConferenceCall::Swap() + { + CCELOGSTRING("CCCEConferenceCall::Swap()"); + return iConferenceCall->Swap(); + } + +// --------------------------------------------------------------------------- +// GoOneToOneL() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::GoOneToOneL( MCCECall& aCall ) + { + CCELOGSTRING("CCCEConferenceCall::GoOneToOne()"); + CCCECall* call = static_cast( &aCall ); + iConferenceCall->GoOneToOneL( call->GetCCPCall() ); + } + +// --------------------------------------------------------------------------- +// GetCallArray() +// --------------------------------------------------------------------------- +// +TInt CCCEConferenceCall::GetCallArray( RPointerArray& aCallArray ) + { + TInt err( KErrNotFound ); + + for (TInt a = 0; a < iCallArray.Count(); a++) + { + aCallArray.Append( iCallArray[a] ); + err = KErrNone; + } + + + return err; + } + +// --------------------------------------------------------------------------- +// ConferenceCallEventOccurred() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::ErrorOccurred( const TCCPConferenceCallError aError ) + { + CCELOGSTRING("CCCEConferenceCall::ErrorOccurred()"); + + iCallContainer.ErrorOccurred( NULL, ECCPErrorGeneral ); + + iObserver->ErrorOccurred( aError ); + } + +// --------------------------------------------------------------------------- +// ConferenceCallCapsChanged() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::ConferenceCallCapsChanged( + const TCCPConferenceCallCaps aCaps ) + { + CCELOGSTRING2( + "CCCEConferenceCall::ConferenceCallStateChanged() Caps = %d", aCaps ); + + CapsChanged( aCaps ); + } + +// --------------------------------------------------------------------------- +// ConferenceCallEventOccurred() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::ConferenceCallStateChanged( + const TCCPConferenceCallState aState ) + { + CCELOGSTRING2( + "CCCEConferenceCall::ConferenceCallStateChanged() State = %d", aState ); + TInt offset(0); + switch( aState ) + { + /** The conference call is in the idle state. */ + case ECCPConferenceIdle: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallStateChanged() ECCPConferenceIdle"); + iState = MCCEConferenceCallObserver::ECCEConferenceIdle; + DeActivate(); + iObserver->CallStateChanged( + MCCEConferenceCallObserver::ECCEConferenceIdle ); + + iCallContainer.HandleConferenceStatusChange( + MCCEConferenceCallObserver::ECCEConferenceIdle ); + + // Stop duration timer + iCCEDurationTimer->Stop(); + + break; + /** The conference call is in the active, connected state. */ + case ECCPConferenceActive: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallStateChanged() ECCPConferenceActive"); + iState = MCCEConferenceCallObserver::ECCEConferenceActive; + iObserver->CallStateChanged( + MCCEConferenceCallObserver::ECCEConferenceActive ); + iCallContainer.HandleConferenceStatusChange( + MCCEConferenceCallObserver::ECCEConferenceActive ); + + // Start call duration timer + + for (TInt a = 0; a < iCallArray.Count(); a++) + { + TInt beats = iCallArray[a]->CallDuration().Int(); + if (beats > offset) + { + offset = beats; + } + } + iCCEDurationTimer->Start(offset); + + break; + /** The conference call is in the held, connected state. */ + case ECCPConferenceHold: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallStateChanged() ECCPConferenceHold"); + iState = MCCEConferenceCallObserver::ECCEConferenceHold; + iObserver->CallStateChanged( + MCCEConferenceCallObserver::ECCEConferenceHold ); + iCallContainer.HandleConferenceStatusChange( + MCCEConferenceCallObserver::ECCEConferenceHold ); + break; + default: + break; + } + + } + +// --------------------------------------------------------------------------- +// ConferenceCallEventOccurred() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::ConferenceCallEventOccurred( + const TCCPConferenceCallEvent aEvent, + MCCPCall* aReferredCall ) + { + CCELOGSTRING2( + "CCCEConferenceCall::ConferenceCallEventOccurred() aEvent = %d", aEvent ); + CCCECall* call = NULL; + + if( aReferredCall ) + { + call = iCallContainer.GetCall( aReferredCall ); + } + + switch( aEvent ) + { + /** Conference call added. TODO, do we need call pointer with this + notification? and a existing call pointer list of the conference?*/ + case ECCPConferenceCallAdded: + + if( call ) + { + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred():CallAdded"); + iCallArray.InsertInAddressOrder( call ); + iObserver->CallEventOccurred( + MCCEConferenceCallObserver::ECCEConferenceCallAdded, call); + + iCallParameters->SetServiceId( call->ServiceId() ); + iImplementationUid = call->ImplementationUid(); + } + + break; + /** Conference call removed */ + case ECCPConferenceCallRemoved: + + if( call ) + { + TInt index = iCallArray.FindInAddressOrder( call ); + + if( index != KErrNotFound ) + { + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred():CallRemoved"); + + iCallArray.Remove( index ); + iCallArray.Compress(); + + iObserver->CallEventOccurred( + MCCEConferenceCallObserver::ECCEConferenceCallRemoved, call); + iObserver->ErrorOccurred((TCCPConferenceCallError)KErrNone); + + } + else + { + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred(): Call not found"); + } + + } + + break; + /** Names of the two calls used to build the conference call + returned in aCallName. */ + case ECCPConferenceBuilt: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred():ECCPConferenceBuilt"); + iObserver->CallEventOccurred( + MCCEConferenceCallObserver::ECCEConferenceBuilt, call); + break; + /** No name provided */ + case ECCPConferenceTerminated: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred():ECCPConferenceTerminated"); + + iObserver->CallEventOccurred( + MCCEConferenceCallObserver::ECCEConferenceTerminated, call); + break; + /** No name provided. */ + case ECCPConferenceSwapped: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred():ECCPConferenceSwapped"); + iObserver->CallEventOccurred( + MCCEConferenceCallObserver::ECCEConferenceSwapped, call); + break; + /** Name of the call being seperated. */ + case ECCPConferenceSplit: + CCELOGSTRING( + "CCCEConferenceCall::ConferenceCallEventOccurred():ECCPConferenceSplit"); + iObserver->CallEventOccurred( + MCCEConferenceCallObserver::ECCEConferenceSplit, call); + break; + default: + break; + + } + } + +// --------------------------------------------------------------------------- +// CapsChanged() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::CapsChanged( TInt aCaps ) + { + if( aCaps != iConferenceCaps ) + { + CCELOGSTRING2("CCCEConferenceCall::CapsChanged() aCaps = %d", aCaps); + iConferenceCaps = aCaps; + + iObserver->CallCapsChanged( + (MCCEConferenceCallObserver::TCCEConferenceCallCaps)iConferenceCaps ); + } + } + + +// --------------------------------------------------------------------------- +// DeActivate() +// --------------------------------------------------------------------------- +// +void CCCEConferenceCall::DeActivate() + { + CCELOGSTRING("CCCEConferenceCall::DeActivate():Conference idle"); + + iCallArray.Reset(); + + const TInt caps = MCCEConferenceCallObserver::KCCECapsCreate; // Create + CapsChanged( caps ); + } + +// --------------------------------------------------------------------------- +// CallDuration() +// --------------------------------------------------------------------------- +// +TTimeIntervalSeconds CCCEConferenceCall::CallDuration() const + { + return iCCEDurationTimer->NumberOfBeats(); + } + +// End of file