--- /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 <cfcontextdataobject.h>
+#include <s32mem.h>
+#include <f32file.h>
+#include <centralrepository.h>
+
+// 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<TUid> 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<TInt> 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<TInt> 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<CCFContextSubscriptionImpl&>( 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<CCFContextObjectImpl&>( 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<CCFContextQueryImpl*>( 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<CCFContextQueryImpl*>( 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<CCFContextQueryImpl&>( 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