diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/cfserver/CFContextManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/cfserver/CFContextManager.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,930 @@ +/* +* Copyright (c) 2002-2008 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: CCFContextManager class implementation. +* +*/ + + +#include + +#include "CFContextManager.h" +#include "CFContextQueryImpl.h" +#include "CFContextObjectImpl.h" +#include "cfcontextsubscriptionlistener.h" +#include "CFContextSubscriptionImpl.h" +#include "CFCacheElement.h" +#include "cfutils.h" +#include "cftrace.h" +#include "CFContextDataProxy.h" +#include "cfcommon.h" + +// Public Constructors and destructors +CCFContextManager* CCFContextManager::NewL( + MCFSecurityChecker& aSecurityChecker ) + { + FUNC_LOG; + + CCFContextManager* self = CCFContextManager::NewLC( aSecurityChecker ); + CleanupStack::Pop(self); + + return self; + } + +CCFContextManager* CCFContextManager::NewLC( + MCFSecurityChecker& aSecurityChecker ) + { + FUNC_LOG; + + CCFContextManager* self + = new (ELeave) CCFContextManager( aSecurityChecker ); + CleanupStack::PushL(self); + self->ConstructL(); + + return self; + } + +CCFContextManager::~CCFContextManager() + { + FUNC_LOG; + + iCleanupCacheElements.Close(); + iContextCache.ResetAndDestroy(); + iContextCache.Close(); + delete iPreviousContext; + delete iCacheOrder; + delete iCacheSearchKey; + + iSubscriptions.ResetAndDestroy(); + } + +CCFContextManager::CCFContextManager( MCFSecurityChecker& aSecurityChecker ) + { + FUNC_LOG; + + iSecurityChecker = &aSecurityChecker; + } + +void CCFContextManager::ConstructL() + { + FUNC_LOG; + + iCacheOrder = new (ELeave) TLinearOrder + (CCFCacheElement::CompareByTypeAndSource); + + iCacheSearchKey = CCFCacheElement::NewL(); + + iPreviousContext = CCFContextObject::NewL(); + } + +// METHODS + +//----------------------------------------------------------------------------- +// CCFContextManager::PublishContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::PublishContextL( CCFContextObject &aContext, + RThread& aClientThread ) + { + FUNC_LOG; + + ValidatePublishContextL( aContext, aClientThread ); + DoPublishContextL( aContext ); + } + +//----------------------------------------------------------------------------- +// CCFContextManager::PublishContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::PublishContextL( CCFContextObject &aContext, + RThread& aClientThread, + CCFContextDataObject& aData ) + { + FUNC_LOG; + + ValidatePublishContextL( aContext, aClientThread ); + DoPublishContextL( aContext, &aData ); + } + +//----------------------------------------------------------------------------- +// CCFContextManager::RequestContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::RequestContextL( RContextObjectArray& aResultBuffer, + CCFContextQuery& aContextQuery, + RThread& aClientThread ) + { + FUNC_LOG; + + // Accessing the context cache for the latest context values is enough + DoRequestContextL( aResultBuffer, aContextQuery, &aClientThread ); + } + + +//----------------------------------------------------------------------------- +// CCFContextManager::RequestContextL +//----------------------------------------------------------------------------- +// +CCFContextObject* CCFContextManager::RequestContextL( const TDesC& aContextType, + const TDesC& aContextSource, + RThread& aClientThread ) + { + FUNC_LOG; + + // check the cache + iCacheSearchKey->Context().SetTypeL( aContextType ); + iCacheSearchKey->Context().SetSourceL( aContextSource ); + TInt index = KErrNone; + if( iContextCache.FindInOrder( iCacheSearchKey, index, + *iCacheOrder ) == KErrNone ) + { + // index points to the matching object + if( index >= 0 && index < iContextCache.Count() ) + { + User::LeaveIfError( DoReadSecurityCheck( + *iContextCache[index], + aClientThread ) ); + return &iContextCache[index]->Context(); + } + else + { + return NULL; + } + } + else // == KErrNotFound + { // index points to "the place to be" + return NULL; + } + } + +//----------------------------------------------------------------------------- +// CCFContextManager::SubscriptionAddedL +//----------------------------------------------------------------------------- +// +void CCFContextManager::SubscriptionAddedL( + CCFContextSubscriptionImpl& aSubscription, + RThread& aClientThread ) + { + FUNC_LOG; + + TInt count = iContextCache.Count(); + CCFCacheElement* element = NULL; + for( TInt i = 0; i < count; i++ ) + { + element = iContextCache[i]; + if( aSubscription.Matches( element->Context().Type(), + element->Context().Source() ) ) + { + TInt err = DoReadSecurityCheck( *element, aClientThread ); + if (err == KErrNone) + { + element->AddSubscriptionL( aSubscription ); + } + else + { + aSubscription.SubscriptionListener().HandleContextSubscriptionError( err, + element->Context().Source(), + element->Context().Type() ); + } + } + } + } + +//----------------------------------------------------------------------------- +// CCFContextManager::SubscriptionRemoved +//----------------------------------------------------------------------------- +// +TBool CCFContextManager::SubscriptionRemoved( + CCFContextSubscriptionImpl& aSubscription) + { + FUNC_LOG; + + TBool cleanupElement( EFalse ); + for( TInt i = 0; i < iContextCache.Count(); i++ ) + { + TInt j = iContextCache[ i ]->Subscriptions().Count() - 1; + for( ; j >= 0; j-- ) + { + if( &aSubscription == iContextCache[ i ]->Subscriptions()[ j ] ) + { + CCFCacheElement* cacheElement = iContextCache[ i ]; + if ( iPublishingForCacheElement + && ( iPublishingForCacheElement == cacheElement ) ) + { + cleanupElement = ETrue; + cacheElement->NullifySubscription( j ); + TInt err = iCleanupCacheElements.InsertInAddressOrder( + cacheElement ); + if ( err == KErrAlreadyExists ) + { + err = KErrNone; + } + ERROR( err, "CCFContextManager::SubscriptionRemoved - Adding cache element to cleanup array failed!" ); + } + else + { + cacheElement->RemoveSubscription( j ); + } + } + } + } + + return cleanupElement; + } + + +//---------------------------------------------------------------------------- +// CCFContextManager::DefineContextL +//---------------------------------------------------------------------------- +// +void CCFContextManager::DefineContextL( const TDesC& aContextSource, + const TDesC& aContextType, + const TSecurityPolicy& aReadSecurityPolicy, + const TSecurityPolicy& aWriteSecurityPolicy ) + { + FUNC_LOG; + + RThread thread; + CleanupClosePushL( thread ); + + DefineContextL( aContextSource, aContextType, aReadSecurityPolicy, + aWriteSecurityPolicy, NULL, thread.SecureId() ); + + CleanupStack::PopAndDestroy( ); + } + + +//---------------------------------------------------------------------------- +// CCFContextManager::DefineContextL +//---------------------------------------------------------------------------- +// +void CCFContextManager::DefineContextL( const TDesC& aContextSource, + const TDesC& aContextType, + const TSecurityPolicy& aReadSecurityPolicy, + const TSecurityPolicy& aWriteSecurityPolicy, + MCFContextSource* aContextPublisher, + const TUid& aPublisherUid ) + { + FUNC_LOG; + + // Prepare and find context + iCacheSearchKey->Context().SetSourceL( aContextSource ); + iCacheSearchKey->Context().SetTypeL( aContextType ); + iCacheSearchKey->Context().SetValueL( KNullDesC ); + iCacheSearchKey->SetReadSecurityPolicy( aReadSecurityPolicy ); + iCacheSearchKey->SetWriteSecurityPolicy( aWriteSecurityPolicy ); + iCacheSearchKey->SetContextPublisher( aContextPublisher, aPublisherUid ); + + TInt index = KErrNone; + TInt searchError = iContextCache.FindInOrder( iCacheSearchKey, + index, + *iCacheOrder ); + + if ( searchError != KErrNone ) + { + // New context type + User::LeaveIfError( + iContextCache.Insert( iCacheSearchKey, index ) ); + CacheElementAddedL( *iCacheSearchKey ); + iCacheSearchKey = NULL; + iCacheSearchKey = CCFCacheElement::NewL(); + + // Signalling new context type + iPreviousContext->SetSourceL( KNullDesC ); + iPreviousContext->SetTypeL( KNullDesC ); + + INFO_2( "New context defined: [%S: %S]", + &aContextSource, + &aContextType ); + } + else + { + TInt err = KErrNone; + CCFCacheElement* cacheElement = iContextCache[index]; + if( cacheElement->PublisherUid() == aPublisherUid ) + { + if( RedefineAllowed( *cacheElement, aContextPublisher, aPublisherUid ) ) + { + cacheElement->SetContextPublisher( aContextPublisher, + aPublisherUid ); + INFO_3( "Context [%S: %S] redefined by client [%x]", + &aContextSource, &aContextType, aPublisherUid.iUid ); + } + else + { + err = KErrAlreadyExists; + } + } + else + { + err = KErrAlreadyExists; + } + + ERROR_2( err, "Context already defined: [%S: %S]", + &aContextSource, + &aContextType ); + User::LeaveIfError( err ); + } + } + + +//----------------------------------------------------------------------------- +// CCFContextManager::GetReadSecurityPolicyL +//----------------------------------------------------------------------------- +// +void CCFContextManager::GetReadSecurityPolicyL( const TDesC& aContextSource, + const TDesC& aContextType, + TSecurityPolicy& aPolicy ) + { + FUNC_LOG; + + TInt count = iContextCache.Count(); + CCFCacheElement* cacheElement = NULL; + for( TInt i = 0; i < count; i++ ) + { + cacheElement = iContextCache[ i ]; + + if( cacheElement->Context().Source().Compare( aContextSource ) == 0 + && cacheElement->Context().Type().Compare( aContextType ) == 0 ) + { + aPolicy = cacheElement->GetReadSecurityPolicy(); + return; + } + } + + ERROR_2( KErrNotFound, "Security Policy for [%S: %S] not found!", + &aContextSource, &aContextType ); + User::Leave( KErrNotFound ); + } + +//----------------------------------------------------------------------------- +// CCFContextManager::GetWriteSecurityPolicyL +//----------------------------------------------------------------------------- +// +void CCFContextManager::GetWriteSecurityPolicyL( const TDesC& aContextSource, + const TDesC& aContextType, + TSecurityPolicy& aPolicy ) + { + FUNC_LOG; + + TInt count = iContextCache.Count(); + CCFCacheElement* cacheElement = NULL; + for( TInt i = 0; i < count; i++ ) + { + cacheElement = iContextCache[ i ]; + + if( cacheElement->Context().Source().Compare( aContextSource ) == 0 + && cacheElement->Context().Type().Compare( aContextType ) == 0 ) + { + aPolicy = cacheElement->GetWriteSecurityPolicy(); + return; + } + } + + ERROR_2( KErrNotFound, "Security Policy for [%S: %S] not found!", + &aContextSource, &aContextType ); + User::Leave( KErrNotFound ); + } + + +//----------------------------------------------------------------------------- +// CCFContextManager::DeregisterPublisher +//----------------------------------------------------------------------------- +// +void CCFContextManager::DeregisterPublisher( MCFContextSource& aPublisher ) + { + FUNC_LOG; + + for( TInt i = 0; i < iContextCache.Count() ; i++ ) + { + CCFCacheElement* cacheElement = iContextCache[ i ]; + if( cacheElement->ContextPublisher() == &aPublisher ) + { + cacheElement->SetContextPublisher( NULL ); + } + } + } + + +//----------------------------------------------------------------------------- +// CCFContextManager::GetLatestFromCacheL +//----------------------------------------------------------------------------- +// +void CCFContextManager::GetLatestFromCacheL( + RContextObjectArray& aLatestContexts, + queryMatchFunction aMatchFunction, + const CCFContextQueryImpl& aContextQuery, + RThread* aClientThread ) + { + FUNC_LOG; + + TInt count = iContextCache.Count(); + CCFCacheElement* cacheElement = NULL; + for( TInt i = 0; i < count; ++i ) + { + cacheElement = iContextCache[ i ]; + if( cacheElement->Context().Value().Length() + && ( aContextQuery.*aMatchFunction )( + cacheElement->Context().Type(), + cacheElement->Context().Source() ) ) + { + if( !aClientThread || + DoReadSecurityCheck( *cacheElement, *aClientThread ) == KErrNone ) + { + aLatestContexts.AppendL( &cacheElement->Context() ); + } + } + } + } + +//----------------------------------------------------------------------------- +// CCFContextManager::LogContextCache +//----------------------------------------------------------------------------- +// +void CCFContextManager::LogContextCache() + { +#ifdef DEBUG_LOG_CONTEXT_CACHE + INFO( "CONTEXT CACHE start:" ); + TInt cacheIndex; + for (cacheIndex = 0; cacheIndex < iContextCache.Count(); ++cacheIndex) + { + iContextCache[cacheIndex]->DebugPrintContents(); + } + INFO( "CONTEXT CACHE start:" ); + INFO( "CONTEXT CACHE BY TYPE start:" ); + for (cacheIndex = 0; cacheIndex < iContextCacheByType.Count() ; + ++cacheIndex) + { + iContextCacheByType[cacheIndex]->DebugPrintContents(); + } + INFO( "CONTEXT CACHE BY TYPE end:" ); +#endif // DEBUG_LOG_CONTEXT_CACHE + } + +//----------------------------------------------------------------------------- +// CCFContextManager::DoSecurityCheck +//----------------------------------------------------------------------------- +// +TInt CCFContextManager::DoReadSecurityCheck( CCFCacheElement& aContextCache, + RThread& aClientThread ) + { + FUNC_LOG; + + // Security check only needed if request is from other process than CF + TInt err = KErrNone; + + TBool securityCheckOk = + iSecurityChecker->CheckClientSecurity( aClientThread, + aContextCache.GetReadSecurityPolicy() ); + + if( !securityCheckOk ) + { + // Insuffcient security, indicate client + err = KErrAccessDenied; + } + + return err; + } + +//----------------------------------------------------------------------------- +// CCFContextManager::DoSecurityCheck +//----------------------------------------------------------------------------- +// +TInt CCFContextManager::DoWriteSecurityCheck( CCFCacheElement& aContextCache, + RThread& aClientThread ) + { + FUNC_LOG; + + // Security check only needed if request is from other process than CF + TInt err = KErrNone; + + TBool securityCheckOk = + iSecurityChecker->CheckClientSecurity( aClientThread, + aContextCache.GetWriteSecurityPolicy() ); + + if( !securityCheckOk ) + { + // Insuffcient security, indicate client + err = KErrAccessDenied; + } + + return err; + } + + +//----------------------------------------------------------------------------- +// CCFContextManager::DoRequestContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::DoRequestContextL( RContextObjectArray& aResultBuffer, + CCFContextQuery& aContextQuery, + RThread* aClientThread ) + { + FUNC_LOG; + + CCFContextQueryImpl& queryImpl = (CCFContextQueryImpl&) aContextQuery; + GetLatestFromCacheL( aResultBuffer, + &CCFContextQueryImpl::Matches, + queryImpl, + aClientThread ); + } + +//----------------------------------------------------------------------------- +// CCFContextManager::SubscribeContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::SubscribeContextL( + CCFContextSubscription* aSubscription, + MCFContextSubscriptionListener* aListener, + RThread& aClientThread ) + { + FUNC_LOG; + + CCFContextSubscriptionImpl* subscriptionImpl = + static_cast( aSubscription ); + subscriptionImpl->SetSubscriptionListener( *aListener ); + + // Append new subscription into array + TInt err = iSubscriptions.Append( subscriptionImpl ); + if( err != KErrNone ) + { + User::Leave( err ); + } + + // Notify data manager that new subscription has been added + TRAP( err, + SubscriptionAddedL( *subscriptionImpl, aClientThread ) ); + if( err ) + { + iSubscriptions.Remove( iSubscriptions.Count() -1 ); + User::Leave( err ); + } + } + +//----------------------------------------------------------------------------- +// CCFContextManager::RemoveSubscription +//----------------------------------------------------------------------------- +// +TBool CCFContextManager::RemoveSubscription( + CCFContextSubscription& aSubscription, + MCFContextSubscriptionListener& aListener ) + { + FUNC_LOG; + + TBool cleanupElement( EFalse ); + CCFContextSubscriptionImpl* subscriptionImpl = + static_cast( &aSubscription ); + + subscriptionImpl->SetSubscriptionListener( aListener ); + TBool deleteSubscriptionImpl( EFalse ); + + TInt i = iSubscriptions.Count() - 1; + while ( i >= 0 ) + { + if ( i >= iSubscriptions.Count() ) + { + // Context source has removed subscriptions via synchronous call + // e.g. from managers call to source's NoSubscribers() function. + i = iSubscriptions.Count() - 1; + } + + if ( i < 0 ) + { + INFO( "All subscriptions removed" ); + break; + } + + if ( iSubscriptions[ i ]->IsSame( *subscriptionImpl ) ) + { + CCFContextSubscriptionImpl* subscription = iSubscriptions[ i ]; + iSubscriptions.Remove( i ); + INFO_2( "CCFContextManager::RemoveSubscription - Subscription [%S: %S] removed", + &subscription->ContextSource(), + &subscription->ContextType() ); + if ( SubscriptionRemoved( *subscription ) ) + { + cleanupElement = ETrue; + } + if ( subscription != subscriptionImpl ) + { + delete subscription; + } + else + { + // Delay deleting when the same subscription instance is used + // internally for both subscribe and unsubscribe. + deleteSubscriptionImpl = ETrue; + } + } + --i; + } + + if ( deleteSubscriptionImpl ) + { + delete subscriptionImpl; + } + + return cleanupElement; + } + +//----------------------------------------------------------------------------- +// CCFContextManager::RemoveSubscription +//----------------------------------------------------------------------------- +// +TBool CCFContextManager::RemoveSubscriptions( + MCFContextSubscriptionListener* aListener) + { + FUNC_LOG; + + TBool cleanupElement( EFalse ); + + TInt i = iSubscriptions.Count() - 1; + while ( i >= 0 ) + { + if ( i >= iSubscriptions.Count() ) + { + // Context source has removed subscriptions via synchronous call + // e.g. from managers call to source's NoSubscribers() function. + i = iSubscriptions.Count() - 1; + } + + if ( i < 0 ) + { + INFO( "All subscriptions removed" ); + break; + } + + CCFContextSubscriptionImpl* subscription = iSubscriptions[ i ]; + if ( &( subscription->SubscriptionListener() ) == aListener ) + { + iSubscriptions.Remove( i ); + if ( SubscriptionRemoved( *subscription ) ) + { + cleanupElement = ETrue; + } + delete subscription; + subscription = NULL; + } + --i; + } + + return cleanupElement; + } + +//----------------------------------------------------------------------------- +// CCFContextManager::CleanupCacheElementSubscriptions +//----------------------------------------------------------------------------- +// +void CCFContextManager::CleanupCacheElementSubscriptions() + { + FUNC_LOG; + + for ( TInt i = 0; i < iCleanupCacheElements.Count(); ++i ) + { + CCFCacheElement* element = iCleanupCacheElements[ i ]; + element->RemoveNullSubscriptions(); + } + iCleanupCacheElements.Reset(); + } + +//----------------------------------------------------------------------------- +// CCFContextManager::CacheElementAddedL +//----------------------------------------------------------------------------- +// +void CCFContextManager::CacheElementAddedL( + CCFCacheElement& aCacheElement ) + { + FUNC_LOG; + + TInt count = iSubscriptions.Count(); + CCFContextSubscriptionImpl* subscription = NULL; + for( TInt i = 0; i < count; i++ ) + { + subscription = iSubscriptions[i]; + if( subscription->Matches( aCacheElement.Context().Type(), + aCacheElement.Context().Source() ) ) + { + // Check security + RThread thread; + TInt err = + subscription->SubscriptionListener().Client( thread ); + if( err == KErrNone ) + { + err = DoReadSecurityCheck( aCacheElement, thread ); + if( err == KErrNone ) + { + aCacheElement.AddSubscriptionL( *subscription ); + } + else + { + subscription->SubscriptionListener().HandleContextSubscriptionError( + err, + aCacheElement.Context().Source(), + aCacheElement.Context().Type() ); + } + } + else + { + subscription->SubscriptionListener().HandleContextSubscriptionError( + err, + aCacheElement.Context().Source(), + aCacheElement.Context().Type() ); + } + thread.Close(); + } + } + } + +//----------------------------------------------------------------------------- +// CCFContextManager::ValidatePublishContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::ValidatePublishContextL( CCFContextObject& aContext, + RThread& aClientThread ) + { + FUNC_LOG; + + // Define context + iCacheSearchKey->Context().CopyL( aContext ); + CCFCacheElement* currentCacheElement = iCacheSearchKey; + TInt index = KErrNone; + TInt searchError = iContextCache.FindInOrder( iCacheSearchKey, + index, + *iCacheOrder); + + // Both source and type must match. + // Otherwise context has not been defined and will lead to error. + if( searchError == KErrNone ) + { + if( index >= 0 && index < iContextCache.Count() ) + { + // index and indexByType points to the matching cache elements + currentCacheElement = iContextCache[index]; + } + else + { + // index not found -> leave + ERROR_GEN( "Context cache element not found from cache list" ); + User::Leave( KErrNotFound ); + } + + // Perform security check + TInt err = DoWriteSecurityCheck( *currentCacheElement, aClientThread ); + ERROR_2( err, "Security check failed: [%S: %S]", + &aContext.Source(), + &aContext.Type() ); + User::LeaveIfError( err ); + } + else + { + // Indicate client that specified context cannot be found + ERROR_2( KErrNotFound, "Published context not found: [%S: %S]", + &aContext.Source(), + &aContext.Type() ); + User::Leave( KErrNotFound ); + } + } + +//----------------------------------------------------------------------------- +// CCFContextManager::DoPublishContextL +//----------------------------------------------------------------------------- +// +void CCFContextManager::DoPublishContextL( CCFContextObject& aContext, + CCFContextDataObject* aData ) + { + FUNC_LOG; + + // Define context + aContext.SetTimestampToHomeTime(); + iCacheSearchKey->Context().CopyL( aContext ); + CCFCacheElement* currentCacheElement = iCacheSearchKey; + TBool valueChanged = EFalse; + TInt index = KErrNone; + TInt searchError = iContextCache.FindInOrder( iCacheSearchKey, + index, + *iCacheOrder); + + // Both source and type must match. + // Otherwise context has not been defined and will lead to error. + if( searchError == KErrNone ) + { + if( index >= 0 && index < iContextCache.Count() ) + { + // index and indexByType points to the matching cache elements + currentCacheElement = iContextCache[ index ]; + } + else + { + // index not found -> leave + ERROR( KErrNotFound, "Context cache element not found from cache list" ); + User::Leave( KErrNotFound ); + } + + // store previous values + iPreviousContext->CopyL( currentCacheElement->Context() ); + + // Check if we have to update cache and indicate subscribers + if( currentCacheElement->Context().Value() != aContext.Value() ) + { + // Update context + currentCacheElement->Context().CopyL( aContext ); + valueChanged = ETrue; + } + + LogContextCache(); + + // Let subscriptions do the indication if needed + iPublishingForCacheElement = currentCacheElement; + const RPointerArray< CCFContextSubscriptionImpl >& subscriptions = + currentCacheElement->Subscriptions(); + TInt count = subscriptions.Count(); + CCFContextSubscriptionImpl* subscription = NULL; + for( TInt i = 0 ; i < count; i++ ) + { + subscription = subscriptions[ i ]; + if( subscription ) + { + if( aData && subscription->DataObjectEnabled() ) + { + subscription->EvaluateContextChangeL( aContext, + *aData, + valueChanged ); + } + else + { + subscription->EvaluateContextChangeL( aContext, + *iPreviousContext, + valueChanged ); + } + } + } + iPublishingForCacheElement = NULL; + + INFO_3( "Published context: [%S: %S: %S]", + &aContext.Source(), + &aContext.Type(), + &aContext.Value() ); + if( aData ) + { + INFO_1( "Published data object: [0x%x]", aData->Uid() ); + } + } + else + { + // Indicate client that specified context cannot be found + ERROR_2( KErrNotFound, "Published context not found: [%S: %S]", + &aContext.Source(), + &aContext.Type() ); + User::Leave( KErrNotFound ); + } + } + +//------------------------------------------------------------------------------ +// CCFContextManager::RedefineAllowed +//------------------------------------------------------------------------------ +// +TBool CCFContextManager::RedefineAllowed( CCFCacheElement& aElement, + const MCFContextSource* aSource, + const TUid& aUid ) const + { + FUNC_LOG; + + TBool allowed = EFalse; + + // Redefine is allowed: + // - Same client session from the same client process + if( aElement.ContextPublisher() == aSource && + aElement.PublisherUid() == aUid ) + { + allowed = ETrue; + } + + // - The owner is NULL and the client process is the same + else if( !aElement.ContextPublisher() && + aElement.PublisherUid() == aUid ) + { + allowed = ETrue; + } + + // - Owner is NULL and the redefine is done by context source plug-in + else if( !aElement.ContextPublisher() && + KCFServerSid == aUid ) + { + allowed = ETrue; + } + + return allowed; + } + +// End of file +