diff -r 000000000000 -r a4daefaec16c convergedconnectionhandler/cchclientapi/src/cchclientobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/convergedconnectionhandler/cchclientapi/src/cchclientobserver.cpp Mon Jan 18 20:12:36 2010 +0200 @@ -0,0 +1,334 @@ +/* +* 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: Cch client api +* +*/ + + +// INCLUDE FILES +#include "cchimpl.h" +#include "cchclientobserver.h" +#include "cchlogger.h" +#include "cchserviceimpl.h" +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +// None + +// MACROS +// None + +// LOCAL CONSTANTS AND MACROS +// None + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +// None + +// FORWARD DECLARATIONS +// None + +// ============================= LOCAL FUNCTIONS ============================= + +// ============================ MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------------------------- +// CCchClientObserver::CCchClientObserver +// C++ default constructor can NOT contain any code, that might leave. +// --------------------------------------------------------------------------- +// +CCchClientObserver::CCchClientObserver( CCchServiceImpl& aCchService ) +: CActive ( EPriorityStandard ) +, iCchService( aCchService ) +, iBackwardSupportObserver( NULL ) + { + CActiveScheduler::Add( this ); + } + +CCchClientObserver::~CCchClientObserver() + { + iObservers.Reset(); + + Cancel(); + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::ConstructL +// Symbian 2nd phase constructor can leave. +// --------------------------------------------------------------------------- +// +void CCchClientObserver::ConstructL() + { + CCHLOGSTRING( "CCchClientObserver::ConstructL: IN" ); + + CCHLOGSTRING( "CCchClientObserver::ConstructL: OUT" ); + } +// --------------------------------------------------------------------------- +// CCchClientObserver::NewL +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CCchClientObserver* CCchClientObserver::NewL( CCchServiceImpl& aCchService ) + { + CCHLOGSTRING( "CCchClientObserver::NewL: IN" ); + CCchClientObserver* self = + CCchClientObserver::NewLC( aCchService ); + CleanupStack::Pop( self ); + CCHLOGSTRING( "CCchClientObserver::NewL: OUT" ); + return self; + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::NewLC +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CCchClientObserver* CCchClientObserver::NewLC( CCchServiceImpl& aCchService ) + { + CCHLOGSTRING( "CCchClientObserver::NewLC: IN" ); + CCchClientObserver* self = + new (ELeave) CCchClientObserver( aCchService ); + CleanupStack::PushL( self ); + self->ConstructL(); + CCHLOGSTRING( "CCchClientObserver::NewLC: OUT" ); + return self; + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::SetObserver +// --------------------------------------------------------------------------- +// +void CCchClientObserver::SetObserver( MCchServiceStatusObserver& aObserver ) + { + CCHLOGSTRING( "CCchClientObserver::SetObserver: IN - deprecated use AddObserver" ); + + // This is for old API user support remove this when all are using new API + if( iBackwardSupportObserver ) + { + // remove existing observer + CCHLOGSTRING( "CCchClientObserver::SetObserver: removing old observer" ); + RemoveObserver(); + } + + CCHLOGSTRING( "CCchClientObserver::SetObserver: adding new observer" ); + // This is for old API user support remove this when all are using new API + AddObserver( aObserver ); + iBackwardSupportObserver = &aObserver; + + CCHLOGSTRING( "CCchClientObserver::SetObserver: OUT" ); + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::RemoveObserver +// --------------------------------------------------------------------------- +// +void CCchClientObserver::RemoveObserver( ) + { + CCHLOGSTRING( "CCchClientObserver::RemoveObserver: IN - deprecated use the one with parameter" ); + + if( iBackwardSupportObserver ) + { + // remove using observer set in SetObserver. This is for old API user support + // remove this when all are using new API + RemoveObserver( *iBackwardSupportObserver ); + iBackwardSupportObserver = NULL; + } + + CCHLOGSTRING( "CCchClientObserver::RemoveObserver: OUT" ); + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::AddObserver +// --------------------------------------------------------------------------- +// +TInt CCchClientObserver::AddObserver( + MCchServiceStatusObserver& aObserver ) + { + CCHLOGSTRING2( "CCchClientObserver::AddObserver: IN count=%d", iObservers.Count() ); + + TInt index = iObservers.Find( &aObserver ); + + // Insert if not already observing + if ( index == KErrNotFound ) + { + CCHLOGSTRING( "CCchClientObserver::AddObserver: observer added" ); + iObservers.Append( &aObserver ); + } + else + { + CCHLOGSTRING( "CCchClientObserver::AddObserver: observer KErrAlreadyExists" ); + return KErrAlreadyExists; + } + + if ( iObservers.Count() ) + { + if ( !IsActive() ) + { + iCchService.CchImpl()->CchClient().SubscribeToEvents( + TServiceSelection( iCchService.ServiceId(), ECCHUnknown ), + iServiceStatus, + iStatus ); + + CCHLOGSTRING( "CCchClientObserver::AddObserver: setting active" ); + + SetActive(); + } + + CCHLOGSTRING( "CCchClientObserver::AddObserver: subscrbing to events" ); + + } + else + { + CCHLOGSTRING( "CCchClientObserver::AddObserver: already subscribed subscrbing to events - skipping" ); + } + + CCHLOGSTRING2( "CCchClientObserver::AddObserver: OUT count=%d", iObservers.Count() ); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::RemoveObserver +// --------------------------------------------------------------------------- +// +TInt CCchClientObserver::RemoveObserver( + MCchServiceStatusObserver& aObserver ) + { + CCHLOGSTRING( "CCchClientObserver::RemoveObserver: IN" ); + CCHLOGSTRING2( "CCchClientObserver::RemoveObserver IN: COUNT=%d", iObservers.Count() ); + + TInt index = iObservers.Find( &aObserver ); + + if ( index == KErrNotFound ) + { + CCHLOGSTRING("CCchClientObserver::RemoveObserver - observer NOT found KErnotFound returned" ); + return KErrNotFound; + } + else + { + CCHLOGSTRING( "CCchClientObserver::RemoveObserver: removing observer" ); + + // Observer found. + iObservers.Remove( index ); + iObservers.Compress(); + + // Cancel subcribe to events and free up memory. + if ( !iObservers.Count() ) + { + CCHLOGSTRING( "CCchClientObserver::RemoveObserver: unsubscrbing from events" ); + iCchService.CchImpl()->CchClient().SubscribeToEventsCancel( ); + iObservers.Reset(); + } + } + + CCHLOGSTRING2( "CCchClientObserver::RemoveObserver OUT: COUNT=%d", iObservers.Count() ); + + CCHLOGSTRING( "CCchClientObserver::RemoveObserver: OUT" ); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::DoCancel +// --------------------------------------------------------------------------- +// +void CCchClientObserver::DoCancel() + { + CCHLOGSTRING( "CCchClientObserver::DoCancel: IN" ); + + CCHLOGSTRING( "CCchClientObserver::DoCancel: OUT" ); + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::RunL +// --------------------------------------------------------------------------- +// +void CCchClientObserver::RunL() + { + TServiceStatus serviceStatus = iServiceStatus(); + CCHLOGSTRING( "CCchClientObserver::RunL: IN" ); + + //if someone is observing and correct service is changed + if ( iObservers.Count() && ( serviceStatus.ServiceId() == iCchService.ServiceId() ) ) + { + TCchServiceStatus status; + + status.SetError( serviceStatus.iError ); + status.SetState( serviceStatus.iState ); + + CCHLOGSTRING2( "CCchClientObserver::RunL: count=%d", iObservers.Count() ); + + // If observer array can change while iterating it add support for that. + // Then there is a need to iterate starting from beginning until done and save + // already notified observers etc + TInt count( iObservers.Count() ); + + for( TInt i=0; i < count; i++ ) + { + CCHLOGSTRING2( "CCchClientObserver::RunL: looping observers: %d", i ); + + // If some client removes observer in middle of iteration start from beginning of array again. + if ( count > iObservers.Count() ) + { + CCHLOGSTRING( "CCchClientObserver::RunL: Start from beginning of array" ); + + i = 0; + count = iObservers.Count(); + } + + if( iObservers[ i ] ) + { + CCHLOGSTRING2( "CCchClientObserver::RunL: send service status changed to client: %d", i ); + iObservers[ i ]->ServiceStatusChanged( iCchService.ServiceId(), + serviceStatus.Type(), status ); + } + } + } + + if ( iObservers.Count() ) + { + if ( !IsActive() ) + { + CCHLOGSTRING( "CCchClientObserver::RunL: Subscribing " ); + iCchService.CchImpl()->CchClient().SubscribeToEvents( + TServiceSelection( iCchService.ServiceId(), ECCHUnknown ), + iServiceStatus, + iStatus ); + + CCHLOGSTRING( "CCchClientObserver::RunL: Setting active" ); + SetActive(); + } + } + + + CCHLOGSTRING( "CCchClientObserver::RunL: OUT" ); + } + +// --------------------------------------------------------------------------- +// CCchClientObserver::RunError +// --------------------------------------------------------------------------- +// +TInt CCchClientObserver::RunError( TInt /*aError*/ ) + { + CCHLOGSTRING( "CCchClientObserver::RunError: IN OUT" ); + return KErrNone; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File