/*
* 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 <e32base.h> // TPriority::EPriorityHigh=20
#include <PSVariables.h>
#include <telinternalpskeys.h>
#include <telephonydomainpstypes.h>
#include <btengdomainpskeys.h>
#include <startupdomainpskeys.h>
#include <coreapplicationuisdomainpskeys.h>
#include <hwrmdomainpskeys.h>
#include <UikonInternalPSKeys.h>
#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<CPhonePubSubProxy*>
( 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<CPhonePubSubProxy*>
( 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 );
}
}
}
// End of File