srsf/vcommandhandler/src/contextprovider.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:29:17 +0100
branchRCL_3
changeset 19 e36f3802f733
parent 0 bf1d17376201
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2006 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:  Provides access to the VAS context
*
*/


#include "rubydebug.h"
#include "contextprovider.h"

#include <nssvasmcontextmgr.h>
#include <nssvasmcontext.h>
#include "vcommandinternalapi.h"

_LIT( KContextProviderPanic, "VCP" );

CContextProvider* CContextProvider::NewL( CNssVASDBMgr& aVasDbManager )
	{
	CContextProvider* self = CContextProvider::NewLC( aVasDbManager );
	CleanupStack::Pop( self );
	return self;
	}
	
CContextProvider* CContextProvider::NewLC( CNssVASDBMgr& aVasDbManager )
	{
	CContextProvider* self = new (ELeave) CContextProvider;
	CleanupStack::PushL( self );
	// No part of initialization can leave -> no ConstructL()
	self->iContextManager = aVasDbManager.GetContextMgr();
	return self;
	}
	
CContextProvider::~CContextProvider()
	{
	delete iSaveContextWaiter; // if any
	delete iVasContext;  // if any
	}
	
/**
* Returns the VCommand VAS context. If it doesn't exists,
* it is being created. client is responsible for the context deletion
* 
* @todo If support for different contexts is needed, 
* 1) Rename the method into GetContextLC;
* 2) add the optional
* argument "const TDesC& aContextName = KVoiceCommandContext"
*/
MNssContext* CContextProvider::GetVCommandContextLC()
	{
	RUBY_DEBUG0( "CContextProvider::GetVCommandContextL start" );
    __ASSERT_ALWAYS( !iVasContext, User::Leave( KErrNotReady ) );
    if( iContextManager->GetContextList( this ) != KErrNone )
        {
        RUBY_DEBUG0( "CContextProvider::GetVCommandContextL No context in the VAS yet. Creating one" );
        return CreateVCommandContextLC();
        }
    else
        {
        RUBY_DEBUG0( "CContextProvider::GetVCommandContextL List of contexts requested" );
        }
        TRAPD ( err, WaitForAsyncCallbackL(); );
        if ( err )
            {
            iContextManager->CancelGetContext();
            User::Leave( err );
            }
        MNssContext* result = iVasContext;
        iVasContext = NULL;        
        CleanupDeletePushL( result );
        
        RUBY_DEBUG0( "CContextProvider::GetVCommandContextL end" );
        return result;
	}

/**
* Creates VCommand context. To be called during the GetVCommandContextLC
* sequence
*/	
MNssContext* CContextProvider::CreateVCommandContextLC()
	{
	RUBY_DEBUG0( "CContextProvider::CreateVCommandContextLC start" );
	__ASSERT_ALWAYS( !iVasContext, User::Leave( KErrNotReady ) );
    iVasContext = iContextManager->CreateContextL();
    iVasContext->SetNameL( KVoiceCommandContext );
    iVasContext->SetGlobal( ETrue );
    
    if ( iContextManager->SaveContext( this, iVasContext ) != 
                            KErrNone )
        {
        RUBY_ERROR0( "CContextProvider::CreateVCommandContextLC SaveContext call failed" );
        User::Leave( KErrAbort );
        }
    else 
        {
        RUBY_DEBUG0( "CContextProvider::CreateVCommandContextLC SaveContext requested" );
        }
        
    // We cannot use the inherited WaitForAsyncCallback. 
    // It might already be waiting from GetVCommandContextLC
    /** 
     * @todo Consider transforming WaitForAsyncCallback from wait/released into 
     *        wait_counter
     */
    iSaveContextWaiter = CAsyncWorker::NewL();
    iSaveContextWaiter->WaitForAsyncCallbackL();
    delete iSaveContextWaiter;
    iSaveContextWaiter = NULL;
    MNssContext* result = iVasContext;
    iVasContext = NULL;
    CleanupDeletePushL( result );

    RUBY_DEBUG0( "CContextProvider::CreateVCommandContextLC end" );
    return result;
	}	
				
