diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/cfclient/cfcontextservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/cfclient/cfcontextservice.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,693 @@ +/* +* Copyright (c) 2008-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: CCFContextService class implementation. + * +*/ + + +// SYSTEM INCLUDES +#include +#include +#include +#include + +// USER INCLUDES +#include "cfcontextservice.h" +#include "cftrace.h" +#include "cfcommon.h" +#include "CFContextObjectImpl.h" +#include "cfcontextsubscriptionlistener.h" +#include "CFClientSession.h" +#include "cfservermessagelistener.h" +#include "ContextFrameworkPrivateCRKeys.h" +#include "CFContextQueryImpl.h" +#include "CFContextSubscriptionImpl.h" + +// CONSTANTS +static const TInt KDefaultBufferSize = 1024; + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// C++ constructor. +// --------------------------------------------------------------------------- +// +CCFContextService::CCFContextService( RCFClientSession& aSession, + MCFListener& aListener ): + CCFServiceBase( CCFServiceBase::ECFContextService, aSession, aListener ), + iContextDataMaxSize( KContextDataObjectDefaultSize ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor. +// --------------------------------------------------------------------------- +// +void CCFContextService::ConstructL( ) + { + FUNC_LOG; + + // Create context subscription listener + iContextSubscriptionListener = CCFContextSubscriptionListener::NewL( + iListener, + iSession ); + + // Create server message listener + iServerMessageListener = CCFServerMessageListener::NewL( + iListener, + iSession ); + + // Get context data object maximum size + CRepository* cenrep = NULL; + TRAPD( err, cenrep = CRepository::NewL( KCRUidCFCommonConf ) ); + if( cenrep && err == KErrNone ) + { + INFO( "Context data object size read from cenrep." ); + err = cenrep->Get( KContextDataObjectMaxSize, iContextDataMaxSize ); + if( err != KErrNone ) + { + iContextDataMaxSize = KContextDataObjectDefaultSize; + } + delete cenrep; + } + INFO_1( "Context data object max size set to: [0x%x].", + iContextDataMaxSize ); + } + +// --------------------------------------------------------------------------- +// Symbian two phased constructor. +// --------------------------------------------------------------------------- +// +CCFContextService* CCFContextService::NewL( RCFClientSession& aSession, + MCFListener& aListener ) + { + FUNC_LOG; + + CCFContextService* self = CCFContextService::NewLC( aSession, aListener ); + CleanupStack::Pop ( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Symbian two phased constructor. +// Leaves pointer in the cleanup stack. +// --------------------------------------------------------------------------- +// +CCFContextService* CCFContextService::NewLC( RCFClientSession& aSession, + MCFListener& aListener ) + { + FUNC_LOG; + + CCFContextService* self = new( ELeave ) CCFContextService( + aSession, + aListener ); + CleanupStack::PushL ( self ); + self->ConstructL ( ); + return self; + } + +// --------------------------------------------------------------------------- +// C++ destructor. +// --------------------------------------------------------------------------- +// +CCFContextService::~CCFContextService( ) + { + FUNC_LOG; + + delete iContextSubscriptionListener; + delete iServerMessageListener; + } + +//---------------------------------------------------------------------------- +// CCFContextService::DefineContext +//---------------------------------------------------------------------------- +// +TInt CCFContextService::DefineContext( const TDesC& aContextSource, + const TDesC& aContextType, + const TSecurityPolicy& aReadSecurityPolicy, + const TSecurityPolicy& aWriteSecurityPolicy ) + { + FUNC_LOG; + + TInt err = KErrNone; + if( aContextSource.Length() && aContextType.Length() ) + { + TSecurityPolicyBuf readSecPolicyBuf( aReadSecurityPolicy ); + TSecurityPolicyBuf writeSecPolicyBuf( aWriteSecurityPolicy ); + TIpcArgs args( &aContextSource, &aContextType, &readSecPolicyBuf, + &writeSecPolicyBuf ); + err = iSession.SendSync( EDefineContext, args ); + } + else + { + // Incorrect context definition + err = KErrArgument; + } + + if( err == KErrNone ) + { + if( !iServerMessageListener->IsActive() ) + { + // Activate listening + iServerMessageListener->ReceiveMessages(); + } + } + + return err; + } + +//---------------------------------------------------------------------------- +// CCFContextService::PublishContextL +//---------------------------------------------------------------------------- +// +void CCFContextService::PublishContextL( CCFContextObject& aContext ) + { + FUNC_LOG; + + TInt err = KErrNone; + if( IsContextLegalForAdd( aContext ) ) + { + HBufC8* buffer = WriteStreamContextObjectLC( aContext ); + TIpcArgs args( buffer ); + err = iSession.SendSync( EPublishContext, args ); + CleanupStack::PopAndDestroy( buffer ); + } + else + { + err = KErrArgument; + } + + User::LeaveIfError( err ); + } + +//---------------------------------------------------------------------------- +// CCFContextService::PublishContextL +//---------------------------------------------------------------------------- +// +void CCFContextService::PublishContextL( CCFContextObject& aContext, + CCFContextDataObject& aData ) + { + FUNC_LOG; + + TInt err = KErrNone; + + if( IsContextLegalForAdd( aContext ) ) + { + err = IsContextDataLegalForAdd( aData ); + if( err == KErrNone ) + { + // Define IPC arguments + HBufC8* contextBuffer = WriteStreamContextObjectLC( aContext ); + HBufC8* contextDataBuffer = WriteStreamContextDataObjectLC( aData ); + TPckg uidPckg( aData.Uid() ); + TIpcArgs args( contextBuffer, contextDataBuffer, &uidPckg ); + + // Send message + err = iSession.SendSync( EPublishContextWithData, args ); + + // Clean up + CleanupStack::PopAndDestroy( contextDataBuffer ); + CleanupStack::PopAndDestroy( contextBuffer ); + } + } + else + { + err = KErrArgument; + } + + User::LeaveIfError( err ); + } + +//---------------------------------------------------------------------------- +// CCFContextService::SubscribeContextL +//---------------------------------------------------------------------------- +// +void CCFContextService::SubscribeContextL( + CCFContextSubscription& aSubscription) + { + FUNC_LOG; + + TInt err = KErrNone; + + // Stream subscription and send + HBufC8* buffer = WriteStreamContextSubscriptionLC( aSubscription ); + TIpcArgs args( buffer ); + err = iSession.SendSync( EAddSubscription, args ); + CleanupStack::PopAndDestroy( buffer ); + + User::LeaveIfError( err ); + + if( err == KErrNone ) + { + if( !iContextSubscriptionListener->IsActive() ) + { + // Activate listening + iContextSubscriptionListener->ReceiveContextIndications(); + } + } + } + +//---------------------------------------------------------------------------- +// CCFContextService::UnsubscribeContextL +//---------------------------------------------------------------------------- +// +void CCFContextService::UnsubscribeContextL( + CCFContextSubscription& aSubscription) + { + FUNC_LOG; + + TInt err = KErrNone; + + // Stream subscription and send + HBufC8* buffer = WriteStreamContextSubscriptionLC( aSubscription ); + TIpcArgs args( buffer ); + err = iSession.SendSync( ERemoveSubscription, args ); + CleanupStack::PopAndDestroy( buffer ); + + User::LeaveIfError( err ); + } + +//---------------------------------------------------------------------------- +// CCFContextService::RequestContextL +//---------------------------------------------------------------------------- +// +void CCFContextService::RequestContextL( CCFContextQuery& aContextQuery, + RContextObjectArray& aRequestResults ) + { + FUNC_LOG; + + TInt err = KErrNone; + + // Stream context query set into buffer + HBufC8* buffer = buffer = WriteStreamContextQueryLC( aContextQuery ); + HBufC8* resultBuffer = HBufC8::NewLC( iRequestBufferSize ); + TPtr8 resultBufferPtr = resultBuffer->Des(); + TPckg bufferSizePtr( iRequestBufferSize ); + + // Send request to server + TIpcArgs args( &resultBufferPtr, buffer, &bufferSizePtr ); + err = iSession.SendSync( ERequestContext, args ); + if( err == KErrNone ) + { + // Results succesfully received + ReadStreamContextObjectL( *resultBuffer, aRequestResults ); + } + else if( err == KErrTooBig ) + { + // Insufficient buffer size, increase buffer and try again + CleanupStack::PopAndDestroy( resultBuffer ); + resultBuffer = HBufC8::NewLC( iRequestBufferSize ); + resultBufferPtr.Set( resultBuffer->Des() ); + TIpcArgs args( &resultBufferPtr ); + err = iSession.SendSync( ERequestContext, args ); + if( err == KErrNone ) + { + ReadStreamContextObjectL( *resultBuffer, aRequestResults ); + } + else + { + err = KErrNoMemory; + } + } + CleanupStack::PopAndDestroy( resultBuffer ); + CleanupStack::PopAndDestroy( buffer ); + + // If requst buffer size grows too big, zero it + if( iRequestBufferSize > KDefaultBufferSize ) + { + iRequestBufferSize = 0; + } + + User::LeaveIfError( err ); + } + +//---------------------------------------------------------------------------- +// CCFContextService::RequestContextSetL +//---------------------------------------------------------------------------- +// +void CCFContextService::RequestContextSetL( + RContextQueryArray& aContextQuerySet, + RContextObjectArray& aRequestResults) + { + FUNC_LOG; + + TInt err = KErrNone; + + // Stream context query set into buffer + HBufC8* buffer = WriteStreamContextQueryLC( aContextQuerySet ); + HBufC8* resultBuffer = HBufC8::NewLC( iRequestBufferSize ); + TPtr8 resultBufferPtr = resultBuffer->Des(); + resultBufferPtr.Set( resultBuffer->Des() ); + + // Send request to server + TPckg bufferSizePtr( iRequestBufferSize ); + TIpcArgs args( &resultBufferPtr, buffer, &bufferSizePtr ); + err = iSession.SendSync( ERequestContextSet, args ); + if( err == KErrNone ) + { + // Results succesfully received + ReadStreamContextObjectL( *resultBuffer, aRequestResults ); + } + else if( err == KErrTooBig ) + { + // Insufficient buffer size, increase buffer and try again + CleanupStack::PopAndDestroy( resultBuffer ); + resultBuffer = HBufC8::NewLC( iRequestBufferSize ); + resultBufferPtr.Set( resultBuffer->Des() ); + TIpcArgs args( &resultBufferPtr ); + err = iSession.SendSync( ERequestContextSet, args ); + if( err == KErrNone ) + { + ReadStreamContextObjectL( *resultBuffer, aRequestResults ); + } + else + { + err = KErrNoMemory; + } + } + CleanupStack::PopAndDestroy( resultBuffer ); + CleanupStack::PopAndDestroy( buffer ); + + // If requst buffer size grows too big, zero it + if( iRequestBufferSize > KDefaultBufferSize ) + { + iRequestBufferSize = 0; + } + + User::LeaveIfError( err ); + } + +//---------------------------------------------------------------------------- +// CCFContextService::InstallContextSourceSetting +//---------------------------------------------------------------------------- +// +TInt CCFContextService::InstallContextSourceSetting( + const TDesC& aSettingFilename, + const TUid& aContextSourceUid ) + { + FUNC_LOG; + + RFs fs; + TInt err = fs.Connect(); + if ( err != KErrNone ) + { + return err; + } + + // Make possible to share the file server session with the CF server. + err = fs.ShareProtected(); + if( err != KErrNone ) + { + fs.Close(); + return err; + } + + // Open the file. + RFile settingFile; + err = settingFile.Open( fs, aSettingFilename, EFileRead ); + if( err != KErrNone ) + { + fs.Close(); + return err; + } + + // Deliver the file handle to the server. + TIpcArgs args; + err = settingFile.TransferToServer( args, 0, 1 ); + if( err != KErrNone ) + { + settingFile.Close(); + fs.Close(); + return err; + } + + TPckgC< TUid > uidPckgC( aContextSourceUid ); + args.Set( 2, &uidPckgC ); + + err = iSession.SendSync( EInstallSourceSetting, args ); + + settingFile.Close(); + fs.Close(); + + return err; + } + +//---------------------------------------------------------------------------- +// CCFContextService::UninstallContextSourceSetting +//---------------------------------------------------------------------------- +// +TInt CCFContextService::UninstallContextSourceSetting( + const TDesC& aSettingFilename, + const TUid& aContextSourceUid ) + { + FUNC_LOG; + + // Deliver setting filename and context source UID to the server. + TPckgC< TUid > uidPckgC( aContextSourceUid ); + TIpcArgs args( &aSettingFilename, &uidPckgC ); + + TInt err = iSession.SendSync( EUninstallSourceSetting, args ); + + return err; + } + +//---------------------------------------------------------------------------- +// CCFContextService::UninstallContextSourceSettings +//---------------------------------------------------------------------------- +// +TInt CCFContextService::UninstallContextSourceSettings( + const TUid& aContextSourceUid ) + { + FUNC_LOG; + + // Deliver context source UID to the server. + TPckgC< TUid > uidPckgC( aContextSourceUid ); + TIpcArgs args( &uidPckgC ); + + TInt err = iSession.SendSync( EUninstallSourceSettings, args ); + + return err; + } + +//---------------------------------------------------------------------------- +// CCFContextService::IsContextLegalForAdd +//---------------------------------------------------------------------------- +// +TBool CCFContextService::IsContextLegalForAdd( + const CCFContextObject& aContext) + { + FUNC_LOG; + + TBool retVal = EFalse; + + if( aContext.Type().Length() > 0 && + aContext.Source().Length() > 0 && + aContext.Value().Length() > 0 ) + { + retVal = ETrue; + } + + return retVal; + } + +//---------------------------------------------------------------------------- +// CCFContextService::IsContextDataLegalForAdd +//---------------------------------------------------------------------------- +// +TInt CCFContextService::IsContextDataLegalForAdd( + const CCFContextDataObject& aContextData ) + { + FUNC_LOG; + + TInt retVal = KErrNone; + if( aContextData.Size() > iContextDataMaxSize ) + { + retVal = KErrTooBig; + } + else if( aContextData.Uid() == KNullUid ) + { + retVal = KErrNotSupported; + } + + return retVal; + } + +//---------------------------------------------------------------------------- +// CCFContextService::ReadStreamContextObjectL +//---------------------------------------------------------------------------- +// +void CCFContextService::ReadStreamContextObjectL( const TDesC8& aData, + RContextObjectArray& aArray ) + { + FUNC_LOG; + + // Check that we have received data from server + if( aData.Length() ) + { + CCFContextObjectImpl* context = NULL; + RDesReadStream stream( aData ); + stream.PushL(); + TInt count = stream.ReadInt16L(); + for( TInt i = 0; i < count; i++ ) + { + context = CCFContextObjectImpl::NewLC(); + context->InternalizeL( stream ); + aArray.AppendL( context ); + CleanupStack::Pop( context ); + } + + // Clean up + CleanupStack::PopAndDestroy( &stream ); + } + } + +//---------------------------------------------------------------------------- +// CCFContextService::WriteStreamContextSubscriptionLC +//---------------------------------------------------------------------------- +// +HBufC8* CCFContextService::WriteStreamContextSubscriptionLC( + CCFContextSubscription& aSubscription ) + { + FUNC_LOG; + + CCFContextSubscriptionImpl& subscription = + static_cast( aSubscription ); + + HBufC8* buffer = HBufC8::NewLC( subscription.Size() ); + TPtr8 bufferPtr = buffer->Des(); + + RDesWriteStream stream( bufferPtr ); + stream.PushL(); + subscription.ExternalizeL( stream ); + + // Cleanup + CleanupStack::PopAndDestroy( &stream ); + + return buffer; + } + +//---------------------------------------------------------------------------- +// CCFContextService::WriteStreamContextObjectLC +//---------------------------------------------------------------------------- +// +HBufC8* CCFContextService::WriteStreamContextObjectLC( + CCFContextObject& aContext ) + { + FUNC_LOG; + + CCFContextObjectImpl& context = + static_cast( aContext ); + + HBufC8* buffer = HBufC8::NewLC( context.Size() ); + TPtr8 bufferPtr = buffer->Des(); + + RDesWriteStream stream( bufferPtr ); + stream.PushL(); + context.ExternalizeL( stream ); + + // Cleanup + CleanupStack::PopAndDestroy( &stream ); + + return buffer; + } + +//---------------------------------------------------------------------------- +// CCFContextService::WriteStreamContextQueryLC +//---------------------------------------------------------------------------- +// +HBufC8* CCFContextService::WriteStreamContextQueryLC( + RContextQueryArray& aQueryArray ) + { + FUNC_LOG; + + // Calculate buffer size + // Count of array and queries + CCFContextQueryImpl* query = NULL; + TInt size = 0; + size += sizeof( TInt ); + TInt count = aQueryArray.Count(); + for( TInt i = 0; i < count; i++ ) + { + query = static_cast( aQueryArray[i] ); + size += query->Size(); + } + + HBufC8* buffer = HBufC8::NewLC( size ); + TPtr8 bufferPtr = buffer->Des(); + + RDesWriteStream stream( bufferPtr ); + stream.PushL(); + stream.WriteInt16L( count ); + for( TInt i = 0; i < count; i++ ) + { + query = static_cast( aQueryArray[i] ); + query->ExternalizeL( stream ); + } + + // Commit stream + stream.CommitL(); + + // Cleanup + CleanupStack::PopAndDestroy( &stream ); + + return buffer; + } + +//---------------------------------------------------------------------------- +// CCFContextService::WriteStreamContextQueryLC +//---------------------------------------------------------------------------- +// +HBufC8* CCFContextService::WriteStreamContextQueryLC( CCFContextQuery& aQuery ) + { + FUNC_LOG; + + CCFContextQueryImpl& query = + static_cast( aQuery ); + + HBufC8* buffer = HBufC8::NewLC( query.Size() ); + TPtr8 bufferPtr = buffer->Des(); + + RDesWriteStream stream( bufferPtr ); + stream.PushL(); + query.ExternalizeL( stream ); + + // Cleanup + CleanupStack::PopAndDestroy( &stream ); + + return buffer; + } + +//---------------------------------------------------------------------------- +// CCFContextService::WriteStreamContextDataObjectLC +//---------------------------------------------------------------------------- +// +HBufC8* CCFContextService::WriteStreamContextDataObjectLC( + CCFContextDataObject& aContextData ) + { + FUNC_LOG; + + HBufC8* streamBuf = HBufC8::NewLC( aContextData.Size() ); + TPtr8 streamBufPtr( streamBuf->Des() ); + RDesWriteStream writeStream( streamBufPtr ); + CleanupClosePushL( writeStream ); + aContextData.ExternalizeL( writeStream ); + + // Clean up + CleanupStack::PopAndDestroy( &writeStream ); + + return streamBuf; + } + +// End of file