locationtriggering/ltstrategyengine/src/lbttriggerview.cpp
changeset 56 4e949f03ecc5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationtriggering/ltstrategyengine/src/lbttriggerview.cpp	Wed Nov 03 23:28:39 2010 +0530
@@ -0,0 +1,1401 @@
+/*
+* Copyright (c) 2006, 2007 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:  Implementation of Trigger View
+*
+*/
+
+
+
+#include <lbtlisttriggeroptions.h>
+
+#include "lbtlogger.h"
+#include "lbttriggerview.h"
+#include "lbttriggerconditionarea.h"
+#include "lbtgeohybrid.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::NewL
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView* CLbtTriggerView::NewL( MLbtTriggerViewObserver* aObserver )
+    {    
+    FUNC_ENTER("CLbtTriggerView::NewL");
+    
+    CLbtTriggerView* self = new ( ELeave ) CLbtTriggerView;
+    CleanupStack::PushL( self );
+    self->ConstructL( aObserver );
+    CleanupStack::Pop();
+    return self;
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::CheckRefreshRequests
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::CheckRefreshRequests()
+    {
+    FUNC_ENTER("CLbtTriggerView::CheckRefreshRequests");
+    if( iRefRequestList.Count() > 0 )
+        {
+        iState = ERefreshView;
+        SetEvent();
+        }
+    else
+        {
+        // switch back to idle state
+        iState = EIdle;
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::Refresh
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::Refresh( TPositionInfo& aPosInfo, 
+                               TLbtTriggerEventMask aEventMask,
+                               RArray<TLbtTriggerId>& aTriggerID )
+    {
+    FUNC_ENTER("CLbtTriggerView::Refresh");
+    
+        // Append refresh requests to the queue to be processed by trigger view
+        if( aTriggerID.Count() != 0 )
+            {            
+            TRefRequestParam req;
+            req.posInfo = aPosInfo;
+            req.eventMask = aEventMask;
+            
+            RArray< TLbtTriggerId >* triggerID = NULL;
+            TRAPD( err,  triggerID = 
+                new( ELeave ) RArray< TLbtTriggerId > );
+            if( KErrNone == err )
+                {
+                for( TInt i = 0; i < aTriggerID.Count(); i++ )
+                    {
+                    triggerID->Append( aTriggerID[i] );
+                    }
+                req.triggerID = triggerID;
+                }
+            else
+                {
+                // Memory allocation failure
+                LOG1("Mem Error: %d", err);
+                // ToDo: Initiate termination
+                return;
+                }
+
+            iRefRequestList.Append( req );
+            }
+            
+        LOG1( "View State is %d", iState );
+        // Initiate processing of request queue only if the current state is
+        // idle. Processing of subsequent requests is automatically handled 
+        // by the ProcessRefreshRequests() method when state is ERefreshView
+        if( EIdle == iState )
+            {
+            LOG("Resetting modified trigger list");
+            iModifiedTrgList.Reset();
+            iState = ERefreshView;
+            SetEvent();
+            }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::GetModifiedTriggers
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::GetModifiedTriggers( RArray< TLbtTriggerId >& aList )
+    {
+    FUNC_ENTER("CLbtTriggerView::GetModifiedTriggers");
+    
+    for( TInt index = 0; index < iModifiedTrgList.Count(); index++ )
+        {
+        aList.Append( iModifiedTrgList[index] );
+        }
+    
+    // This is done here because strategy engine invokes this method and evaluates all modified triggers
+    iModifiedTrgList.Reset();
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::GetTriggerByID
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CLbtTriggerView::GetTriggerByID( TLbtTriggerId aID, 
+                                     CLbtContainerTriggerEntry*& aTriggerInfo )
+    {
+    FUNC_ENTER("CLbtTriggerView::GetTriggerByID");
+    
+    TBtreePos pos;
+    TBool found = EFalse;
+    TRAPD( err, 
+        found = iTriggerList->FindL( pos, aID ); 
+        if( found )
+            {
+            TTrigger tEntry;
+            iTriggerList->ExtractAtL( pos, tEntry );
+            aTriggerInfo = tEntry.info;
+            } 
+    );
+    if( KErrNone != err )
+        {
+        found = EFalse;
+        }
+     
+    return found;
+    
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::IsEmpty
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CLbtTriggerView::IsEmpty()
+    {
+    return iTriggerList->IsEmpty();
+    }
+
+       
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::SetContainerObserver
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::SetContainerObserver( 
+                                MLbtContainerChangeEventObserver* aObserver )
+    {
+    FUNC_ENTER("CLbtTriggerView::SetContainerObserver");
+    
+    // Set observer for trigger change notifications from container
+    TLbtTriggerEventMask event = CLbtContainer::ELbtConTriggerEnabledAndValidCreated | 
+		                         CLbtContainer::ELbtConTriggerDeleted |
+		                         CLbtContainer::ELbtConTriggerStateFieldChanged |
+		                         CLbtContainer::ELbtConTriggerConditionFieldChanged |
+		                         CLbtContainer::ELbtConTriggerValidityFieldChanged;
+
+    iTrgContainer->SetChangeObserver( aObserver, event );
+    iContainerObserver = aObserver;    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::SetTriggerStatusObserver
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::SetTriggerStatusObserver( 
+                                MLbtTriggerStatusObsrvr* aObserver )
+    {
+    FUNC_ENTER("CLbtTriggerView::SetTriggerStatusObserver");
+    
+    iTriggerStatusObserver = aObserver;
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::UpdateTriggerInfo
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::UpdateTriggerInfo( CLbtGeoAreaBase::TGeoAreaType aAreaType,
+                                         TPositionInfo aPosInfo,
+                                         CLbtContainerTriggerEntry* aTrigger, 
+                                         TLbtTriggerDataMask aDataMask )
+    {
+    FUNC_ENTER("CLbtTriggerView::UpdateTriggerInfo");
+    
+    TUpdateRequestParam reqParam;
+    reqParam.areaType = aAreaType;
+    reqParam.posInfo = aPosInfo;
+    reqParam.trigger = aTrigger;
+    reqParam.dataMask = aDataMask;
+    iUpdateRequestList.Append( reqParam );
+    if( EIdle == iState )
+        {
+        iState = ERefreshContainer;
+        SetEvent();
+        }
+        
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::RemContainerObserver
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::DetermineNearestTriggerChanges( RArray< TNearestTrigger >* aNearestTriggers )
+    {
+    FUNC_ENTER("CLbtTriggerView::DetermineNearestTriggerChanges");
+    TLinearOrder< TLbtTriggerId > byTriggerID( CompareByID );
+    TInt pos = 0;
+    TInt count = aNearestTriggers->Count();
+    for( TInt index = count - 1; index >= 0; index-- )
+        {
+        pos = iModifiedTrgList.FindInOrder( ( *aNearestTriggers )[0].id, byTriggerID );
+        if( KErrNotFound != pos )
+            {
+            aNearestTriggers->Remove( index );
+            }
+        }
+    }
+
+    
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::RemContainerObserver
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::RemContainerObserver()
+    {
+    FUNC_ENTER("CLbtTriggerView::RemContainerObserver");
+    
+    iTrgContainer->RemoveObserver( iContainerObserver );
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::InvalidateTrigger
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::InvalidateTrigger( TLbtTriggerId aKey )
+    {
+    FUNC_ENTER("CLbtTriggerView::InvalidateTrigger");
+    
+    TBtreePos pos;
+    TBool found = EFalse;
+    TRAPD( err, 
+        found = iTriggerList->FindL( pos, aKey );
+        if( found )
+            {
+            TTrigger tEntry;
+            iTriggerList->ExtractAtL( pos, tEntry );
+            tEntry.validity = EFalse;
+            
+            // Remove entry from tree and re-insert the modified entry
+            iTriggerList->DeleteL( aKey );
+            iTriggerList->InsertL( pos, tEntry );
+            } 
+    );
+    if( KErrNone != err )
+        {
+        LOG1("Invalidation of trigger %d failed",aKey );
+        LOG1("Reason: %d", err);
+        }
+    else
+        {
+        LOG1("Trigger %d will no longer be supervised as it is invalidated", aKey);
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::BeginL
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter CLbtTriggerView::BeginL(CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea)
+    {
+    FUNC_ENTER("CLbtTriggerView::BeginL");
+    
+     TTriggerViewIter iter = TTriggerViewIter( iTriggerList,aPrimaryTriggerArea );
+     TInt err = iter.Reset();
+     if( KErrNone != err && KErrNotFound != err )
+        {
+        User::Leave( err );
+        }
+     return iter;
+     
+    }
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::BeginL
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter CLbtTriggerView::BeginL(CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea,
+                                                          CLbtGeoAreaBase::TGeoAreaType aSecondaryTriggerArea)
+    {
+    FUNC_ENTER("CLbtTriggerView::BeginL");
+    
+     TTriggerViewIter iter = TTriggerViewIter( iTriggerList,aPrimaryTriggerArea,
+                                               aSecondaryTriggerArea);
+     TInt err = iter.Reset();
+     if( KErrNone != err && KErrNotFound != err )
+        {
+        User::Leave( err );
+        }
+     return iter;
+     
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::Begin
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter CLbtTriggerView::Begin( 
+                                                RArray< TLbtTriggerId >* aID,
+                                                CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea)
+    {
+    FUNC_ENTER("CLbtTriggerView::CLbtTriggerView::Begin");
+    
+    TTriggerViewIter iter = TTriggerViewIter( iTriggerList, aID ,aPrimaryTriggerArea );
+    ( void )iter.Reset();
+    return iter;
+    
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::~CLbtTriggerView
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::~CLbtTriggerView()
+    {
+    FUNC_ENTER("CLbtTriggerView::~CLbtTriggerView");
+    
+    TBtreeMark index;
+    TBool next = EFalse;
+    
+    if (IsActive())
+        {
+        Cancel();
+        }
+    
+    if( NULL != iTriggerList )
+        {
+        TRAPD( err, 
+        next = iTriggerList->ResetL( index );
+        TTrigger tEntry;
+        while( next ) 
+            {
+            iTriggerList->ExtractAtL( index, tEntry );
+            delete tEntry.info;
+            iTriggerList->DeleteL( tEntry.key );
+            next = iTriggerList->ResetL( index );
+            } );
+        if( KErrNone != err )
+            {
+            LOG("Entries could not be deleted");
+            }
+        }
+
+    iList.ResetAndDestroy();
+    delete iTriggerList;
+    delete iPool;
+    if( NULL != iTrgContainer )
+        {
+        iTrgContainer->Destroy();
+        }
+    iModifiedTrgList.Close();
+    iUpdateRequestList.Close();
+    
+    for(TInt i=0;i<iRefRequestList.Count();++i)
+    	{
+    	if( iRefRequestList[i].triggerID != NULL )
+    		{
+    		iRefRequestList[i].triggerID->Close();
+    		delete (iRefRequestList[i].triggerID);
+    		}    	
+    	}
+    iRefRequestList.Close();
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::TTriggerViewIter
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter::TTriggerViewIter()
+    {
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::TTriggerViewIter
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter::TTriggerViewIter( 
+                           TBtreeFix< TTrigger, TLbtTriggerId >* aTriggerList,
+                           CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea )
+    {
+    FUNC_ENTER("CLbtTriggerView::TTriggerViewIter");
+    iTrgArray = NULL;
+    iLast = ETrue;    
+    iTree = aTriggerList;
+    iPrimaryAreaType = aPrimaryTriggerArea;
+    }
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::TTriggerViewIter
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter::TTriggerViewIter( 
+                           TBtreeFix< TTrigger, TLbtTriggerId >* aTriggerList,
+                           CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea,
+                           CLbtGeoAreaBase::TGeoAreaType aSecondaryTriggerArea)
+    {
+    FUNC_ENTER("CLbtTriggerView::TTriggerViewIter");
+    iTrgArray = NULL;
+    iLast = ETrue;    
+    iTree = aTriggerList;
+    iPrimaryAreaType = aPrimaryTriggerArea;
+    iSecondaryAreaType = aSecondaryTriggerArea;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::TTriggerViewIter
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter::TTriggerViewIter( 
+                                TBtreeFix< TTrigger, TLbtTriggerId >* aTriggerList,
+                                RArray< TLbtTriggerId >* aTriggerIDs,
+                                CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea )
+    {
+    FUNC_ENTER("CLbtTriggerView::TTriggerViewIter");
+    iTrgArray = aTriggerIDs;
+    iLast = ETrue;    
+    iTree = aTriggerList; 
+    iPrimaryAreaType = aPrimaryTriggerArea;   
+    }
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::TTriggerViewIter
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::TTriggerViewIter::TTriggerViewIter( 
+                                TBtreeFix< TTrigger, TLbtTriggerId >* aTriggerList,
+                                RArray< TLbtTriggerId >* aTriggerIDs,
+                                CLbtGeoAreaBase::TGeoAreaType aPrimaryTriggerArea,
+                                CLbtGeoAreaBase::TGeoAreaType aSecondaryTriggerArea)
+    {
+    FUNC_ENTER("CLbtTriggerView::TTriggerViewIter");
+    iTrgArray = aTriggerIDs;
+    iLast = ETrue;    
+    iTree = aTriggerList; 
+    iPrimaryAreaType = aPrimaryTriggerArea;   
+    iSecondaryAreaType = aSecondaryTriggerArea;   
+    }
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::ResetL
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CLbtTriggerView::TTriggerViewIter::Reset()
+    {
+    FUNC_ENTER("CLbtTriggerView::Reset");
+    
+    if( iTrgArray && iTrgArray->Count() )
+        {
+        iIndex = 0;
+        }
+    else
+        {
+        TBool exist = EFalse;
+        TRAPD( err, exist = iTree->ResetL( iPos ) );
+        if( KErrNone != err )
+            {
+            return err;
+            }
+        else if( !exist )
+            {
+            return KErrNotFound;
+            }
+        }
+    iLast = EFalse;
+    return KErrNone;
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::TTriggerViewIter::NextL
+// 
+// -----------------------------------------------------------------------------
+//
+ TBool CLbtTriggerView::TTriggerViewIter::NextL( 
+                                     CLbtContainerTriggerEntry*& aTriggerInfo )
+    {
+    FUNC_ENTER("CLbtTriggerView::NextL");
+    TInt err;
+    TInt count = 0;
+    if( iTrgArray )
+        {
+        count = iTrgArray->Count();
+        }
+    
+    // This section of code is for triggers whose IDs are specified. This 
+    // section is executed only when there are trigger changes ( addition /
+    // modification / deletion ) in the system
+    if( count )
+        {
+        while( iIndex < count )
+            {
+            TBtreePos pos;
+            TBool found = EFalse;
+            
+            TRAP( err,
+                found = iTree->FindL( pos, ( *iTrgArray )[iIndex] ) );
+            if( KErrNone == err )
+                {
+                if( found )
+                    {
+                    CLbtTriggerView::TTrigger tEntry;
+                    TRAP( err, iTree->ExtractAtL( pos, tEntry ) );
+                    if( KErrNone == err && tEntry.validity  && 
+                        ( tEntry.type == iPrimaryAreaType || tEntry.type == iSecondaryAreaType ) )
+                        {
+                        aTriggerInfo = tEntry.info;
+                        ++iIndex;
+                        return ETrue;
+                        }
+                    }
+                }
+            LOG1("TTriggerViewIter::NextL - trigger %d not found in repository",( *iTrgArray )[iIndex]);    
+            // This step only ignores missing trigger information and proceeds 
+            // with the next entry
+            ++iIndex;
+            continue;
+            }   // end of while
+            
+        return EFalse;
+        }
+
+    // This section is for all triggers in the BTree
+    else
+        {
+        while( ETrue )
+            {
+            if( !iLast )
+                {
+                CLbtTriggerView::TTrigger tEntry;
+                iTree->ExtractAtL( iPos, tEntry );
+                if( tEntry.validity && 
+                    ( tEntry.type == iPrimaryAreaType || tEntry.type == iSecondaryAreaType ) )
+                    {
+                    aTriggerInfo = tEntry.info;
+                    }
+                else
+                    {
+                    if( iTree->NextL( iPos ) )
+                        {
+                        continue;
+                        }
+                    else
+                        {
+                        aTriggerInfo = NULL;
+                        iLast = ETrue;
+                        return !iLast;
+                        }
+                    }
+                    
+                if( iTree->NextL( iPos ) )
+                    {
+                    return !iLast;
+                    }
+                else
+                    {
+                    iLast = ETrue;
+                    return iLast;
+                    }    
+                }
+            else
+                {
+                return !iLast;
+                }
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::CLbtTriggerView
+// 
+// -----------------------------------------------------------------------------
+//
+CLbtTriggerView::CLbtTriggerView() : 
+            CActive( EPriorityStandard )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::ConstructL
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::ConstructL( MLbtTriggerViewObserver* aObserver )
+    {
+    FUNC_ENTER("CLbtTriggerView::ConstructL");
+    iObserver = aObserver;
+    iRefReqCounter = 0;
+    iUpdateReqCounter = 0;
+    iCellTriggerCount = 0;
+    iCoordTriggerCount = 0;
+    iRequestInitiated = EFalse;
+    iDelayedInitialization = EFalse;
+    
+    
+    iTriggerList = new ( ELeave ) 
+                            TBtreeFix< TTrigger, TLbtTriggerId >( EBtreeFast );
+    iPool = CMemPagePool::NewL();
+    iTriggerList->Connect( iPool, &iKey );
+    
+    iTrgContainer = CLbtContainer::NewL();
+    iState = EInitialize;
+    // Retrieve triggers from container
+    ListEnabledAndValidTriggersL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::InitializeList
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::InitializeList()
+    {
+    FUNC_ENTER("CLbtTriggerView::InitializeList");
+    
+    TInt err;
+    TInt count = iList.Count();
+    for( TInt index = count - 1; index >= 0; index-- )
+        {
+        TRAP( err, AddToTreeL( ( iList[index] )->TriggerEntry()->Id(), 
+                                                    iList[index] ) );
+        if( KErrNone != err )
+            {
+            LOG1("Initializing trigger repository failed. Reason: %d", err );
+            iObserver->OperationComplete( 
+                                MLbtTriggerViewObserver::EOperationError );
+            iList.ResetAndDestroy();
+            return;
+            }
+            
+        iList.Remove( index );
+        }
+
+    // Reset the trigger list as this would be used later to retrieve 
+    // trigger information from container during refresh operations
+    iList.Reset();
+    
+    // Check if there have been any refresh requests queued while view was
+    // being initialized. Process these requests and delay notification to
+    // strategy engine.
+    if( iRefRequestList.Count() )
+        {
+        iDelayedInitialization = ETrue;
+        iState = ERefreshView;
+        SetEvent();
+        }
+    else
+        {
+        iState = EIdle;
+        iObserver->OperationComplete( MLbtTriggerViewObserver::EViewInitialized );
+        }
+    }
+    
+    
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::ProcessRefreshRequests
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::ProcessRefreshRequests()
+    {
+    FUNC_ENTER("CLbtTriggerView::ProcessRefreshRequests");
+    
+	// TODO: Implement relevance here! Currently the list contains
+	//       all enabled and valid triggers in the system
+    while( iRefRequestList.Count() > 0 )
+        {
+        TRefRequestParam req = iRefRequestList[iRefReqCounter];
+    	if( !req.eventMask )
+    	    {
+    	    // This is a special case when strategy engine requests refresh of 
+    	    // trigger view based on position info
+    	    // Current implementation only removes request from queue and 
+    	    // notifies strategy engine
+    	    req.triggerID->Close();
+    	    delete (req.triggerID);
+            iRefRequestList.Remove( iRefReqCounter );
+            
+            LOG("Event mask absent for process refresh requests");
+            continue;
+    	    }
+        
+        if( req.eventMask & CLbtContainer::ELbtConTriggerDeleted )
+            {
+            LOG("Event Mask : Trigger Deleted");
+            // Trigger(s) deleted - remove entry from tree
+            iRefRequestList.Remove( iRefReqCounter );
+            HandleTriggerDeletionEvent( req.triggerID );
+            ( req.triggerID )->Reset();
+            delete (req.triggerID);
+            }
+        else
+            {
+            // Trigger(s) created or modified
+            if( !iRequestInitiated && iList.Count() == 0 )
+                {
+                iRequestInitiated = ETrue;
+                // Retrieve modified triggers from container
+                TRAPD( err, GetTriggers( req.triggerID ) );
+                if( KErrNone != err )
+                    {
+                    iRefRequestList.Remove( iRefReqCounter );
+                    // Invalidate triggers that have been modified
+                    if( !( req.eventMask & CLbtContainer::ELbtConTriggerEnabledAndValidCreated ) &&
+                        !( req.eventMask & CLbtContainer:: ELbtConTriggerDeleted) )
+                        {
+                        TInt index = 0;
+                        while ( index < ( req.triggerID )->Count() )
+                            {
+                            InvalidateTrigger( ( *req.triggerID )[index] );
+                            index++;
+                            }
+                        }
+                    ( req.triggerID )->Reset();
+                    delete req.triggerID;
+                    
+                    continue;
+                    }
+                    
+                break;
+                }
+            else
+                {
+                iRequestInitiated = EFalse;
+                
+                // Triggers with the specified IDs were not found in container
+                if( iList.Count() == 0 )
+                    {
+                    LOG("Zombie Triggers!!");
+                    iRefRequestList.Remove( iRefReqCounter );
+                    ( req.triggerID )->Reset();
+                    delete req.triggerID;
+                    }
+                    
+                // Update tree with triggers retrieved from container
+                else if( req.eventMask & CLbtContainer::ELbtConTriggerEnabledAndValidCreated )
+                    {
+                    LOG("Event Mask : Trigger Created");
+                    // Add new triggers to view
+                    iRefRequestList.Remove( iRefReqCounter );
+                    HandleTriggerCreationEvent();
+                    ( req.triggerID )->Reset();
+                    delete req.triggerID;
+                    }  
+                else
+                    {
+                    LOG("Event Mask : Trigger Modified");
+                    // Check for trigger modifications
+                    iRefRequestList.Remove( iRefReqCounter );
+                    HandleTriggerModificationEvent();
+                    ( req.triggerID )->Reset();
+                    delete req.triggerID;
+                    }
+                }
+            }
+            
+        continue;
+        }// end while
+        
+    if( iRefRequestList.Count() <= 0 )
+        {
+        LOG("End of ProcessRefreshReqs");
+
+        // Reset request list to be reused
+        iRefRequestList.Reset();
+        iState = EIdle;
+        
+        // If a result of delayed initialization caused by triggers being created
+        // before the initialization process is complete, notify initialization
+        // operation complete now.
+        if( iDelayedInitialization )
+            {
+            iDelayedInitialization = EFalse;
+            iObserver->OperationComplete( MLbtTriggerViewObserver::EViewInitialized );
+            }
+        else
+            {
+            iObserver->OperationComplete( MLbtTriggerViewObserver::EViewRefreshed );
+            }
+        
+        
+        // Check if there are any update requests pending. If so, switch to
+        // processing of updates
+        if( iUpdateRequestList.Count() > 0 )
+            {
+            LOG("ERefreshContainer");
+            iState = ERefreshContainer;
+            SetEvent();
+            }
+        else
+            {
+            iState = EIdle;
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::ProcessUpdateRequests
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::ProcessUpdateRequests()
+    {
+    FUNC_ENTER("CLbtTriggerView::ProcessUpdateRequests");
+    
+    if( iUpdateReqCounter )
+        {
+        if( KErrNone != iStatus.Int() )
+            {
+            LOG1("Updating information of trigger %d in the container failed.", 
+                    iUpdateRequestList[iUpdateReqCounter - 1].trigger->TriggerEntry()->Id());
+            LOG1("Reason: %d", iStatus.Int() );      
+            // Error in updating container
+            }
+        else if( iUpdateRequestList[iUpdateReqCounter - 1].dataMask & 
+                    CLbtContainerTriggerEntry::EContainerAttributeIsFired )
+            {
+            iTriggerStatusObserver->TriggerFired( 
+            iUpdateRequestList[iUpdateReqCounter - 1].areaType,
+            iUpdateRequestList[iUpdateReqCounter - 1].trigger->TriggerEntry()->Id(), 
+            iUpdateRequestList[iUpdateReqCounter - 1].posInfo );
+            }
+        }
+
+    if( iUpdateReqCounter < iUpdateRequestList.Count() )
+        {
+        // Update trigger information in container. 
+        // TODO: May need to revisit this TRAP_IGNORE part if container decides 
+        // to leave. Current implementation, there aint no leave!
+        TRAP_IGNORE( iTrgContainer->UpdateTriggerL( 
+                            *( iUpdateRequestList[iUpdateReqCounter].trigger ),
+                            iUpdateRequestList[iUpdateReqCounter].dataMask, 0, 
+                            iRequestID, iStatus ) );
+        SetActive();
+        iUpdateReqCounter++;
+        }
+    else
+        {
+        // Reset request list to be reused
+        iUpdateRequestList.Reset();
+        iUpdateReqCounter = 0;
+        
+        // Check for any refresh requests from container
+        CheckRefreshRequests();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::HandleTriggerCreationEvent
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::HandleTriggerCreationEvent()
+    {
+    FUNC_ENTER("CLbtTriggerView::HandleTriggerCreationEvent");
+    TInt count = iList.Count();
+    for( TInt index = count - 1; index >= 0; index-- )
+        {
+        TRAPD( err, AddToTreeL( ( iList[index] )->TriggerEntry()->Id(),  
+                                                    iList[index] ) );
+        if( KErrNone == err )
+            {
+            LOG1("Added Trigger to tree: %d", ( iList[index] )->TriggerEntry()->Id() );
+            TLinearOrder< TLbtTriggerId > byTriggerID( CompareByID );
+            iModifiedTrgList.InsertInOrder( ( iList[index] )->TriggerEntry()->Id(), byTriggerID );
+            }
+        else
+            {
+            LOG1("Including trigger %d in view failed.",( iList[index] )->TriggerEntry()->Id());
+            LOG1("Reason:%d",err);
+            continue;
+            }
+        
+        iList.Remove( index );
+        }
+        
+    // Reset list to be reused for subsequent refresh operations
+    iList.ResetAndDestroy();
+    }
+
+    
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::HandleTriggerModificationEvent
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::HandleTriggerModificationEvent()
+    {
+    FUNC_ENTER("CLbtTriggerView::HandleTriggerModificationEvent");
+    TInt count = iList.Count();
+    TBool found = EFalse;
+    for( TInt index = count - 1; index >= 0; index-- )
+        {
+        // Check for triggers that have been rendered invalid or disabled and 
+        // remove them from view
+        if( ( iList[index] )->TriggerEntry()->State() == 
+                            CLbtTriggerEntry::EStateDisabled || 
+            ( iList[index] )->DynInfo()->iValidity == 
+                            TLbtTriggerDynamicInfo::EInvalid )
+            {
+            TLbtTriggerId id = ( iList[index] )->TriggerEntry()->Id();
+            
+            LOG1("Trigger deleted / set invalid: %d", id );
+            TRAPD( err, found = DeleteFromTreeL( id ) );
+            if( found )
+                {
+                if( KErrNone == err )
+                    {
+                    TLinearOrder< TLbtTriggerId > byTriggerID( CompareByID );
+                    iModifiedTrgList.InsertInOrder( id, byTriggerID );
+                    }
+                else
+                    {
+                    LOG1("Excluding trigger %d from view failed.",id);
+                    LOG1("This trigger is invalidated and shall not be supervised. Reason: %d",err);
+                    InvalidateTrigger( id );
+                    }
+                }
+            }
+        else
+            {
+            TLbtTriggerId id = ( iList[index] )->TriggerEntry()->Id();            
+            TTrigger trigger;
+            
+            // Find trigger information from tree if it exists
+            TRAPD( err, found = FindInTreeL( id, trigger ) );
+            if( found && (KErrNone == err) )
+            	{
+            	TBool copyStrategyData = ETrue;
+
+            	CLbtTriggerConditionArea* cond = 
+            	        static_cast<CLbtTriggerConditionArea*>(iList[index]->TriggerEntry()->GetCondition());
+            	CLbtTriggerConditionArea::TDirection oldDirection = 
+	            	    cond->Direction();
+            	
+            	CLbtContainerTriggerEntry* triggerEntry = trigger.info;
+            	cond = static_cast<CLbtTriggerConditionArea*>(triggerEntry->TriggerEntry()->GetCondition());
+            	CLbtTriggerConditionArea::TDirection newDirection = 
+	            	    cond->Direction();
+	            	    
+	           	if( triggerEntry->ExtendedTriggerInfo()->IsTriggerFireOnCreation() )
+	           		{
+	           		copyStrategyData = EFalse;
+	           		}
+	           	else if( newDirection != oldDirection )
+	           		{
+	           		copyStrategyData = EFalse;
+	           		}
+            	
+            	if( copyStrategyData )
+            	    {
+            	    // The trigger is already present in the tree. Save the strategy information
+                    // since it is required for regular supervision             
+                    TStrategyData strategyData = triggerEntry->StrategyData();
+                    iList[index]->SetStrategyData( strategyData );
+            	    }            	
+            	}
+            
+            found = EFalse;
+            
+            // Remove trigger information from tree if it exists
+            TRAP( err, found = DeleteFromTreeL( id ) );
+            if( found && KErrNone != err )
+                {
+                InvalidateTrigger( id );
+                }
+            else
+                {
+                LOG1("Added modified trigger to tree: %d", id );
+                
+                // Add modified trigger information to tree
+                TRAP( err, AddToTreeL( id, iList[index] ) );
+                if( KErrNone == err )
+                    {
+                    TLinearOrder< TLbtTriggerId > byTriggerID( CompareByID );
+                    iModifiedTrgList.InsertInOrder( id, byTriggerID );
+                    }
+                else
+                    {
+                    LOG1("Excluding trigger %d from view failed.",id);
+                    LOG1("This trigger is invalidated and shall not be supervised. Reason: %d",err);
+                    InvalidateTrigger( id );
+                    }
+                }
+            }
+        
+        iList.Remove( index );
+        }
+        
+    // Reset list to be reused for subsequent refresh operations        
+    iList.ResetAndDestroy();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::HandleTriggerDeletionEvent
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::HandleTriggerDeletionEvent( 
+                                        RArray< TLbtTriggerId >* aIDs )
+    {
+    FUNC_ENTER("CLbtTriggerView::HandleTriggerDeletionEvent");
+    TBool found = EFalse;
+    for( TInt index = 0; index < aIDs->Count(); index++ )
+        {
+        TRAPD( err, found = DeleteFromTreeL( ( *aIDs )[index] ) );
+        if( found )
+            {
+            if( KErrNone == err )
+                {
+                TLinearOrder< TLbtTriggerId > byTriggerID( CompareByID );
+                iModifiedTrgList.InsertInOrder( ( *aIDs )[index], byTriggerID );
+                }
+            else
+                {
+                LOG1("Invalid trigger ID:%d",( *aIDs )[index]);
+                InvalidateTrigger( ( *aIDs )[index] );
+                }
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::CompareByID
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CLbtTriggerView::CompareByID( const TLbtTriggerId& src, const TLbtTriggerId& dst )
+    {
+    if( src > dst )
+        {
+        return 1;
+        }
+    else if( src < dst )
+        {
+        return -1;
+        }
+    return 0;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::ListEnabledAndValidTriggersL
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::ListEnabledAndValidTriggersL()
+	{
+	FUNC_ENTER("CLbtTriggerView::ListEnabledAndValidTriggersL");
+    
+    CLbtTriggerFilterByAttribute* filter = 
+                        CLbtTriggerFilterByAttribute::NewL();
+    CleanupStack::PushL( filter );
+        
+    filter->AddTriggerTypeL( CLbtTriggerEntry::ETypeSession );
+    filter->AddTriggerTypeL( CLbtTriggerEntry::ETypeStartup );
+    filter->AddTriggerStateL( CLbtTriggerEntry::EStateEnabled );
+    filter->AddTriggerValidityL( TLbtTriggerDynamicInfo::EValid );    
+    
+    // Set fields to retrieve
+    TLbtTriggerDataMask dataMask = 
+               CLbtContainerTriggerEntry::EContainerAttributeHysteresisRadius |
+               CLbtContainerTriggerEntry::EContainerAttributeRectTriggerArea | 
+               CLbtContainerTriggerEntry::EContainerAttributeIsFired |
+               CLbtContainerTriggerEntry::EContainerAttributeStrategyData |
+               CLbtContainerTriggerEntry::EContainerAttributeIsTriggerFireOnCreation;
+            
+       
+    TLbtTriggerAttributeFieldsMask attribMask = CLbtTriggerEntry::EAttributeId |
+                                         CLbtTriggerEntry::EAttributeCondition |
+                                         CLbtTriggerEntry::EAttributeState |
+                                         CLbtTriggerEntry::EAttributeName;
+                                         
+    TLbtTriggerDynamicInfoFieldsMask dynInfoMask = 
+                                      TLbtTriggerDynamicInfo::EValidityStatus;
+    
+    CLbtListTriggerOptions* listOpt = CLbtListTriggerOptions::NewL();
+    listOpt->SetRetrievedFields( attribMask, dynInfoMask );
+    listOpt->SetFilter( filter );
+    CleanupStack::PushL( listOpt );
+    
+    CLbtContainerListOptions* conOpt = CLbtContainerListOptions::NewL( 
+                                                               listOpt, NULL );
+    conOpt->SetDataMask( dataMask );
+    
+    CleanupStack::Pop();    // listOpt
+    CleanupStack::Pop();    // filter
+    
+    iTrgContainer->ListTriggers( conOpt, iList, iRequestID, iStatus );
+    SetActive(); 
+	}
+
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::GetTriggers
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::GetTriggers( RArray< TLbtTriggerId >* aIDs )
+    {
+    FUNC_ENTER("CLbtTriggerView::GetTriggers");
+    iTrgContainer->GetTriggers( *aIDs,
+    							iList,
+    							iRequestID,
+    							iStatus );
+    SetActive();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::AddToTreeL
+// 
+// -----------------------------------------------------------------------------
+//    
+void CLbtTriggerView::AddToTreeL( TLbtTriggerId aKey, 
+                                    CLbtContainerTriggerEntry* aEntry )
+    {
+    FUNC_ENTER("CLbtTriggerView::AddToTreeL");
+    TBtreePos pos;
+    TTrigger tEntry;
+    tEntry.info = aEntry;
+    tEntry.key = aKey;
+    
+    CLbtTriggerEntry* trgEntry = aEntry->TriggerEntry();
+    CLbtTriggerConditionBase* conditionBase = trgEntry->GetCondition();
+    CLbtTriggerConditionArea* conditionArea = 
+            static_cast< CLbtTriggerConditionArea* >( conditionBase );
+    CLbtGeoAreaBase* areaBase = conditionArea->TriggerArea();    
+
+    tEntry.type = areaBase->Type();
+    tEntry.validity = ETrue;
+    
+    iTriggerList->InsertL( pos, tEntry );
+
+    if( CLbtGeoAreaBase::ECellular == tEntry.type )
+        {
+        ++iCellTriggerCount;
+        }
+    else if( CLbtGeoAreaBase::ECircle == tEntry.type )
+        {
+        ++iCoordTriggerCount;
+        }
+    else if( CLbtGeoAreaBase::EHybrid == tEntry.type )
+        {
+        CLbtGeoHybrid* hybridArea = static_cast<CLbtGeoHybrid*> ( areaBase );
+        RPointerArray<CLbtGeoAreaBase> hybridAreaArray = hybridArea->HybridArea();
+        
+        if( hybridAreaArray.Count() )
+            {
+            // Since hybrid area can hold similar area types, it is enough to 
+            // check the first element in the array
+            if( hybridAreaArray[0]->Type() == CLbtGeoAreaBase::ECircle )
+                {
+                ++iCoordTriggerCount;
+                }
+            else if( hybridAreaArray[0]->Type() == CLbtGeoAreaBase::ECellular )
+                {
+                ++iCellTriggerCount;
+                }
+            }
+        }
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::FindInTreeL
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CLbtTriggerView::FindInTreeL( TLbtTriggerId aKey, TTrigger& aEntry )
+	{
+	FUNC_ENTER("CLbtTriggerView::FindInTreeL");
+	TBtreePos pos;
+    TBool found = EFalse;
+    found = iTriggerList->FindL( pos, aKey );
+    if( found )
+        {
+        iTriggerList->ExtractAtL( pos, aEntry );
+        }
+    return found;
+	}    
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::DeleteFromTreeL
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CLbtTriggerView::DeleteFromTreeL( TLbtTriggerId aKey )
+    {
+    FUNC_ENTER("CLbtTriggerView::DeleteFromTreeL");
+    TBtreePos pos;
+    TBool found = EFalse;
+    found = iTriggerList->FindL( pos, aKey );
+    if( found )
+        {
+        TTrigger tEntry;
+        iTriggerList->ExtractAtL( pos, tEntry );
+        
+        if( CLbtGeoAreaBase::ECellular == tEntry.type && iCellTriggerCount != 0 )
+            {
+            --iCellTriggerCount;
+            }
+        else if( CLbtGeoAreaBase::ECircle == tEntry.type && iCoordTriggerCount != 0 )
+            {
+            --iCoordTriggerCount;
+            }
+        else if( CLbtGeoAreaBase::EHybrid == tEntry.type )
+            {
+            CLbtTriggerEntry* trgEntry = tEntry.info->TriggerEntry();
+            CLbtTriggerConditionBase* conditionBase = trgEntry->GetCondition();
+            CLbtTriggerConditionArea* conditionArea = 
+                    static_cast< CLbtTriggerConditionArea* >( conditionBase );
+            CLbtGeoAreaBase* areaBase = conditionArea->TriggerArea();    
+
+            CLbtGeoHybrid* hybridArea = static_cast<CLbtGeoHybrid*> ( areaBase );
+            RPointerArray<CLbtGeoAreaBase> hybridAreaArray = hybridArea->HybridArea();
+            
+            if( hybridAreaArray.Count() )
+                {
+                // Since hybrid area can hold similar area types, it is enough to 
+                // check the first element in the array
+                if( hybridAreaArray[0]->Type() == CLbtGeoAreaBase::ECircle && iCoordTriggerCount != 0)
+                    {
+                    --iCoordTriggerCount;
+                    }
+                else if( hybridAreaArray[0]->Type() == CLbtGeoAreaBase::ECellular && iCellTriggerCount != 0 )
+                    {
+                    --iCellTriggerCount;
+                    }
+                }
+            }
+        delete tEntry.info;
+        iTriggerList->DeleteL( aKey );
+        }
+    return found;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::SetEvent
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::SetEvent()
+    {
+    FUNC_ENTER("CLbtTriggerView::SetEvent");
+    if ( !IsActive() )
+    	{
+    	TRequestStatus* lStatus = &iStatus;
+    	User::RequestComplete( lStatus, KErrNone );
+    	LOG("Calling Set Active !!");
+        SetActive();
+    	}    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::RunL
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::RunL()
+    {
+    FUNC_ENTER("CLbtTriggerView::RunL");
+    if( KErrNone != iStatus.Int() )
+        {
+        LOG1("iStatus.Int = %d",iStatus.Int() );
+        // TODO: Check if error needs to be reported through the 
+        //       observer interface
+        }
+        
+    switch( iState )
+        {
+        
+    case EInitialize:
+       InitializeList();
+       break;
+    
+    case ERefreshView:
+        ProcessRefreshRequests();
+        break;
+
+    case ERefreshContainer:
+        ProcessUpdateRequests();
+        break;
+    
+    default:
+        break;
+        
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CLbtTriggerView::DoCancel
+// 
+// -----------------------------------------------------------------------------
+//
+void CLbtTriggerView::DoCancel()
+    {
+    FUNC_ENTER("CLbtTriggerView::DoCancel");
+    if( IsActive() )
+        {
+        iTrgContainer->CancelAsyncOperation( iRequestID );
+        }
+    
+    // Reset the state the idle
+    iState = EIdle;
+    }
+
+// end of file
+