diff -r 000000000000 -r 08ec8eefde2f featuremgmt/featuremgr/src/clientdll/featurenotifier.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/featuremgmt/featuremgr/src/clientdll/featurenotifier.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,311 @@ +// Copyright (c) 2007-2009 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: +// + + + +// INCLUDE FILES +#include +#include "featmgrdebug.h" +#include +#include "featmgrclient.h" + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// FindByUid +// Returns Zero if UIDs do match. +// ----------------------------------------------------------------------------- +// +static TInt FindByUid( const TUid* aFeature, const TUid& aItem ) + { + if ( aFeature->iUid == aItem.iUid ) + { + return 1; + } + + return 0; + } + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::CFeatureNotifier() +// ----------------------------------------------------------------------------- +// +CFeatureNotifier::CFeatureNotifier( MFeatureObserver& aObserver ) : + CActive( EPriorityStandard ), + iObserver( aObserver ) + { + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::NewL() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CFeatureNotifier* CFeatureNotifier::NewL( MFeatureObserver& aObserver ) + { + CFeatureNotifier* self = new( ELeave ) CFeatureNotifier( aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::ConstructL +// ----------------------------------------------------------------------------- +// +void CFeatureNotifier::ConstructL() + { + FUNC_LOG + + iFeatMgrClient = new (ELeave) RFeatMgrClient; + // Connect to Feature Manager server + TInt err( iFeatMgrClient->Connect() ); + User::LeaveIfError(err); + + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::~CFeatureNotifier() +// ----------------------------------------------------------------------------- +// +EXPORT_C CFeatureNotifier::~CFeatureNotifier() + { + FUNC_LOG + + if( iFeatMgrClient ) + { + iFeatMgrClient->RequestNotifyCancelAll(); + iFeatMgrClient->Close(); + delete iFeatMgrClient; + } + Cancel(); + + iFeatures.Close(); + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::NotifyRequest(TUid) +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CFeatureNotifier::NotifyRequest( TUid aFeature ) + { + if(IsActive()) + { + return KErrAlreadyExists; + } + + iFeatures.Reset(); + iFeatures.Append( aFeature ); + TInt err = iFeatMgrClient->RequestNotification( iFeatures, iFeatureChanged, iStatus ); + if ( err == KErrNone ) + { + SetActive(); + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::NotifyRequest(RFeatureUidArray&) +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CFeatureNotifier::NotifyRequest( RFeatureUidArray& aFeatures ) + { + if(IsActive()) + { + return KErrAlreadyExists; + } + + iFeatures.Reset(); + TInt count = aFeatures.Count(); + + for(TInt i = 0; i < count; i++ ) + { + // Do not append duplicate entries + const TUid& uid( aFeatures[i] ); + TInt index = iFeatures.Find( uid, FindByUid ); + if( index == KErrNotFound ) + { + iFeatures.Append( uid ); + } + } + + TInt err = iFeatMgrClient->RequestNotification( iFeatures, iFeatureChanged, iStatus ); + if ( err == KErrNone ) + { + SetActive(); + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::NotifyCancel(TUid aFeature) +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CFeatureNotifier::NotifyCancel( TUid aFeature ) + { + TInt err( KErrNotFound ); + TInt count = iFeatures.Count(); + + for(TInt i = 0; i < count; i++ ) + { + if( iFeatures[i].iUid == aFeature.iUid ) + { + err = iFeatMgrClient->RequestNotifyCancel( aFeature ); + + if( err == KErrNone ) + { + iFeatures.Remove( i ); + // If this is the last feature in the list, then also cancel the Active Object + if( 0 == iFeatures.Count() ) + { + Cancel(); + } + break; + } + } + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::NotifyCancelAll() +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CFeatureNotifier::NotifyCancelAll() + { + iFeatures.Reset(); + TInt err = iFeatMgrClient->RequestNotifyCancelAll( ); + Cancel(); + + return err; + } + +/** + Gets the number of features in the server's array. + This API is only for internal use and testing purposes. + + @return The number of features on the server for debug builds, otherwise it returns KErrNotSupported in release builds. + @internalComponent +*/ +EXPORT_C TInt CFeatureNotifier::NumberOfNotifyFeatures() + { +#ifdef EXTENDED_FEATURE_MANAGER_TEST + TInt count = iFeatMgrClient->NumberOfNotifyFeatures(); + return count; +#else + return KErrNotSupported; +#endif + } + +/** + Gets the number of heap cells in the thread. + This API is only for internal use and testing purposes. + + @return The number of heap cells for debug build, otherwise it returns KErrNotSupported in release builds. + @internalComponent +*/ +EXPORT_C TInt CFeatureNotifier::CountAllocCells() + { +#ifdef EXTENDED_FEATURE_MANAGER_TEST + TInt count = iFeatMgrClient->CountAllocCells(); + return count; +#else + return KErrNotSupported; +#endif + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::RunL() +// ----------------------------------------------------------------------------- +// +void CFeatureNotifier::RunL( ) + { + FUNC_LOG + + TInt status = iStatus.Int(); + if( status < 0 ) + { + // Got an error + if( status != KErrCancel ) + { + iObserver.HandleNotifyError( status ); + } + return; + } + + // iStatus >= 0 means it contains the change type + TFeatureChangeType changeType = static_cast(status); + + // If the feature was deleted, remove it from the array of features with notifications requested + if( changeType == EFeatureFeatureDeleted ) + { + TInt index = iFeatures.Find( iFeatureChanged, FindByUid ); + if( index != KErrNotFound ) + { + iFeatures.Remove( index ); + } + } + // Should we validate whether iFeatureChanged matches + // to any UID in the array of requested features? + + TFeatureEntry feature( iFeatureChanged ); + if( iFeatures.Count() > 0 ) + { + // Asynchronously resubscribe notify request + iFeatMgrClient->ReRequestNotification( iFeatureChanged, iStatus ); + // Next inform client about changed feature + // Should we validate whether iFeatureChanged matches + // to any UID in the array of requested features + iObserver.HandleNotifyChange( changeType, feature ); + // Set us active + SetActive(); + } + else + { + // All features with notifications requested were deleted, + // so don't need to resubscribe notify request - + // just notify client about the deleted feature + iObserver.HandleNotifyChange( changeType, feature ); + } + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::DoCancel() +// ----------------------------------------------------------------------------- +// +void CFeatureNotifier::DoCancel( ) + { + } + +// ----------------------------------------------------------------------------- +// CFeatureNotifier::RunError() +// ----------------------------------------------------------------------------- +// +TInt CFeatureNotifier::RunError( TInt aError ) + { + iObserver.HandleNotifyError( aError ); + + return KErrNone; + } + +// End of File