contextframework/cfw/src/cfclient/cfcontextservice.cpp
changeset 0 2e3d3ce01487
child 18 0818dd463d41
--- /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