diff -r 000000000000 -r 5f000ab63145 phoneapp/phoneuiutils/src/cphonepubsubproxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phoneapp/phoneuiutils/src/cphonepubsubproxy.cpp Mon Jan 18 20:18:27 2010 +0200 @@ -0,0 +1,325 @@ +/* +* Copyright (c) 2005 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: Publish & Subscribe proxy. +* +*/ + + +// INCLUDE FILES +#include // TPriority::EPriorityHigh=20 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "phoneui.pan" +#include "phoneconstants.h" +#include "phonelogger.h" + +#include "cphonepubsubproxy.h" +#include "cphonepublishsubscriberao.h" + +// ================= MEMBER FUNCTIONS ======================= + + +// --------------------------------------------------------- +// CPhonePubSubProxy::Instance +// Initializes the singleton object +// (other items were commented in a header). +// --------------------------------------------------------- +// +EXPORT_C CPhonePubSubProxy* CPhonePubSubProxy::Instance() + { + CPhonePubSubProxy* instance = static_cast + ( CCoeEnv::Static ( KUidPubSubProxySingleton ) ); + + if ( !instance ) + { + TRAPD( err, instance = CPhonePubSubProxy::NewL() ); + if ( err ) + { + Panic( EPhoneUtilsCouldNotCreateSingleton ); + } + } + return instance; + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::CancelAllNotifications +// Cancel the notification if the singleton still exists. +// (other items were commented in a header). +// --------------------------------------------------------- +// +EXPORT_C void CPhonePubSubProxy::CancelAllNotifications( + MPhonePubSubObserver* aObserver ) + { + CPhonePubSubProxy* instance = static_cast + ( CCoeEnv::Static( KUidPubSubProxySingleton ) ); + + // Ignore the call since the singleton has already been destroyed and the + // notifications removed + if ( instance ) + { + instance->CancelAllObserverNotifies( aObserver ); + } + } + + +// --------------------------------------------------------- +// CPhonePubSubProxy::NewL +// --------------------------------------------------------- +// +CPhonePubSubProxy* CPhonePubSubProxy::NewL() + { + CPhonePubSubProxy* self = new (ELeave) CPhonePubSubProxy(); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::~CPhonePubSubProxy +// --------------------------------------------------------- +// +EXPORT_C CPhonePubSubProxy::~CPhonePubSubProxy() + { + if ( iPublishSubscriberArray ) + { + iPublishSubscriberArray->ResetAndDestroy(); + } + delete iPublishSubscriberArray; + delete iObserverArray; + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::CPhonePubSubProxy +// --------------------------------------------------------- +// +CPhonePubSubProxy::CPhonePubSubProxy() : + CCoeStatic( KUidPubSubProxySingleton, EThread ) + { + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::ConstructL +// --------------------------------------------------------- +// +void CPhonePubSubProxy::ConstructL() + { + iObserverArray = new ( ELeave ) CArrayFixFlat< TPubSubObserverTag >( + KPhonePubSubProxyObserverArrayGranularity ); + + iPublishSubscriberArray = new ( ELeave ) + CArrayPtrFlat< CPhonePublishSubscriberAO >( + KPhonePubSubArrayGranularity ); + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::Value +// --------------------------------------------------------- +// +EXPORT_C TInt CPhonePubSubProxy::Value( + const TUid& aCategory, + const TUint aKey ) + { + TInt err( KErrNone ); + TInt value( 0 ); + + err = RProperty::Get( aCategory, aKey, value ); + if ( err != KErrNone ) + { + value = err; + + __PHONELOG1( + EBasic, + EPhonePhoneapp, + "CPhonePubSubProxy::GetValue error: %d", + err ); + } + + return value; + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::NotifyChangeL +// --------------------------------------------------------- +// +EXPORT_C void CPhonePubSubProxy::NotifyChangeL( + const TUid& aCategory, + const TUint aKey, + MPhonePubSubObserver* aObserver ) + { + __ASSERT_DEBUG( aObserver, Panic( EPhoneUtilsParameterNotInitialized ) ); + __LOGMETHODSTARTEND(EPhoneUIUtils, "CPhonePubSubProxy::NotifyChangeL() "); + + // make sure this a new item in iObserverArray + TBool requestIssued = EFalse; + TBool sameRequestIssuedByObserver = EFalse; + TInt count = iObserverArray->Count(); + + // check if the request has already been issued + for ( TInt i = 0; i < count && !requestIssued; i++ ) + { + const TPubSubObserverTag& observerTag = iObserverArray->At( i ); + if ( ( observerTag.iCategory == aCategory ) && + ( observerTag.iKey == aKey ) ) + { + requestIssued = ETrue; + if ( observerTag.iObserver == aObserver ) + { + sameRequestIssuedByObserver = ETrue; + } + } + } + + // make sure the same request hasn't been issued by this observer + if ( !sameRequestIssuedByObserver ) + { + //add new observer to the array + TPubSubObserverTag newObserver; + newObserver.iCategory = aCategory; + newObserver.iKey = aKey; + newObserver.iObserver = aObserver; + iObserverArray->AppendL( newObserver ); + } + + //make sure the request hasn't been issued before + if ( !requestIssued ) + { + //issue a new request + CPhonePublishSubscriberAO* publishSubscriber = + CPhonePublishSubscriberAO::NewL( this, aCategory, aKey ); + + CleanupStack::PushL( publishSubscriber ); + iPublishSubscriberArray->AppendL( publishSubscriber ); + CleanupStack::Pop( publishSubscriber ); + + //subscribe for property change notications + publishSubscriber->Subscribe(); + } + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::ChangePropertyValue +// --------------------------------------------------------- +// +EXPORT_C void CPhonePubSubProxy::ChangePropertyValue( + const TUid& aCategory, + const TUint aKey, + const TInt aValue ) + { + TInt err( KErrNone ); + + err = RProperty::Set( aCategory, aKey, aValue ); + if ( err != KErrNone ) + { + __PHONELOG1( + EBasic, + EPhonePhoneapp, + "CPhonePubSubProxy::ChangePropertyValue error: %d", + err ); + } + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::HandlePropertyChangedL +// --------------------------------------------------------- +// +void CPhonePubSubProxy::HandlePropertyChangedL( + const TUid& aCategory, + const TUint aKey, + const TInt aValue ) + { + TInt count = iObserverArray->Count(); + for ( TInt i = 0; i < count; ) + { + // Take observer information. + TPubSubObserverTag observerTag = iObserverArray->At( i ); + + if ( ( observerTag.iCategory == aCategory ) && + ( observerTag.iKey == aKey ) ) + { + observerTag.iObserver->HandlePropertyChangedL( + aCategory, aKey, aValue ); + } + + // Update count variable - might have been modified by the + // HandlePropertyChangedL call. + count = iObserverArray->Count(); + + // If still in bounds, check if nothing changed. If so, then + // we can move to next observer. + if ( i < count ) + { + const TPubSubObserverTag& obs = iObserverArray->At( i ); + + if ( ( obs.iObserver == observerTag.iObserver ) && + ( obs.iCategory == observerTag.iCategory ) && + ( obs.iKey == observerTag.iKey ) ) + { + i++; + } + } + } + } + +// --------------------------------------------------------- +// CPhonePubSubProxy::CancelAllObserverNotifies +// --------------------------------------------------------- +// +void CPhonePubSubProxy::CancelAllObserverNotifies( + MPhonePubSubObserver* aObserver ) + { + TInt count = iObserverArray->Count(); + + // Remove the observer and its subscriptions + TBool observerRemoved = EFalse; + for( TInt i = count - 1; i >= 0 && !observerRemoved; i-- ) + { + const TPubSubObserverTag& observerTag = iObserverArray->At( i ); + if ( observerTag.iObserver == aObserver ) + { + // Remove observer + observerRemoved = ETrue; + iObserverArray->Delete( i ); + + // Remove this observers' subscriptions + TInt pubSubCount = iPublishSubscriberArray->Count(); + + for ( TInt j = pubSubCount - 1; j >= 0; j++ ) + { + CPhonePublishSubscriberAO* publishSubscriber = + iPublishSubscriberArray->At( j ); + + if ( publishSubscriber->Category() == observerTag.iCategory && + publishSubscriber->Key() == observerTag.iKey ) + { + iPublishSubscriberArray->Delete( i ); + delete publishSubscriber; + } + } + } + } + } + +// End of File +