// From MNssGetContextClient
/**
* Callback to indicate GetContext successed.
* client has to delete the context after using the context.
* @since 2.0
* @param aContext
* @param aErrorCode KErrNone if getting of context was successfull
* @return None
*/
void CContextProvider::GetContextCompleted( MNssContext* /*aContext*/,
                                            TInt /*aErrorCode*/ )
	{
	RUBY_ERROR0( "CContextProvider::GetContextCompleted Should never be called" );
	__ASSERT_ALWAYS( EFalse, User::Panic( KContextProviderPanic, KErrNotSupported ) );
	}

/**
* Callback to indicate GetContext successed.
* client has to ResetAndDestroy() after using the list.
* @since 2.0
* @param aContextList A list of contexts. 
* @param aErrorCode KErrNone if getting of context list was successfull
* @return None
*/
void CContextProvider::GetContextListCompleted(
    MNssContextListArray *aContextList, TInt aErrorCode )
	{
	// No single L function called => TRAPD( DoGetContextListCompletedL() ) not needed
    RUBY_DEBUG0( "CContextProvider::GetContextListCompleted start" );
    
    if( aErrorCode == KErrNone )
        {
        TInt err = KErrNone;

        if ( iVasContext )
            {
            RUBY_ERROR0( "CContextProvider::GetContextListCompleted iVasContext is not NULL" );
            err = KErrAlreadyExists;
            }
       
        if( !aContextList )
            {
            RUBY_ERROR0( "CContextProvider::GetContextListCompleted empty context list" );
            err = KErrArgument;
            }
        
        if( err == KErrNone )  // guarding conditions are ok
            {
            RUBY_DEBUG1( "CContextProvider::GetContextListCompleted Iterating over [%d] contexts",
                        aContextList->Count() );
            for( TInt i ( 0 ); i < aContextList->Count(); i++ ) 
                {
                if ( aContextList->At(i)->ContextName() == KVoiceCommandContext )
                    {
                    iVasContext = aContextList->At( i );
                    }
                else
                    {
                    delete aContextList->At( i );
                    }
                }  // for
            aContextList->Reset();
            delete aContextList;
        
        	if( !iVasContext ) 
    	        {
    	        RUBY_DEBUG0( "CContextProvider::GetContextListCompleted COMMAND context not found" );
    	        TRAP( err,
    	                iVasContext = CreateVCommandContextLC();
    	        		CleanupStack::Pop( iVasContext );
    	        		);
    	        if( err != KErrNone )
    	        	{
    	        	RUBY_ERROR1( "CContextProvider::GetContextListCompleted \
    	        				 Failed to create the VCommandContext", err );
    	        	}
    	        }
            }  // if guarding conditions are ok
            
        if( err != KErrNone )
        	{
        	RUBY_ERROR1( "CContextProvider::GetContextListCompleted failed with [%d]", err );
        	// Whenever error is returned, post-WaitForAsynchCallbackL code has no chance
            // to clean the iVasContext;
            delete iVasContext;
            iVasContext = NULL;
        	}
            
        StopAsyncWaitingOrPanic( err );
        }
        
    else // aErrorCode is not KErrNone
        {
        RUBY_ERROR1( "CContextProvider::GetContextCompleted error. Error code [%d] ", aErrorCode );
        
        // Whenever error is returned, post-WaitForAsynchCallbackL code has no chance
        // to clean the iVasContext;
        delete iVasContext;
        iVasContext = NULL;
        StopAsyncWaitingOrPanic( aErrorCode );       
        }
    
    RUBY_DEBUG0( "CContextProvider::GetContextListCompleted end" );     
   	}

// From MNssSaveContextClient

/**
* Callback to indicate SaveContext successed.
* @since 2.0
* @param aErrorCode KErrNone if saving of context was successfull
* @return None
*/
void CContextProvider::SaveContextCompleted( TInt aErrorCode )
	{
	RUBY_DEBUG0( "CContextProvider::SaveContextCompleted start" );
	
	if( aErrorCode == KErrNone )
	    {
	    iSaveContextWaiter->StopAsyncWaitingOrPanic( KErrNone );    
	    }
    else
        {
        RUBY_ERROR1( "CContextProvider::SaveContextCompleted error. Error code [%d] ", aErrorCode );
        
        // Whenever error is returned, post-WaitForAsynchCallbackL code has no chance
        // to clean the iVasContext;
        delete iVasContext;
        iVasContext = NULL;
        iSaveContextWaiter->StopAsyncWaitingOrPanic( aErrorCode );        
        }
    
    RUBY_DEBUG0( "CContextProvider::SaveContextCompleted end" );
	}

//End of file