locationtriggering/ltcontextsourceplugin/src/lbtcontextsourceplugin.cpp
author hgs
Fri, 06 Aug 2010 19:34:22 +0530
changeset 39 3efc7a0e8755
parent 18 3825cf2dc8c2
child 45 6b6920c56e2f
permissions -rw-r--r--
201031

/*
* Copyright (c) 2009 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:  CLBTContextSourcePlugin DLL source
*
*/

//  Include Files  

#define __INCLUDE_CAPABILITY_NAMES__
#include <e32capability.h>

#include "lbtcontextsourceplugin.h"	// CLBTContextSourcePlugin
#include "lbtcontextsourceplugindebug.h"


// constants
_LIT (KTriggerName, "name");
_LIT (KTriggerLocation, "TriggerLocation");
_LIT (KLatitude, "latitude");
_LIT (KLongitude, "longitude");
_LIT (KRadius, "radius");
_LIT (KRegion, "region");
_LIT (KSource, "setName");
_LIT (KDirection, "Direction");
_LIT (KCurrentState, "CurrentState");

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::NewLC
// ---------------------------------------------------------------------------
//
CLBTContextSourcePlugin* CLBTContextSourcePlugin::NewLC( TContextSourceInitParams* aParams )
    {
    CLBTContextSourcePlugin* self = new (ELeave) CLBTContextSourcePlugin( aParams );
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::NewL
// ---------------------------------------------------------------------------
//
CLBTContextSourcePlugin* CLBTContextSourcePlugin::NewL(TContextSourceInitParams* aParams)
    {
    CLBTContextSourcePlugin* self = CLBTContextSourcePlugin::NewLC( aParams );
    CleanupStack::Pop(self);
    return self;
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::ConstructL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::ConstructL()
    {
    
    // Start listening to trigger fire events
        iLocationTrigger = CLocationTriggerAdapter::NewL(*this);
        
    // Start monitoring Management UI events
    iLbtManagerObserver = CLocationTriggerManager::NewL();
    iLbtManagerObserver->StartManagerObserver();
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::CLBTContextSourcePlugin
// ---------------------------------------------------------------------------
//
CLBTContextSourcePlugin::CLBTContextSourcePlugin( 
TContextSourceInitParams* aParams ):
CCFContextSourcePlugIn( aParams ),
iTriggersCreated(FALSE)
    {
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::~CLBTContextSourcePlugin
// ---------------------------------------------------------------------------
//
CLBTContextSourcePlugin::~CLBTContextSourcePlugin()
    {
    iTriggerList.ResetAndDestroy();
    iTriggerList.Close();
    
    iTriggerNodeList.ResetAndDestroy();
    iTriggerNodeList.Close();
    
    if( iLocationTrigger )
        {
        delete iLocationTrigger;
        iLocationTrigger = NULL;
        }
    
    if( iSettingList )
        {
        delete iSettingList;
        iSettingList = NULL;
        }
    
    if( iLbtManagerObserver )
        {
        delete iLbtManagerObserver;
        iLbtManagerObserver = NULL;
        }
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::HandleSettingL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::HandleSettingL(
        CCFContextSourceSettingArray* aSettingList )
    {
    
    // Cancel all active requests if any
    if (iLocationTrigger->IsActive())
        {
        iLocationTrigger->Cancel();
        }
    
    if( !iSettingList )
        {
        delete iSettingList;
        iSettingList = NULL;
        }
    // take ownership of this object
    iSettingList = aSettingList;
    
    // Clear contents of previous valid trigger specifications
    iTriggerList.ResetAndDestroy();
    iTriggerList.Close();
    
    // Clear contents of array of created triggers
    iTriggerNodeList.ResetAndDestroy();
    iTriggerNodeList.Close();

    // Read from XML file(s) and save onto array
    for ( TInt i = 0; i < aSettingList->Count(); i++ )
        {
        const CCFContextSourceSetting& item = aSettingList->Item( i );
	TInt error = KErrNone;
        TRAP( error, ParseTriggerInformationL( item ) );
        LBTCONTEXTSOURCEPLUGINDEBUG1( " error on ParseTriggerInformationL %d", error );
        }

    if( iTriggerNodeList.Count()>0 )
        {
            iCurrentTriggerIndex = 0;
            TInt err= KErrNone;
            TRAP(err, CreateTriggersL( ));
            while(err != KErrNone)
                {
                iCurrentTriggerIndex++;
                if( iCurrentTriggerIndex <= iTriggerNodeList.Count()-1 )
                    {
                    TRAP( err, CreateTriggersL( ) );
                    }
                }
        }

    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::ParseTriggerInformationL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::ParseTriggerInformationL( const CCFContextSourceSetting& aItem )
    {
    // Flages used to check if the tags are present & also to check repetition of tags
    TBool triggerNameSet = EFalse;
    TBool latitudeSet = EFalse;
    TBool longitudeSet = EFalse;
    TBool regionSet = EFalse;
    TBool radiusSet = EFalse;
    TBool contextSourceSet = EFalse;
    TBool directionSet = EFalse;
    TBool currentStateSet = EFalse;
    
    
    LBTCONTEXTSOURCEPLUGINDEBUG( "CLBTContextSourcePlugin::ParseTriggerInformationL : IN " );

    // Add check for improper syntax of XML file
    if ( aItem.Name() != KTriggerLocation )     
    {
    User::Leave( KErrGeneral );
    }
    
    TTriggerNode *triggerNode = new(ELeave) TTriggerNode();
    
    
    const RKeyValueArray& paramAttr = aItem.Attributes();
    for( TInt k = 0; k < paramAttr.Count(); ++k )
        {
            {
            TPtrC key( paramAttr[k]->Key() );
            TPtrC value( paramAttr[ k ]->Value() );

            if ( ! (key.Compare( KTriggerName ))) 
                {
                // INdicate that the name tag has been parsed
                if( !triggerNameSet )
                    {
                    triggerNameSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetTriggerNameL = %S", &value);
                    triggerNode->SetTriggerNameL( value );
                    }
                }
            else if(!(key.CompareF( KLatitude ) ))
                {
                // Indicate that the latitude tag has been parsed
                if( !latitudeSet )
                    {
                    latitudeSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetLatitudeL = %S", &value);
                    triggerNode->SetLatitudeL( value );
                    }
                }
            
            else if( !(key.CompareF( KLongitude ) ))
                {
                // Indicate that the longitude tag has been parsed
                if( !longitudeSet )
                    {
                    longitudeSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetLongitudeL = %S", &value);
                    triggerNode->SetLongitudeL( value );
                    }
                }
            else if (!(key.CompareF( KRegion ) ))
                {
                // Indicate that the region tag has been parsed
                if( !regionSet )
                    {
                    regionSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetRegionL = %S", &value);
                    triggerNode->SetRegionL( value );
                    }
                }
            
            else if ( !(key.CompareF( KRadius ) ))
                {
                // Indicate that the radius tag has been parsed
                if( !radiusSet )
                    {
                    radiusSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetRadiusL = %S", &value);
                    triggerNode->SetRadiusL( value );
                    }
                }
            else if ( !(key.CompareF( KSource ) ) )
                {
                // Indicate that the contextsource tag has been parsed
                if( !contextSourceSet )
                    {
                    contextSourceSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetContextSource = %S", &value);
                    triggerNode->SetContextSource( value );
                    }
                }
            else if ( !(key.CompareF( KDirection ) ) )
                {
                // Indicate that the direction tag has been parsed
                if( !directionSet )
                    {
                    directionSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetDirection = %S", &value); 
                    triggerNode->SetDirectionL( value );
                    }
                }
            else if ( !(key.CompareF(KCurrentState) ) )
                {
                // Indicate that the current state tag has been parsed
                if( !currentStateSet )
                    {
                    currentStateSet = ETrue;
                    LBTCONTEXTSOURCEPLUGINDEBUG1( "SetCurrentState = %S", &value);    
                    triggerNode->SetCurrentStateL( value );
                    }
                }
            }
        }
    // Check if mandatory tags are present before appending to the trigger node list
    if( triggerNameSet && latitudeSet && longitudeSet && regionSet && radiusSet )
        {
        // Check if optional tags are present,if not set default values
        if( !contextSourceSet )
            {
            TPtrC defaultContextSource( KDefaultContextSourceName );
            triggerNode->SetContextSource( defaultContextSource );
            }
        if( !directionSet )
            {
            TPtrC defaultdirection( KNullDesC );
            triggerNode->SetDirectionL( defaultdirection );
            }
        if( !currentStateSet )
            {
            TPtrC defaultCurrentState ( KNullDesC );
            triggerNode->SetCurrentStateL( defaultCurrentState );
            }
        // Add to triggernode list
        iTriggerNodeList.AppendL( triggerNode );
        }
    else
        {
        // delete triggerNode
        delete triggerNode;
        User::Leave( KErrGeneral );
        }
    
    LBTCONTEXTSOURCEPLUGINDEBUG( "CLBTContextSourcePlugin::ParseTriggerInformationL : OUT " );

    }


// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::CreateTriggersL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::CreateTriggersL( )
    {
    if( iCurrentTriggerIndex<iTriggerNodeList.Count())
        {
        iLocationTrigger->CreateContextTriggerL( *iTriggerNodeList[iCurrentTriggerIndex] );
        }
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::InitializeL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::InitializeL()
    {
    
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::DefineContextsL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::DefineContextsL()
    {
    if(iTriggersCreated)
        {
            DefineTriggerContexts();
        }
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::DefineTriggerContextsL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::DefineTriggerContexts( )
    {
    TSecurityPolicy policy( ECapabilityLocalServices );

    for(int i=0; i<iTriggerList.Count() ; i++)
        {
        TInt err = iCF.DefineContext( iTriggerList[i]->contextName, KContextType, policy);
        LBTCONTEXTSOURCEPLUGINDEBUG1( "Defining ContextSource = %S", &iTriggerList[i]->contextName);
        }
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::ContextTriggerFiredL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::ContextTriggerFiredL( TLbtTriggerId aTriggerId )
    {
    LBTCONTEXTSOURCEPLUGINDEBUG( "ContextTriggerFiredL :IN");
    TPtrC contextSource(KNullDesC);
    TPtrC contextName(KNullDesC);
    
    for(int i=0; i<iTriggerList.Count(); i++)
        {
        if (iTriggerList[i]->iTriggerId == aTriggerId)
            {
            contextSource.Set(iTriggerList[i]->contextName);
            contextName.Set(iTriggerList[i]->triggerName);
            break;
            }
        }
        
    CCFContextObject* context = CCFContextObject::NewLC();

    context->SetSourceL( contextSource );
    context->SetTypeL( KContextType );
    context->SetValueL( contextName );   
                    
    // Publish new context value
    RThread thread;
    CleanupClosePushL( thread );
    iCF.PublishContext( *context, thread );
    LBTCONTEXTSOURCEPLUGINDEBUG1( "Publishing Context = %S", &contextSource);
    LBTCONTEXTSOURCEPLUGINDEBUG1( "Context Value = %S", &contextName);
    thread.Close();
    
    CleanupStack::Pop( &thread );
    CleanupStack::PopAndDestroy( context );
    LBTCONTEXTSOURCEPLUGINDEBUG( "ContextTriggerFiredL :OUT");
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::TriggerCreatedL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::TriggerCreatedL( TLbtTriggerId& aTrigId , 
                                                TPtrC& aContextName, 
                                                TPtrC& aTriggerName )
    {
    TriggerList* newTrigger;
    newTrigger = new (ELeave) TriggerList;
    CleanupStack::PushL(newTrigger);
    newTrigger->iTriggerId = aTrigId;
    newTrigger->contextName.Set( aContextName );
    newTrigger->triggerName.Set( aTriggerName );
        
    iTriggerList.AppendL(newTrigger);
    iCurrentTriggerIndex++;
    if( iCurrentTriggerIndex <= iTriggerNodeList.Count()-1 )
        {            
        TInt err = KErrNone;
        TRAP(err, CreateTriggersL( ));
        while(err != KErrNone)
            {
            iCurrentTriggerIndex++;
            if( iCurrentTriggerIndex <= iTriggerNodeList.Count()-1 )
                {
                TRAP( err, CreateTriggersL() );
                }
            }
        }
    else
        {
        iTriggersCreated = TRUE;
        DefineContextsL();
        }
    CleanupStack::Pop(newTrigger);
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::NotifyError
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::NotifyError( TInt /*aError*/ )
    {
    }


// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::Extension
// ---------------------------------------------------------------------------
//
TAny* CLBTContextSourcePlugin::Extension( const TUid& aExtensionUid ) const
    {
    // Check the extension
    if ( aExtensionUid == KCFContextSourceInterfaceUid )
            {
            return ( ( MCFContextSource* ) this );
            }
        else if ( aExtensionUid == KCFContextSourceUpgradeUid )
            {
            return ( ( MCFContextSourceUpgrade* ) this );
            }
        else
            {
            return NULL;
            }
    }
    
// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::UpdateSettingsL
// ---------------------------------------------------------------------------
//
void CLBTContextSourcePlugin::UpdateSettingsL( CCFContextSourceSettingArray* aSettingList )
    {
        LBTCONTEXTSOURCEPLUGINDEBUG( "UpdateSettingsL() : IN");
        
        // Reset list index number to zero.
        iCurrentTriggerIndex = 0;
        // Stop monitoring the triggers to avoid a call back for this
        // delete
        iLbtManagerObserver->Cancel();
        
        // Delete all existing triggers created by the plugin
        LBTCONTEXTSOURCEPLUGINDEBUG( "DeleteAllTriggersL");
        iTriggersCreated = FALSE;
        TRAPD(error, iLocationTrigger->DeleteAllTriggersL() ); 
        // CHeck if the delete is leaving because there is no triggers 
        // to be created(i.e KErrNotFound),if yes then go ahead & create 
        // the triggers
        if( !error || error == KErrNotFound )
            {
            // start observer
            iLbtManagerObserver->StartManagerObserver();
            // Read updated setting files and re-create triggers
            HandleSettingL( aSettingList );
            }
        LBTCONTEXTSOURCEPLUGINDEBUG( "UpdateSettingsL() : OUT");
    }

// ---------------------------------------------------------------------------
// CLBTContextSourcePlugin::CheckValidity
// ---------------------------------------------------------------------------
//
TInt CLBTContextSourcePlugin::CheckValidity( RThread& aClientThread, 
        const CCFContextSourceSettingArray& aSettingList )
    {
    TBool validFile = EFalse;
    
    // Check capabilities of client application
    if ( !aClientThread.HasCapability( ECapabilityLocation ) )
        {
        return KErrPermissionDenied;
        }
    
    // Check that the file contains atleast a single valid node,else
    // leave with KErrNotSupported
    for ( TInt i = 0; i < aSettingList.Count(); i++ )
        {
        const CCFContextSourceSetting& item = aSettingList.Item( i );

        // Add check for improper syntax of XML file
        if ( item.Name() != KTriggerLocation )     
            {
            validFile = EFalse; 
            }
        else
            {
            validFile = ETrue;
            break;
            }
        }
    
    if ( validFile )
        {
        LBTCONTEXTSOURCEPLUGINDEBUG( "CheckValidity() : OUT , returning KErrNone");
        return KErrNone;
        }
    else
        {
        LBTCONTEXTSOURCEPLUGINDEBUG( "CheckValidity() : OUT , returning KErrNotSupported" );
        return KErrNotSupported;
        }
    }