/*
* 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: This file defines the class that handles the storage
* of triggers in database.
*
*/
#include <sysutil.h>
#include <etelmm.h>
#include <lbtstartuptrigger.h>
#include <lbttriggerconditionarea.h>
#include <lbtgeocircle.h>
#include <lbttriggerfilterbase.h>
#include <lbttriggerfilterbyarea.h>
#include <lbttriggerfilterbyattribute.h>
#include <lbttriggerfiltercomposite.h>
#include <lbtgeorect.h>
#include <lbtgeocell.h>
#include <lbtgeohybrid.h>
#include <s32file.h>
#include <bautils.h>
#include "lbtdbtriggersmanager.h"
#include "lbtdboperationao.h"
#include "lbtcontainerextendedtriggerinfo.h"
#include "lbtcontainertriggerfilter.h"
#include "lbtcontainerfilterbase.h"
#include "lbtcontainerareafilter.h"
#include "lbtcontainerattrfilter.h"
#include "lbtcontainercompfilter.h"
#include "lbttriggerstoreobserver.h"
#include "lbtcontainerutilities.h"
#include "lbtserverconsts.h"
#include "lbtlogger.h"
_LIT(KLbtDbName,"lbt.db"); // Name of the Database file for storing triggers.
_LIT(KTriggersTable,"Triggers"); // Name of the Table for Triggers
_LIT(KCircularTriggersTable, "CircularTriggers");
_LIT(KCellTriggersTable, "CellTriggers");
_LIT(KHybridTriggersTable, "HybridTriggers");
_LIT(KTriggersIndexId,"TriggerIdIndex"); // Index based on Trigger Id column
_LIT(KCircTriggersIndexId,"CircularTriggerIdIndex");
_LIT(KCellTriggersIndexId,"CellularTriggerIdIndex");
_LIT(KHybridTriggersIndexId,"HybridTriggerIdIndex");
// Names for the fields in the table
_LIT(KLbtDbFieldId, "id");
_LIT(KLbtDbFieldName, "name");
_LIT(KLbtDbFieldType, "type");
_LIT(KLbtDbFieldDirection, "direction");
_LIT(KLbtDbFieldOwnerSid, "owner");
_LIT(KLbtDbFieldManagerUiSid, "managerui");
_LIT(KLbtDbFieldRearmTime, "rearmtime");
_LIT(KLbtDbFieldStartupSid, "stprocess");
_LIT(KLbtDbFieldStartupPath, "stprocesspath");
_LIT(KLbtDbFieldStartupCommandLine, "stprocesscmdline");
_LIT(KLbtDbFieldState, "state");
_LIT(KLbtDbFieldIsTriggerFired, "IsFired");
_LIT(KLbtDbFieldDistanceToLastLocation,"distance");
_LIT(KLbtDbFieldValidity, "validity");
_LIT(KLbtDbFieldIsTriggerFireOnCreation, "IsTriggerFireOnCreation");
_LIT(KLbtDbTriggerAreaType, "triggerareatype");
// Name for the fields in circular trigger table
_LIT(KLbtCircTrigDbFieldId, "idcirculartrigger");
_LIT(KLbtDbFieldCenterLat, "latitude");
_LIT(KLbtDbFieldCenterLong, "longitude");
_LIT(KLbtDbFieldRadius, "radius");
_LIT(KLbtDbFieldHysteresis, "hysteresis");
_LIT(KLbtDbFieldAreaLeft, "westlong");
_LIT(KLbtDbFieldAreaRight, "eastlong");
_LIT(KLbtDbFieldAreaTop, "northlat");
_LIT(KLbtDbFieldAreaBottom, "southlat");
_LIT(KLbtDbFieldTriggerFiredLat, "FiredLat");
_LIT(KLbtDbFieldTriggerFiredLong, "FiredLong");
_LIT(KLbtDbFieldTriggerFiredAlt, "FiredAlt");
_LIT(KLbtDbFieldTriggerFiredHorizAcc, "FiredHorizAcc");
_LIT(KLbtDbFieldTriggerFiredVertAcc, "FiredVertAcc");
_LIT(KLbtDbFieldCellIdStream,"cellidstream"); // 9.2TB Column additions start
// Name for the fields in cellular trigger table
_LIT(KLbtCellTrigDbFieldId, "idcelltrigger");
_LIT(KLbtCellTrigDbCountryCode, "countrycode");
_LIT(KLbtCellTrigDbNetworkId, "networkid");
_LIT(KLbtCellTrigDbNetworkType, "networktype");
_LIT(KLbtCellTrigDbLAC, "locationcode");
_LIT(KLbtCellTrigDbCellId, "cellid");
// Name for fields in Hybrid trigger table
_LIT(KLbtHybridTrigDbFieldId, "idhybridtrigger");
_LIT(KLbtHybridDataStream, "hybriddatastream"); // Added for 9.2 TB. Older fields not valid from 9.2 TB
// Constants for SQL Queries
_LIT(KWhere, " WHERE ");
_LIT(KLike, " = ");
_LIT(KLessThanEqualTo, " <= ");
_LIT(KGreaterThanEqualTo, " >= ");
_LIT(KAnd, " AND ");
// Enums for the coulumn ids in the common table
enum TCommonDbColNum
{
ELbtDbFieldId = 1,
ELbtDbFieldName,
ELbtDbFieldType,
ELbtDbFieldDirection,
ELbtDbFieldOwnerSid,
ELbtDbFieldManagerUiSid,
ELbtDbFieldRearmTime,
ELbtDbFieldStartupSid,
ELbtDbFieldStartupPath,
ELbtDbFieldStartupCommandLine,
ELbtDbFieldState,
ELbtDbFieldIsTriggerFired,
ELbtDbFieldDistanceToLastLocation,
ELbtDbFieldValidity,
ELbtDbFieldIsTriggerFireOnCreation,
ELbtDbTriggerAreaType,
};
// Enums for the column ids in the cicular trigger's db
enum TCircleTriggerDbColNum
{
ECircleDbFieldId = 1,
ECircleDbFieldCenterLat,
ECircleDbFieldCenterLong,
ECircleDbFieldRadius,
ECircleDbFieldHysteresis,
ECircleDbFieldAreaLeft,
ECircleDbFieldAreaRight,
ECircleDbFieldAreaTop,
ECircleDbFieldAreaBottom,
ECircleDbFieldTriggerFiredLat,
ECircleDbFieldTriggerFiredLong,
ECircleDbFieldTriggerFiredAlt,
ECircleDbFieldTriggerFiredHorizAcc,
ECircleDbFieldTriggerFiredVertAcc,
};
// Enums for the column ids in the cellular trigger db
enum TCellTriggerDbColNum
{
ECellDbFieldId = 1,
ECellDbCountryCode,
ECellDbNetworkId,
ECellDbNetworkType,
ECellDbLocationAreaCode,
ECellDbTriggerCellId,
};
// Enums added for 9.2 TB
enum THybridTriggersDbColNum
{
EHybridDbFieldId = 1,
EHybridDataStream
};
// SQL Query related constants
const TInt KMaxSqlQueryLength = 256;
// If less than the below % of the db is used for legitimate data then compaction is needed
const TInt KDatabaseMinUsagePercentage = 60;
const TInt KDatabaseMaxWastageBytes = (50 * 1024); // More than 50 KB cannot be wasted
const TInt KStepCount(2); // Number of steps to be executed in one step for async operation
// Assumption that the worst case time needed for compaction is the amount in seconds defined
// by KSecondsNeededForCompaction
const TTimeIntervalSeconds KSecondsNeededForCompaction(15);
_LIT(KSelect, "SELECT ");
_LIT(KFrom, " FROM ");
_LIT(KSelectAllFields, "* ");
_LIT(KDelete,"DELETE ");
#ifdef _DEBUG
_LIT(KLbtCntDbPanic,"LBT: Db ");
TInt KLbtCntDbSqlQueryError = -1;
#endif
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// The Symbian 2 phase constructor
// ---------------------------------------------------------------------------
//
CLbtDbTriggersManager* CLbtDbTriggersManager::NewL( )
{
CLbtDbTriggersManager* self = new(ELeave)CLbtDbTriggersManager( );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CLbtDbTriggersManager::~CLbtDbTriggersManager()
{
FUNC_ENTER("CLbtDbTriggersManager::~CLbtDbTriggersManager");
// Close all open Handles
delete iDbOperation;
delete iSqlQuery;
iIdArray.Close();
if(iIsDbOpened)
{
// Compact the data base before going down
iDb.Compact();
}
iDb.Close();
iFs.Close();
}
// ---------------------------------------------------------------------------
// Specify the types of triggers supported by the Db Trigger Store
// ---------------------------------------------------------------------------
//
TTriggerTypeMask CLbtDbTriggersManager::SupportedTriggerTypes()
{
return ( CLbtTriggerEntry::ETypeStartup );
}
// ---------------------------------------------------------------------------
// Specify the types of triggers supported by the Db Trigger Store
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::CreateTriggerL( CLbtContainerTriggerEntry &aEntry,
TRequestStatus& aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::CreateTriggerL-I");
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if(iDbOperation->IsCompactionOngoing())
{
TRequestStatus* status = &aStatus;
User::RequestComplete(status, KErrServerBusy);
return;
}
// Save client data for create trigger
iCurrentOperation = EDbOpCreateTrigger;
iEntry = &aEntry;
iClientReqStatus = &aStatus;
TInt size = 500;//ToDo: implement this GetSize( aEntry );
if ( SysUtil::FFSSpaceBelowCriticalLevelL( &iFs, size ) )
{
// Try Db Compaction in case we don't have enough disk space
iDbOperation->CompactDb();
iOperationState = EOpCompaction;
}
else
{
iOperationState = EOpStateQuery;
TInt error = AsyncPrepareViewOfCommonTable();
if( error != KErrNone )
{
CompleteClientRequest( error );
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::ResetCurrentStates
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::ResetCurrentStates()
{
iOperationState = EOpStateNone;
iCurrentOperation = EDbOpNone;
iEntry = NULL;
iClientReqStatus = NULL;
iFilter = NULL;
delete iFilterBase;
iFilterBase = NULL;
iView.Close();
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::HandleTriggerCreationEventL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::HandleTriggerCreationEventL( )
{
FUNC_ENTER("CLbtDbTriggersManager::HandleTriggerCreationEventL");
switch(iOperationState)
{
case EOpStateQuery:
{
// Query is done. Now update the view
TRAPD( err, CreateTriggerInViewL() );
if( err == KErrNone )
{
CLbtTriggerEntry* trigger = iEntry->TriggerEntry();
if((trigger->State() == CLbtTriggerEntry::EStateEnabled) &&
(iEntry->DynInfo()->iValidity == TLbtTriggerDynamicInfo::EValid))
{
iCountOfEnabledAndValidTrigger++;
}
}
CompleteClientRequest(err);
CompactDbIfRequiredL();
break;
}
case EOpCompaction:
{
TInt size = 500;//ToDo: implement this GetSize( aEntry );
if ( !SysUtil::FFSSpaceBelowCriticalLevelL(&iFs, size) )
{
iOperationState = EOpStateQuery;
TInt error = AsyncPrepareViewOfCommonTable();
if( error != KErrNone )
{
CompleteClientRequest( KErrDiskFull );
}
}
else
{
CompleteClientRequest( KErrDiskFull );
}
break;
}
default:
{
CompleteClientRequest( KErrGeneral );
break;
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::HandleTriggerUpdationEventL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::HandleTriggerUpdationEventL()
{
// Sanity checks to be done here
__ASSERT_DEBUG(iView.CountL() < 2, User::Panic(KLbtCntDbPanic, KLbtCntDbSqlQueryError) );
switch(iOperationState)
{
case EOpStateQuery:
{
iView.FirstL();
// check if view is empty, return KErrNotFound
if( iView.IsEmptyL() || !iView.AtRow() )
{
CompleteClientRequest( KErrNotFound );
break;
}
// Start iterating through all the triggers in view
iOperationState = EOpStateIterating;
iView.FirstL();
}
// Omitting break is intentional
case EOpStateIterating:
{
TPtr sql = iSqlQuery->Des();
iView.GetL();
CLbtContainerTriggerEntry* triggerEntry = RetrieveTriggerEntryFromDbL( iView );
TBool securityCheck = LbtContainerUtilities::RunSecurityPolicy( triggerEntry, iClientSecurityPolicy );
if( securityCheck )
{
// if security check has passed then the trigger will be updated
AppendTriggerInfo( triggerEntry );
}
else
{
CompleteClientRequest( KErrAccessDenied );
return;
}
delete triggerEntry;
iView.FirstL();
iView.UpdateL();
// Check the trigger type and update the appropriate view
CLbtGeoAreaBase::TGeoAreaType triggerAreaType = static_cast<CLbtGeoAreaBase::TGeoAreaType>(iView.ColInt8(ELbtDbTriggerAreaType));
CLbtStartupTrigger* trigger = static_cast<CLbtStartupTrigger*>(iEntry->TriggerEntry());
// Check if the condition itself has to be replaced
if( iAttrMask & CLbtTriggerEntry::EAttributeCondition )
{
CLbtTriggerConditionArea* cond=static_cast <CLbtTriggerConditionArea*> (trigger->GetCondition());
CLbtGeoAreaBase* areaBase = cond->TriggerArea();
// The area condition has changed
if( triggerAreaType != areaBase->Type() )
{
// Check if the trigger area type itself has been updated
RemoveTriggerConditionFromDb( iEntry->TriggerEntry()->Id(), triggerAreaType );
switch(areaBase->Type())
{
case CLbtGeoAreaBase::ECircle:
{
AddGeoCircleIntoDbL(trigger);
break;
}
case CLbtGeoAreaBase::ECellular:
{
AddGeoCellIntoDbL(trigger);
break;
}
case CLbtGeoAreaBase::EHybrid:
{
AddGeoHybridIntoDbL(trigger);
break;
}
default:
{
CompleteClientRequest( KErrArgument );
break;
}
}
// Write the area type
iView.SetColL(ELbtDbTriggerAreaType,static_cast<TInt8>(areaBase->Type()));
// Negate the Attribute condition so that it is not updated again
iAttrMask = iAttrMask & (~(CLbtTriggerEntry::EAttributeCondition));
// Update trigger area type
triggerAreaType = areaBase->Type();
}
CLbtTriggerConditionArea::TDirection currentTriggerDirection =
static_cast<CLbtTriggerConditionArea::TDirection>(iView.ColInt8(ELbtDbFieldDirection));
if( currentTriggerDirection != cond->Direction() )
{
iView.SetColL( ELbtDbFieldDirection, static_cast<TInt8>((cond->Direction())) );
}
}
CLbtTriggerEntry::TLbtTriggerState currentState =
static_cast<CLbtTriggerEntry::TLbtTriggerState>(iView.ColInt8(ELbtDbFieldState));
if( (iEntry->TriggerEntry()->State() == CLbtTriggerEntry::EStateEnabled) &&
(currentState == CLbtTriggerEntry::EStateDisabled) )
{
iCountOfEnabledAndValidTrigger++;
}
else if( (iEntry->TriggerEntry()->State() == CLbtTriggerEntry::EStateDisabled) &&
(currentState == CLbtTriggerEntry::EStateEnabled) )
{
iCountOfEnabledAndValidTrigger--;
}
CLbtExtendedTriggerInfo* extdInfo = iEntry->ExtendedTriggerInfo();
TLbtTriggerDynamicInfo* trigDynInfo = iEntry->DynInfo();
//Check the masks and update the specified attributes
if(trigger != NULL)
{
if( iAttrMask & CLbtTriggerEntry::EAttributeId )
{
iView.SetColL( ELbtDbFieldId, static_cast<TInt64>(trigger->Id()) );
}
if( iAttrMask & CLbtTriggerEntry::EAttributeName )
{
iView.SetColL( ELbtDbFieldName, trigger->Name() );
}
if( iAttrMask & CLbtTriggerEntry::EAttributeState )
{
iView.SetColL( ELbtDbFieldState, trigger->State() );
}
if( iAttrMask & CLbtTriggerEntry::EAttributeRearmTime )
{
iView.SetColL( ELbtDbFieldRearmTime, trigger->TimeToRearm() );
}
if( iAttrMask & CLbtTriggerEntry::EAttributeStartUpCommandLine )
{
iView.SetColL( ELbtDbFieldStartupCommandLine, trigger->CommandLine() );
}
if( iAttrMask & CLbtTriggerEntry::EAttributeCondition )
{
CLbtTriggerConditionArea* cond=static_cast <CLbtTriggerConditionArea*> (trigger->GetCondition());
switch( triggerAreaType )
{
case CLbtGeoAreaBase::ECircle:
{
//Since the trigger type is circular get the appropriate tuple from the circular trigger table
RDbView circView;
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KCircularTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtCircTrigDbFieldId );
sql.Append( KLike );
sql.AppendNum(iEntry->TriggerEntry()->Id());
TInt error = iDbOperation->ExecuteSyncQuery( circView, sql );
if(error != KErrNone)
{
circView.Close();
User::Leave(error);
}
CleanupClosePushL(circView);
circView.FirstL();
if ( circView.IsEmptyL() || !circView.AtRow() )
{
CleanupStack::PopAndDestroy(1); //circView
CompleteClientRequest( KErrNotFound );
return;
}
circView.UpdateL();
// The area is of type circle
CLbtGeoCircle* area= static_cast <CLbtGeoCircle*> (cond->TriggerArea());
circView.SetColL( ECircleDbFieldCenterLat, area->Center().Latitude() );
circView.SetColL( ECircleDbFieldCenterLong, area->Center().Longitude() );
circView.SetColL( ECircleDbFieldRadius, area->Radius() );
if(extdInfo!=NULL)
{
if( iDataMask & CLbtContainerTriggerEntry::EContainerAttributeHysteresisRadius )
{
circView.SetColL( ECircleDbFieldHysteresis, extdInfo->HysteresisRadius() );
}
if( iDataMask & CLbtContainerTriggerEntry::EContainerAttributeRectTriggerArea )
{
circView.SetColL( ECircleDbFieldAreaLeft, extdInfo->TriggerReactangleArea().iTrigAreaWestLong );
circView.SetColL( ECircleDbFieldAreaRight, extdInfo->TriggerReactangleArea().iTrigAreaEastLong );
circView.SetColL( ECircleDbFieldAreaTop, extdInfo->TriggerReactangleArea().iTrigAreaNorthLat );
circView.SetColL( ECircleDbFieldAreaBottom, extdInfo->TriggerReactangleArea().iTrigAreaSouthLat );
}
if( iDataMask & CLbtContainerTriggerEntry::EContainerAttributeFireInfo )
{
TLbtTriggerFireInfo fireInfo = extdInfo->GetFiredInfo();
TPosition pos;
fireInfo.iFiredPositionInfo.GetPosition(pos);
circView.SetColL(ECircleDbFieldTriggerFiredLat, pos.Latitude());
circView.SetColL(ECircleDbFieldTriggerFiredLong, pos.Longitude());
circView.SetColL(ECircleDbFieldTriggerFiredAlt, pos.Altitude());
circView.SetColL(ECircleDbFieldTriggerFiredHorizAcc, pos.HorizontalAccuracy());
circView.SetColL(ECircleDbFieldTriggerFiredVertAcc, pos.VerticalAccuracy());
}
}
circView.PutL();
CleanupStack::PopAndDestroy(1); // circView
break;
}
case CLbtGeoAreaBase::ECellular:
{
//Since the trigger type is cell get the appropriate tuple from the cell trigger table
RDbView cellView;
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KCellTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtCellTrigDbFieldId );
sql.Append( KLike );
sql.AppendNum( iEntry->TriggerEntry()->Id() );
TInt error = iDbOperation->ExecuteSyncQuery( cellView, sql );
if( error != KErrNone )
{
cellView.Close();
User::Leave(error);
}
CleanupClosePushL( cellView );
cellView.FirstL();
if ( cellView.IsEmptyL() || !cellView.AtRow() )
{
CleanupStack::PopAndDestroy(); //cellView
CompleteClientRequest( KErrNotFound );
return;
}
cellView.UpdateL();
// The area is of type cell
CLbtGeoCell* cell = static_cast <CLbtGeoCell*> (cond->TriggerArea());
// Update the cell parameters
// Update NCC
TLex lex( cell->NetworkCountryCode() );
TUint netCountryCode;
lex.Val( netCountryCode );
cellView.SetColL( ECellDbCountryCode, netCountryCode );
// Update NIC
lex.Assign( cell->NetworkIdentityCode() );
TUint networkIdentityCode;
lex.Val( networkIdentityCode );
cellView.SetColL( ECellDbNetworkId, networkIdentityCode );
// Update Network Type
RMobilePhone::TMobilePhoneNetworkMode nwmode = cell->NetworkType();
if(nwmode == RMobilePhone::ENetworkModeGsm)
{
cellView.SetColL( ECellDbNetworkType, RMobilePhone::ENetworkModeGsm );
}
else if(nwmode == RMobilePhone::ENetworkModeWcdma)
{
cellView.SetColL( ECellDbNetworkType, RMobilePhone::ENetworkModeWcdma );
}
// Update LAC and Cell Id
cellView.SetColL( ECellDbLocationAreaCode, cell->LocationAreaCode());
cellView.SetColL( ECellDbTriggerCellId, cell->CellId());
cellView.PutL();
CleanupStack::PopAndDestroy(1); //cellView
break;
}
case CLbtGeoAreaBase::EHybrid:
{
RDbView hybridView;
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KHybridTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtHybridTrigDbFieldId );
sql.Append( KLike );
sql.AppendNum( iEntry->TriggerEntry()->Id() );
TInt err = iDbOperation->ExecuteSyncQuery(hybridView, sql);
if( err != KErrNone )
{
hybridView.Close();
User::Leave(err);
}
CleanupClosePushL(hybridView);
hybridView.FirstL();
if ( hybridView.IsEmptyL() || !hybridView.AtRow() )
{
CleanupStack::PopAndDestroy(); //hybridView
CompleteClientRequest( KErrNotFound );
return;
}
hybridView.UpdateL();
// cast to hybrid area
CLbtGeoHybrid* hybrid = static_cast<CLbtGeoHybrid *>(cond->TriggerArea());
// Externalize the hybrid areas into the DB
hybridView.SetColNullL( EHybridDataStream );
RDbColWriteStream writeStream;
writeStream.OpenLC(hybridView, EHybridDataStream);
const RPointerArray<CLbtGeoAreaBase>& hybridAreas = hybrid->HybridArea();
// Write the count into the the stream
writeStream.WriteInt32L( hybridAreas.Count() );
for( TInt i=0; i<hybridAreas.Count(); ++i )
{
// Write the area type
writeStream.WriteInt32L( hybridAreas[i]->Type() );
// Externalize the area data
hybridAreas[i]->ExternalizeL(writeStream);
}
writeStream.CommitL();
writeStream.Close();
hybridView.PutL();
CleanupStack::PopAndDestroy( 2 ); // hybridView, writeStream
break;
}
default:
{
CompleteClientRequest( KErrArgument );
break;
}
}
}
}
if(extdInfo!=NULL)
{
if( iDataMask & CLbtContainerTriggerEntry::EContainerAttributeIsFired )
{
iView.SetColL(ELbtDbFieldIsTriggerFired, extdInfo->IsTriggerFired());
}
if( iDataMask & CLbtContainerTriggerEntry::EContainerAttributeOwnerSid )
{
iView.SetColL( ELbtDbFieldOwnerSid, extdInfo->OwnerSid().iId );
}
if( iDataMask & CLbtContainerTriggerEntry::EContainerAttributeIsTriggerFireOnCreation )
{
iView.SetColL( ELbtDbFieldIsTriggerFireOnCreation, extdInfo->IsTriggerFireOnCreation() );
}
}
if(trigDynInfo != NULL)
{
if( iDataMask & CLbtContainerTriggerEntry::EContainerDynInfoAttributeValidity )
{
iView.SetColL( ELbtDbFieldValidity, static_cast<TInt8>(trigDynInfo->iValidity) );
}
}
// Flush the updates into the view/db
iView.PutL();
CompleteClientRequest( KErrNone );
CompactDbIfRequiredL();
break;
}
default:
{
CompleteClientRequest( KErrGeneral );
break;
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::HandleTriggerStateUpdationEventL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::HandleTriggerStateUpdationEventL()
{
FUNC_ENTER("CLbtDbTriggersManager::HandleTriggerStateUpdationEventL");
switch(iOperationState)
{
case EOpStateQuery:
{
// check if view is empty, return KErrNotFound
if( iView.IsEmptyL() )
{
CompleteClientRequest( KErrNotFound );
break;
}
// Start iterating through all the triggers in view
iOperationState = EOpStateIterating;
iView.FirstL();
}
// Omitting break is intentional
case EOpStateIterating:
{
TUid ownerSid;
TUid managerUi;
TSecureId startupSid;
TInt isTriggerPresent = 0;
TInt count = 0;
while( iView.AtRow() && count < KStepCount )
{
++count;
iView.GetL();
// Check if the trigger satisfies the security policy
ownerSid.iUid = iView.ColUint32(ELbtDbFieldOwnerSid);
managerUi.iUid = iView.ColUint32(ELbtDbFieldManagerUiSid);
startupSid.iId = iView.ColUint32(ELbtDbFieldStartupSid);
if( LbtContainerUtilities::RunSecurityPolicy( ownerSid,
managerUi,
startupSid,
iClientSecurityPolicy ) )
{
CLbtContainerTriggerEntry* entry = RetrieveTriggerEntryFromDbL( iView );
CleanupStack::PushL(entry);
TInt isFilterPresent = 0;
TBool isEntryRequested = EFalse;
iFilterBase->ProcessFilter(entry, isFilterPresent, isEntryRequested);
if(isFilterPresent > 0 && isEntryRequested)
{
AppendTriggerInfo(entry);
isTriggerPresent++;
iView.UpdateL();
iView.SetColL( ELbtDbFieldState, iState );
if( iFireOnUpdate == ELbtTrue )
{
iView.SetColL( ELbtDbFieldIsTriggerFireOnCreation, ETrue );
}
else if( iFireOnUpdate == ELbtFalse )
{
iView.SetColL( ELbtDbFieldIsTriggerFireOnCreation, EFalse );
}
iView.PutL();
CLbtTriggerEntry* trigEntry = entry->TriggerEntry();
if( trigEntry->State() == CLbtTriggerEntry::EStateDisabled &&
iState == CLbtTriggerEntry::EStateEnabled )
{
iCountOfEnabledAndValidTrigger++;
}
else if( trigEntry->State() == CLbtTriggerEntry::EStateEnabled &&
iState == CLbtTriggerEntry::EStateDisabled)
{
iCountOfEnabledAndValidTrigger--;
}
}
CleanupStack::PopAndDestroy(entry);
}
iView.NextL();
}
if( count >= KStepCount )
{
// Self complete to process next request
SelfComplete();
}
else
{
CompleteClientRequest( KErrNone );
CompactDbIfRequiredL();
}
}
break;
default:
{
CompleteClientRequest( KErrGeneral );
break;
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::HandleTriggersDeletionEventL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::HandleTriggersDeletionEventL()
{
switch( iOperationState )
{
case EOpStateQuery:
{
// check if view is empty, return KErrNotFound
if( iView.IsEmptyL() )
{
CompleteClientRequest( KErrNotFound );
break;
}
// Start iterating through all the triggers in view
iOperationState = EOpStateIterating;
iView.FirstL();
}
// Omitting break is intentional
case EOpStateIterating:
{
TInt count = 0;
while( count != KStepCount )
{
++count;
if( iView.AtRow() )
{
iView.GetL();
TUid ownerSid;
TUid managerUi;
TSecureId startupSid;
ownerSid.iUid = iView.ColUint32( ELbtDbFieldOwnerSid );
managerUi.iUid = iView.ColUint32( ELbtDbFieldManagerUiSid );
startupSid.iId = iView.ColUint32( ELbtDbFieldStartupSid );
if( LbtContainerUtilities::RunSecurityPolicy( ownerSid,
managerUi,
startupSid,
iClientSecurityPolicy ) )
{
CLbtContainerTriggerEntry* entry = RetrieveTriggerEntryFromDbL( iView );
CleanupStack::PushL( entry );
TInt isFilterPresent = 0;
TBool isEntryRequested = EFalse;
iFilterBase->ProcessFilter(entry, isFilterPresent, isEntryRequested);
if( isFilterPresent > 0 && isEntryRequested )
{
AppendTriggerInfo(entry);
CLbtTriggerEntry* trigEntry = entry->TriggerEntry();
if( trigEntry->State() == CLbtTriggerEntry::EStateEnabled &&
entry->DynInfo()->iValidity == TLbtTriggerDynamicInfo::EValid )
{
iCountOfEnabledAndValidTrigger--;
}
// TODO: Check if this will crash
DeleteTriggerL( entry->TriggerEntry()->Id() );
}
CleanupStack::PopAndDestroy( entry );
}
iView.NextL();
}
}
if( !iView.AtRow() )
{
CompleteClientRequest( KErrNone );
CompactDbIfRequiredL();
}
else
{
SelfComplete();
}
break;
}
default:
{
CompleteClientRequest( KErrGeneral );
break;
}
}
}
//-------------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::HandleGetTriggersEventL
//-------------------------------------------------------------------------------------------------
//
void CLbtDbTriggersManager::HandleGetTriggersEventL( )
{
/**
* Once control reaches here it means that the Db Query
* "Select * From table Triggers" has been executed and
* the view contains all the rows.
*/
TInt count = 0;
while( iView.AtRow() && count < KStepCount )
{
++count;
iView.GetL();
TLbtTriggerId trigId = iView.ColInt64( ELbtDbFieldId );
TInt index = iTriggerIds->Find(trigId);
if( index != KErrNotFound )
{
CLbtContainerTriggerEntry* entry = RetrieveTriggerEntryFromDbL( iView );
iTriggerIds->Remove( index );
if( LbtContainerUtilities::RunSecurityPolicy( entry, iClientSecurityPolicy ) )
{
iTriggers->Append(entry);
}
else
{
delete entry;
}
}
iView.NextL();
}
if( count >= KStepCount )
{
// Self complete to process next request
SelfComplete();
}
else // Operation is over
{
if(iTriggers->Count() == 0)
{
CompleteClientRequest( KErrNotFound );
}
else
{
CompleteClientRequest( KErrNone );
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::CompleteClientRequest
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::CompleteClientRequest(TInt aError)
{
FUNC_ENTER("CLbtDbTriggersManager::CompleteClientRequest");
if( iClientReqStatus )
User::RequestComplete(iClientReqStatus,aError);
ResetCurrentStates();
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::AsyncPrepareViewOfCommonTable
// ---------------------------------------------------------------------------
//
TInt CLbtDbTriggersManager::AsyncPrepareViewOfCommonTable()
{
FUNC_ENTER("CLbtDbTriggersManager::PrepareViewsL");
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KTriggersTable );
// First close the view just as a safe check
iView.Close();
TInt error = iView.Prepare( iDb, TDbQuery( sql, EDbCompareFolded) );
if( error != KErrNone )
{
iView.Close();
}
else
{
iView.Evaluate(iStatus);
SetActive();
}
return error;
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::RetrieveTriggerEntryFromDbL
// Retreives a trigger entry from the first row in the views
// ---------------------------------------------------------------------------
//
CLbtContainerTriggerEntry* CLbtDbTriggersManager::RetrieveTriggerEntryFromDbL( RDbView& aMainView )
{
/**
* This function is coded under the assumption that aMainView has been initialized
* and other views have been un-initialized.
*/
FUNC_ENTER("CLbtDbTriggersManager::RetrieveTriggerEntryFromDbL");
CLbtContainerTriggerEntry* entry = CLbtContainerTriggerEntry::NewL();
CleanupStack::PushL(entry);
CLbtStartupTrigger* clientEntry = CLbtStartupTrigger::NewL();
CleanupStack::PushL(clientEntry);
CLbtExtendedTriggerInfo* clientExtInfo = CLbtExtendedTriggerInfo::NewL();
CleanupStack::PushL(clientExtInfo);
CLbtTriggerConditionArea* cond = CLbtTriggerConditionArea::NewL();
CleanupStack::PushL(cond);
TLbtTriggerId trigId = aMainView.ColInt64(ELbtDbFieldId);
clientEntry->SetId(trigId);
clientEntry->SetNameL(aMainView.ColDes16(ELbtDbFieldName));
CLbtTriggerEntry::TLbtTriggerState state =
static_cast <CLbtTriggerEntry::TLbtTriggerState>(aMainView.ColInt8(ELbtDbFieldState));
clientEntry->SetState(state);
TSecureId sid;
sid.iId = aMainView.ColUint32(ELbtDbFieldStartupSid);
TUid managerUi;
managerUi.iUid=aMainView.ColUint32(ELbtDbFieldManagerUiSid);
clientEntry->SetManagerUi(managerUi);
clientEntry->SetTimeToRearm( aMainView.ColInt32(ELbtDbFieldRearmTime) );
clientEntry->SetProcessId(aMainView.ColDes16(ELbtDbFieldStartupPath),sid);
clientEntry->SetCommandLineL( aMainView.ColDes16(ELbtDbFieldStartupCommandLine) );
TInt fireOnCreation;
fireOnCreation=aMainView.ColInt(ELbtDbFieldIsTriggerFireOnCreation);
clientExtInfo->SetTriggerFireOnCreation(fireOnCreation);
cond->SetDirection(static_cast<CLbtTriggerConditionArea::TDirection>(aMainView.ColInt8(ELbtDbFieldDirection)));
TUid ownerSid;
ownerSid.iUid=aMainView.ColUint32(ELbtDbFieldOwnerSid);
clientExtInfo->SetOwnerSid(ownerSid);
clientExtInfo->SetTriggerFiredState(aMainView.ColInt(ELbtDbFieldIsTriggerFired)) ;
TLbtTriggerFireInfo fireInfo;
fireInfo.iAreaType = static_cast<CLbtGeoAreaBase::TGeoAreaType>(aMainView.ColInt8(ELbtDbTriggerAreaType));
fireInfo.iTriggerId = aMainView.ColInt64(ELbtDbFieldId);
clientExtInfo->SetFiredInfo(fireInfo);
switch( aMainView.ColInt8(ELbtDbTriggerAreaType) )
{
case CLbtGeoAreaBase::ECircle:
{
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KCircularTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtCircTrigDbFieldId );
sql.Append( KLike );
sql.AppendNum(trigId);
RDbView circView;
TInt error = iDbOperation->ExecuteSyncQuery( circView, sql );
if(error != KErrNone)
{
circView.Close();
User::Leave(error);
}
CleanupClosePushL( circView );
circView.FirstL();
circView.GetL();
TCoordinate center;
center.SetCoordinate(circView.ColReal64(ECircleDbFieldCenterLat),circView.ColReal64(ECircleDbFieldCenterLong));
CLbtGeoCircle* circle=CLbtGeoCircle::NewL(center,circView.ColReal64(ECircleDbFieldRadius));
cond->SetTriggerArea(circle);
clientExtInfo->SetHysteresisRadius(circView.ColReal64(ECircleDbFieldHysteresis));
CLbtExtendedTriggerInfo::TLbtTriggerRectArea rect;
rect.iTrigAreaSouthLat=circView.ColReal64(ECircleDbFieldAreaBottom);
rect.iTrigAreaNorthLat=circView.ColReal64(ECircleDbFieldAreaTop);
rect.iTrigAreaEastLong=circView.ColReal64(ECircleDbFieldAreaRight);
rect.iTrigAreaWestLong=circView.ColReal64(ECircleDbFieldAreaLeft);
clientExtInfo->SetTriggerRectangleArea(rect);
TPosition pos;
pos.SetCoordinate( circView.ColReal64(ECircleDbFieldTriggerFiredLat),
circView.ColReal64(ECircleDbFieldTriggerFiredLong),
circView.ColReal32(ECircleDbFieldTriggerFiredAlt) );
TReal32 horAcc = circView.ColReal32(ECircleDbFieldTriggerFiredHorizAcc);
TReal32 verAcc = circView.ColReal32(ECircleDbFieldTriggerFiredVertAcc);
if ( horAcc != -1)
{
pos.SetHorizontalAccuracy(horAcc);
}
if(verAcc != -1)
{
pos.SetVerticalAccuracy(verAcc);
}
fireInfo.iFiredPositionInfo.SetPosition(pos);
CleanupStack::PopAndDestroy(1); // circView
break;
}
case CLbtGeoAreaBase::ECellular:
{
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KCellTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtCellTrigDbFieldId );
sql.Append( KLike );
sql.AppendNum( trigId );
RDbView cellView;
TInt error = iDbOperation->ExecuteSyncQuery( cellView, sql );
if(error != KErrNone)
{
cellView.Close();
User::Leave(error);
}
CleanupClosePushL( cellView );
cellView.FirstL();
cellView.GetL();
TUint32 countryCode = cellView.ColUint32(ECellDbCountryCode);
TUint32 networkID = cellView.ColUint32(ECellDbNetworkId);
RMobilePhone::TMobilePhoneNetworkMode netType = static_cast<RMobilePhone::TMobilePhoneNetworkMode>(cellView.ColInt8(ECellDbNetworkType));
TUint32 locAreaCode = cellView.ColUint32(ECellDbLocationAreaCode);
TUint32 cellid = cellView.ColUint32(ECellDbTriggerCellId);
RMobilePhone::TMobilePhoneNetworkIdentity networkCode;
networkCode.AppendNum( networkID );
RMobilePhone::TMobilePhoneNetworkCountryCode setCountryCode;
setCountryCode.AppendNum( countryCode );
CLbtGeoCell* cell= CLbtGeoCell::NewL( netType,
setCountryCode,
networkCode,
locAreaCode,cellid );
cond->SetTriggerArea(cell);
CleanupStack::PopAndDestroy(1); // cellView
break;
}
case CLbtGeoAreaBase::EHybrid:
{
TPtr sql = iSqlQuery->Des();
RDbView view;
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KHybridTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtHybridTrigDbFieldId );
sql.Append( KLike );
sql.AppendNum( trigId );
TInt error = iDbOperation->ExecuteSyncQuery( view, sql );
if(error != KErrNone)
{
view.Close();
User::Leave(error);
}
CleanupClosePushL(view);
view.FirstL();
view.GetL();
RPointerArray<CLbtGeoAreaBase> areaArray;
CleanupClosePushL( areaArray );
RDbColReadStream readStream;
readStream.OpenLC(view, EHybridDataStream);
// Get count of number of area base objects
TInt count = readStream.ReadInt32L();
for( TInt i=0;i<count;++i )
{
// Create appropriate area type object
CLbtGeoAreaBase* areaBase = NULL;
switch( readStream.ReadInt32L() )
{
case CLbtGeoAreaBase::ECircle:
{
areaBase = CLbtGeoCircle::NewLC();
break;
}
case CLbtGeoAreaBase::ECellular:
{
areaBase = CLbtGeoCell::NewLC();
break;
}
default:
{
User::Leave( KErrArgument );
break;
}
}
areaBase->InternalizeL(readStream);
areaArray.Append(areaBase);
CleanupStack::Pop(1); //areaBase
}
CLbtGeoHybrid* hybrid = CLbtGeoHybrid::NewLC(areaArray);
// Set the wlan area to the trigger
cond->SetTriggerArea( hybrid ); // cond takes ownership of hybrid
CleanupStack::Pop(4); // hybrid, readStream, areaArray and view
readStream.Close();
view.Close();
areaArray.Close(); // Ownership of pointers taken by CLbtGeoHybrid
break;
}
}
clientEntry->SetCondition(cond);
TLbtTriggerDynamicInfo* info = new (ELeave) TLbtTriggerDynamicInfo;
info->iValidity=static_cast <TLbtTriggerDynamicInfo::TLbtTriggerValidity> (aMainView.ColInt8(ELbtDbFieldValidity));
info->iDistanceToLatestLocation= aMainView.ColReal32(ELbtDbFieldDistanceToLastLocation) ;
TPosition firedPosition;
fireInfo.iFiredPositionInfo.GetPosition( firedPosition );
info->iFiredLocality = firedPosition;
entry->SetTriggerEntry(clientEntry);
entry->SetExtendedTriggerInfo(clientExtInfo);
entry->SetDynInfo(info);
CleanupStack::Pop(4); // entry, clientEntry, clientExtInfo and cond
return entry;
}
// --------------------------------------------------------------------------
// CLbtDbTriggersManager::GetTriggersL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::GetTriggersL( RArray<TLbtTriggerId>& aTriggerIds,
RPointerArray<CLbtContainerTriggerEntry>& aTriggers,
TLbtSecurityPolicy& aSecurityPolicy,
TRequestStatus &aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::GetTriggersL");
aStatus = KRequestPending;
iClientReqStatus = &aStatus;
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if(iDbOperation->IsCompactionOngoing())
{
ERROR("COMPACTION ONGOING.THIS SHOULD NOT HAPPEN", KErrServerBusy);
CompleteClientRequest( KErrServerBusy );
return;
}
iClientSecurityPolicy = aSecurityPolicy;
iTriggers = &aTriggers;
iTriggerIds = &aTriggerIds;
iCurrentOperation = EDbOpGetTriggers;
// Prepare view for triggers
PrepareViewForTriggersL( aTriggerIds, iView );
// rest of list triggers operation is in the method HandleGetTriggersEventL.
iView.FirstL();
SelfComplete();
}
// ---------------------------------------------------------------------------
// List the triggers in database based on filter
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::ListTriggersL( CLbtContainerListOptions* aFilter,
RPointerArray < CLbtContainerTriggerEntry >& aTriggers,
TLbtSecurityPolicy& aSecurityPolicy,
TRequestStatus &aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::ListTriggersL");
/**
* Here is the alogirthm to do list triggers. The List Triggers
* has filter based on the various attributes of the trigger like,
* State, Validity, ManagerUi, area, Trigger Id etc.
* In order to list triggers based on these various constraints
* we would have to construct a nested query. But since Symbian DBMS does
* not support nested queries, the idea is to implement this as follows.
*
* 1. For i = 1 to number of filter attributes in aFilter
* 2. Construct a SQL query based on the attribute[i] value list.
* 3. Execute this SQL query on the previously obtained view
* 4. Obtain a view that contains only rows that have value matching
* the value list for attribute[i] in aFilter.
* 5. Continue the loop till i < number of filter attributes in aFilter.
*
* So the idea here is to repeatedly execute the query on the filtered
* list of triggers. Each time the query is executed on the already
* updated db view.
*
* As of now this is not the Implementation. TODO: Fix this algo later.
*/
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
aStatus = KRequestPending;
iClientReqStatus = &aStatus;
if(iDbOperation->IsCompactionOngoing())
{
CompleteClientRequest( KErrServerBusy );
return;
}
// Check if this filter is application for the type of triggers supported by DB
CLbtListTriggerOptions* options = aFilter->ListOptions();
if(options)
{
if( !IsFilterForDBTriggersL(options->Filter()) )
{
CompleteClientRequest( KErrNotFound );
return;
}
}
if( aFilter == NULL )
{
CompleteClientRequest( KErrArgument );
return;
}
// Store the parameters first for later references
iFilter = aFilter;
iTriggers = &aTriggers;
iClientSecurityPolicy = aSecurityPolicy;
iCurrentOperation = EDbOpListTriggers;
// Prepare view for listing
PrepareViewForListingL( iView );
// rest of list triggers operation is in the method HandleListTriggersEventL.
iView.FirstL();
iFilterBase = LbtContainerUtilities::GetContainerFilterFromListOptionsLC(iFilter);
CleanupStack::Pop(1); // iFilterBase
SelfComplete();
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::UpdateTriggerL
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::UpdateTriggerL( CLbtContainerTriggerEntry& aEntry,
TLbtTriggerDataMask aDataMask,
TLbtTriggerAttributeFieldsMask aAttrMask,
TLbtSecurityPolicy& aSecurityPolicy,
TRequestStatus& aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::UpdateTriggerL");
aStatus = KRequestPending;
iClientReqStatus = &aStatus;
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if(iDbOperation->IsCompactionOngoing())
{
CompleteClientRequest( KErrServerBusy );
return;
}
// Save user provided data
iClientSecurityPolicy = aSecurityPolicy;
iClientReqStatus = &aStatus;
iEntry = &aEntry;
iDataMask = aDataMask;
iAttrMask = aAttrMask;
// Save the current operation and its state
iCurrentOperation = EDbOpUpdateTriggers;
iOperationState = EOpStateQuery;
iIdArray.Reset();
// Get the tuple from common db for which the primary key is the trigger id
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtDbFieldId );
sql.Append( KLike );
sql.AppendNum(aEntry.TriggerEntry()->Id());
// First close the view just as a safe check
iView.Close();
TInt error = iView.Prepare( iDb, TDbQuery( sql, EDbCompareFolded) );
if( error != KErrNone )
{
iView.Close();
CompleteClientRequest( error );
}
else
{
iView.Evaluate(iStatus);
SetActive();
}
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::RemoveTriggerConditionFromDb
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::RemoveTriggerConditionFromDb( TLbtTriggerId aTriggerId,
CLbtGeoAreaBase::TGeoAreaType aAreaType )
{
RDbView view;
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KDelete );
sql.Append( KFrom );
switch( aAreaType )
{
case CLbtGeoAreaBase::ECircle:
{
sql.Append( KCircularTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtCircTrigDbFieldId );
break;
}
case CLbtGeoAreaBase::ECellular:
{
sql.Append( KCellTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtCellTrigDbFieldId );
break;
}
case CLbtGeoAreaBase::EHybrid:
{
sql.Append( KHybridTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtHybridTrigDbFieldId );
break;
}
}
sql.Append( KLike );
sql.AppendNum( aTriggerId );
// Execute the query to delete the entry
iDbOperation->ExecuteSyncQuery( view, sql );
view.Close();
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::AddGeoCellIntoDbL
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::AddGeoCellIntoDbL( CLbtTriggerEntry* aTriggerEntry )
{
// Prepare view for cellular trigger table
// Create the trigger
CLbtTriggerConditionArea* cond=static_cast <CLbtTriggerConditionArea*> (aTriggerEntry->GetCondition());
if( cond->TriggerArea()->Type() != CLbtGeoAreaBase::ECellular )
{
User::Leave( KErrArgument );
}
CLbtGeoCell* cell = static_cast<CLbtGeoCell* >(cond->TriggerArea());
RDbView view;
TPtr cellSql = iSqlQuery->Des();
cellSql.Zero();
cellSql.Append( KSelect );
cellSql.Append( KSelectAllFields );
cellSql.Append( KFrom );
cellSql.Append( KCellTriggersTable );
TInt err = iDbOperation->ExecuteSyncQuery(view, cellSql);
if( err != KErrNone )
{
view.Close();
User::Leave(err);
return;
}
CleanupClosePushL(view);
view.InsertL();
view.SetColL( ECellDbFieldId, static_cast<TInt64>(aTriggerEntry->Id()) );
// insert MNC
TLex lex( cell->NetworkCountryCode() );
TUint netCountryCode;
lex.Val( netCountryCode );
view.SetColL( ECellDbCountryCode, netCountryCode );
lex.Assign( cell->NetworkIdentityCode() );
TUint networkIdentityCode;
lex.Val( networkIdentityCode );
view.SetColL( ECellDbNetworkId, networkIdentityCode );
RMobilePhone::TMobilePhoneNetworkMode nwmode = cell->NetworkType();
if(nwmode == RMobilePhone::ENetworkModeGsm)
{
view.SetColL( ECellDbNetworkType, RMobilePhone::ENetworkModeGsm);
}
else if(nwmode == RMobilePhone::ENetworkModeWcdma)
{
view.SetColL( ECellDbNetworkType, RMobilePhone::ENetworkModeWcdma);
}
view.SetColL( ECellDbLocationAreaCode, cell->LocationAreaCode());
view.SetColL( ECellDbTriggerCellId, cell->CellId());
view.PutL();
CleanupStack::PopAndDestroy(1); // view
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::AddGeoCircleIntoDbL
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::AddGeoCircleIntoDbL( CLbtTriggerEntry* aTriggerEntry )
{
CLbtTriggerConditionArea* cond = static_cast<CLbtTriggerConditionArea* >(aTriggerEntry->GetCondition());
CLbtGeoAreaBase * areaBase = cond->TriggerArea();
if( areaBase->Type() != CLbtGeoAreaBase::ECircle )
{
User::Leave( KErrArgument );
}
// Prepare view from circlar triggers table
RDbView view;
TPtr circSql = iSqlQuery->Des();
circSql.Zero();
circSql.Append( KSelect );
circSql.Append( KSelectAllFields );
circSql.Append( KFrom );
circSql.Append( KCircularTriggersTable );
TInt err = iDbOperation->ExecuteSyncQuery(view, circSql);
if( err != KErrNone )
{
view.Close();
User::Leave(err);
return;
}
CleanupClosePushL(view);
CLbtGeoCircle* area = static_cast<CLbtGeoCircle* >(cond->TriggerArea());
view.InsertL();
view.SetColL( ECircleDbFieldId, static_cast<TInt64>(aTriggerEntry->Id()) );
view.SetColL( ECircleDbFieldCenterLat, area->Center().Latitude() );
view.SetColL( ECircleDbFieldCenterLong, area->Center().Longitude() );
view.SetColL( ECircleDbFieldRadius, area->Radius() );
TReal defaultValue = -1;
TReal32 alt = -1;
view.SetColL(ECircleDbFieldTriggerFiredLat,defaultValue);
view.SetColL(ECircleDbFieldTriggerFiredLong,defaultValue);
view.SetColL(ECircleDbFieldTriggerFiredAlt,alt);
view.SetColL(ECircleDbFieldTriggerFiredHorizAcc,alt);
view.SetColL(ECircleDbFieldTriggerFiredVertAcc,alt);
view.PutL(); // Complete insertion
CleanupStack::PopAndDestroy(1); // view
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::AddGeoHybridIntoDbL
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::AddGeoHybridIntoDbL( CLbtTriggerEntry* aTriggerEntry )
{
CLbtTriggerConditionArea* cond = static_cast<CLbtTriggerConditionArea* >(aTriggerEntry->GetCondition());
CLbtGeoAreaBase * areaBase = cond->TriggerArea();
if( areaBase->Type() != CLbtGeoAreaBase::EHybrid )
{
User::Leave(KErrArgument);
}
RDbView view;
TPtr hybridSql = iSqlQuery->Des();
hybridSql.Zero();
hybridSql.Append( KSelect );
hybridSql.Append( KSelectAllFields );
hybridSql.Append( KFrom );
hybridSql.Append( KHybridTriggersTable );
TInt err = iDbOperation->ExecuteSyncQuery(view, hybridSql);
if( err != KErrNone )
{
view.Close();
User::Leave(err);
}
CleanupClosePushL(view);
view.InsertL();
// cast to hybrid area
CLbtGeoHybrid* hybrid = static_cast<CLbtGeoHybrid *>(cond->TriggerArea());
// Set Primary key, trigger id.
view.SetColL( EHybridDbFieldId ,static_cast<TInt32>(aTriggerEntry->Id()) );
// Externalize the hybrid areas into the DB
view.SetColNullL( EHybridDataStream );
RDbColWriteStream writeStream;
writeStream.OpenLC(view, EHybridDataStream);
const RPointerArray<CLbtGeoAreaBase>& hybridAreas = hybrid->HybridArea();
// Write the count into the the stream
writeStream.WriteInt32L( hybridAreas.Count() );
for( TInt i=0; i<hybridAreas.Count(); ++i )
{
// Write the area type
writeStream.WriteInt32L( hybridAreas[i]->Type() );
// Externalize the area data
hybridAreas[i]->ExternalizeL(writeStream);
}
writeStream.CommitL();
writeStream.Close();
view.PutL();
CleanupStack::PopAndDestroy( 2 ); // view, writeStream
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::UpdateTriggersState
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::UpdateTriggersStateL( CLbtTriggerEntry::TLbtTriggerState aState,
CLbtContainerUpdateFilter* aFilter,
TLbtFireOnUpdate aFireOnUpdate,
TLbtSecurityPolicy& aSecurityPolicy,
TRequestStatus& aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::UpdateTriggersState");
aStatus = KRequestPending;
iClientReqStatus = &aStatus;
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if( iDbOperation->IsCompactionOngoing() )
{
CompleteClientRequest( KErrServerBusy );
return;
}
if(aFilter==NULL)
{
CompleteClientRequest( KErrArgument );
return;
}
// Save user provided data
iClientSecurityPolicy = aSecurityPolicy;
iState = aState;
iFireOnUpdate = aFireOnUpdate;
iFilterBase = LbtContainerUtilities::GetContainerFilterFromUpdateFilterLC( aFilter );
CleanupStack::Pop(1); // iFilterBase
// Save the current operation and its state
iCurrentOperation = EDbOpUpdateTriggersState;
iOperationState = EOpStateQuery;
iIdArray.Reset();
TInt error = AsyncPrepareViewOfCommonTable();
if( error != KErrNone )
{
CompleteClientRequest( error );
}
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::UpdateTriggersValidity
// --------------------------------------------------------------------------------------------
//
void CLbtDbTriggersManager::UpdateTriggersValidityL( TLbtTriggerDynamicInfo::TLbtTriggerValidity aValidity,
RArray <TLbtTriggerId>& aTriggerIds,
TLbtSecurityPolicy& aSecurityPolicy,
TRequestStatus& aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::UpdateTriggersValidity");
TRequestStatus* status = &aStatus;
aStatus = KRequestPending;
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if(iDbOperation->IsCompactionOngoing())
{
User::RequestComplete(status, KErrServerBusy);
return;
}
if(aTriggerIds.Count() == 0)
{
User::RequestComplete(status, KErrArgument);
return;
}
iIdArray.Reset();
RDbView view;
PrepareViewForTriggersL( aTriggerIds, view );
CleanupClosePushL( view );
view.FirstL();
while(view.AtRow())
{
view.GetL();
TLbtTriggerId triggerId = view.ColInt64(ELbtDbFieldId);
TInt index = aTriggerIds.Find(triggerId);
if( KErrNotFound != index )
{
// This trigger is found in this db. So remove the trigger from the list
aTriggerIds.Remove(index);
// Check if the trigger satisfies the security policy
TUid ownerSid;
TUid managerUi;
TSecureId startupSid;
ownerSid.iUid = view.ColUint32(ELbtDbFieldOwnerSid);
managerUi.iUid = view.ColUint32(ELbtDbFieldManagerUiSid);
startupSid.iId = view.ColUint32(ELbtDbFieldStartupSid);
if( LbtContainerUtilities::RunSecurityPolicy( ownerSid,
managerUi,
startupSid,
aSecurityPolicy ) )
{
TLbtTriggerDynamicInfo::TLbtTriggerValidity currentValidity=
static_cast<TLbtTriggerDynamicInfo::TLbtTriggerValidity>(view.ColInt8(ELbtDbFieldValidity));
if( currentValidity != aValidity )
{
view.UpdateL();
view.SetColL( ELbtDbFieldValidity, static_cast<TInt8>(aValidity) );
view.PutL();
TLbtTriggerModifiedInfo info;
info.iTriggerId = triggerId;
info.iAreaType = static_cast<CLbtGeoAreaBase::TGeoAreaType>(view.ColInt8(ELbtDbTriggerAreaType));;
iIdArray.Append(info);
if( currentValidity == TLbtTriggerDynamicInfo::EInvalid &&
aValidity == TLbtTriggerDynamicInfo::EValid)
{
iCountOfEnabledAndValidTrigger++;
}
else if(currentValidity == TLbtTriggerDynamicInfo::EValid &&
aValidity == TLbtTriggerDynamicInfo::EInvalid)
{
iCountOfEnabledAndValidTrigger--;
}
}
}
}
view.NextL();
}
CleanupStack::PopAndDestroy(); // view
User::RequestComplete( status, KErrNone );
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::UpdateTriggerFiredStateL
// --------------------------------------------------------------------------------------------
//
void CLbtDbTriggersManager::UpdateTriggerFiredStateL( RArray<TLbtTriggerId>& aTriggerIds,
TBool aFireBool,
TRequestStatus& aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::UpdateTriggerFiredStateL");
TRequestStatus* status = &aStatus;
aStatus = KRequestPending;
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if(iDbOperation->IsCompactionOngoing())
{
User::RequestComplete(status, KErrServerBusy);
return;
}
if(aTriggerIds.Count() == 0)
{
User::RequestComplete(status, KErrArgument);
return;
}
RDbView view;
PrepareViewForTriggersL( aTriggerIds, view );
TBool found = EFalse;
CleanupClosePushL( view );
view.FirstL();
while(view.AtRow())
{
view.GetL();
TLbtTriggerId triggerId = view.ColInt64(ELbtDbFieldId);
if( KErrNotFound != aTriggerIds.Find(triggerId) )
{
TBool currentFiredFlag = view.ColInt(ELbtDbFieldIsTriggerFired);
found = ETrue;
if(currentFiredFlag != aFireBool)
{
view.UpdateL();
view.SetColL( ELbtDbFieldIsTriggerFired, aFireBool );
view.PutL();
}
}
view.NextL();
}
CleanupStack::PopAndDestroy(); //view
TInt error = KErrNone;
if(!found)
{
error = KErrNotFound;
}
User::RequestComplete(status, error);
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::DeleteTriggersL
// --------------------------------------------------------------------------------------------
//
void CLbtDbTriggersManager::DeleteTriggersL( CLbtContainerUpdateFilter* aFilter,
TLbtSecurityPolicy& aSecurityPolicy,
TRequestStatus& aStatus )
{
FUNC_ENTER("CLbtDbTriggersManager::DeleteTriggersL");
// Save user provided data
iClientSecurityPolicy = aSecurityPolicy;
iClientReqStatus = &aStatus;
// This is just a safe check. While compaction is ongoing the
// request is queued in container AO
if(iDbOperation->IsCompactionOngoing())
{
CompleteClientRequest( KErrServerBusy );
return;
}
if(aFilter == NULL)
{
CompleteClientRequest( KErrArgument );
return;
}
if( !IsFilterForDBTriggersL(aFilter->TrigInfoFilter()) )
{
CompleteClientRequest( KErrNotFound );
return;
}
TInt error = AsyncPrepareViewOfCommonTable();
if( error != KErrNone )
{
CompleteClientRequest( error );
return;
}
iFilterBase = LbtContainerUtilities::GetContainerFilterFromUpdateFilterLC( aFilter );
CleanupStack::Pop(1); // iFilterBase
// Save the current operation and its state
iCurrentOperation = EDbOpDeleteTriggers;
iOperationState = EOpStateQuery;
iIdArray.Reset();
}
// --------------------------------------------------------------------------
// CLbtDbTriggersManager::SelfComplete
// --------------------------------------------------------------------------
//
void CLbtDbTriggersManager::SelfComplete()
{
TRequestStatus* status = &iStatus;
iStatus = KRequestPending;
SetActive();
User::RequestComplete(status, KErrNone);
}
// --------------------------------------------------------------------------
// CLbtDbTriggersManager::DeleteTriggerL
// --------------------------------------------------------------------------
//
void CLbtDbTriggersManager::DeleteTriggerL( TLbtTriggerId aTriggerId )
{
FUNC_ENTER("CLbtDbTriggersManager::DeleteTriggerL");
CLbtGeoAreaBase::TGeoAreaType areaType =
static_cast<CLbtGeoAreaBase::TGeoAreaType>( iView.ColInt8(ELbtDbTriggerAreaType) );
switch( areaType )
{
case CLbtGeoAreaBase::ECircle:
{
TPtr circSql = iSqlQuery->Des();
RDbView circView;
circSql.Zero();
circSql.Append( KSelect );
circSql.Append( KSelectAllFields );
circSql.Append( KFrom );
circSql.Append( KCircularTriggersTable );
circSql.Append( KWhere );
circSql.Append( KLbtCircTrigDbFieldId );
circSql.Append( KLike );
circSql.AppendNum(aTriggerId);
TInt error = iDbOperation->ExecuteSyncQuery( circView, circSql );
if(error != KErrNone)
{
circView.Close();
User::Leave(error);
}
CleanupClosePushL(circView);
circView.FirstL();
circView.GetL();
circView.DeleteL();
circView.Close();
CleanupStack::PopAndDestroy(1); // circView
break;
}
case CLbtGeoAreaBase::ECellular:
{
TPtr cellSql = iSqlQuery->Des();
cellSql.Zero();
cellSql.Append( KSelect );
cellSql.Append( KSelectAllFields );
cellSql.Append( KFrom );
cellSql.Append( KCellTriggersTable );
cellSql.Append( KWhere );
cellSql.Append( KLbtCellTrigDbFieldId );
cellSql.Append( KLike );
cellSql.AppendNum(aTriggerId);
RDbView cellView;
TInt error = iDbOperation->ExecuteSyncQuery( cellView, cellSql );
if(error != KErrNone)
{
cellView.Close();
User::Leave(error);
}
CleanupClosePushL(cellView);
cellView.FirstL();
cellView.GetL();
cellView.DeleteL();
cellView.Close();
CleanupStack::PopAndDestroy(1); // cellView
break;
}
case CLbtGeoAreaBase::EHybrid:
{
TPtr cellSql = iSqlQuery->Des();
cellSql.Zero();
cellSql.Append( KSelect );
cellSql.Append( KSelectAllFields );
cellSql.Append( KFrom );
cellSql.Append( KHybridTriggersTable );
cellSql.Append( KWhere );
cellSql.Append( KLbtHybridTrigDbFieldId );
cellSql.Append( KLike );
cellSql.AppendNum(aTriggerId);
RDbView hybridView;
TInt error = iDbOperation->ExecuteSyncQuery( hybridView, cellSql );
if(error != KErrNone)
{
hybridView.Close();
User::Leave(error);
}
CleanupClosePushL(hybridView);
hybridView.FirstL();
hybridView.GetL();
hybridView.DeleteL();
hybridView.Close();
CleanupStack::PopAndDestroy(1); // hybridView
break;
}
}
if(iIdArray.Count() == 0)
{
MLbtTriggerStore::TLbtTriggerModifiedInfo info;
info.iTriggerId = aTriggerId;
info.iAreaType = areaType;
iIdArray.Append(info);
}
iView.DeleteL();
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::RunL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::RunL()
{
if( iStatus.Int() != KErrNone )
{
CompleteClientRequest( iStatus.Int() );
return;
}
switch( iCurrentOperation )
{
case EDbOpCreateTrigger:
{
HandleTriggerCreationEventL();
break;
}
case EDbOpDeleteTriggers:
{
HandleTriggersDeletionEventL();
break;
}
case EDbOpListTriggers:
{
HandleListTriggersEventL();
break;
}
case EDbOpGetTriggers:
{
HandleGetTriggersEventL();
break;
}
case EDbOpUpdateTriggersState:
{
HandleTriggerStateUpdationEventL();
break;
}
case EDbOpUpdateTriggers:
{
HandleTriggerUpdationEventL();
break;
}
default:
{
//CompleteClientRequest( KErrGeneral );
break;
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::RunError
// ---------------------------------------------------------------------------
//
TInt CLbtDbTriggersManager::RunError( TInt aError )
{
CompleteClientRequest( aError );
return KErrNone;
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::DoCancel
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::DoCancel()
{
switch( iOperationState )
{
case EOpCompaction:
{
// Cancel compaction if ongoing
iDbOperation->Cancel();
break;
}
case EOpStateQuery:
{
iView.Cancel();
break;
}
case EOpStateIterating:
default:
{
break;
}
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::PrepareViewForTriggersL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::PrepareViewForTriggersL( const RArray<TLbtTriggerId>& aTriggerIds, RDbView& aView )
{
FUNC_ENTER("CLbtDbTriggersManager::PrepareViewForTriggersL");
TPtr sql = iSqlQuery->Des();
sql.Zero();
if( !aTriggerIds.Count() )
{
User::Leave( KErrArgument );
return;
}
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtDbFieldId );
if( aTriggerIds.Count() == 1 )
{
sql.Append( KLike );
sql.AppendNum( aTriggerIds[0] );
}
else
{
// Find the max and min of trigger ids so that we get only thos triggers
// that fall into that bracket
TInt min = 0xFFFFFFFF;
TInt max = KLbtNullTriggerId;
for(TInt i=0;i<aTriggerIds.Count();++i)
{
if(aTriggerIds[i] < min)
{
min = aTriggerIds[i];
}
if(aTriggerIds[i] > max)
{
max = aTriggerIds[i];
}
}
sql.Append( KLessThanEqualTo );
sql.AppendNum( max );
sql.Append( KAnd );
sql.Append( KLbtDbFieldId );
sql.Append( KGreaterThanEqualTo );
sql.AppendNum( min );
}
TInt err = iDbOperation->ExecuteSyncQuery(aView, sql);
if( err != KErrNone )
{
aView.Close();
User::Leave(err);
return;
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::AsyncPrepareViewForTriggersL
// ---------------------------------------------------------------------------
//
TInt CLbtDbTriggersManager::AsyncPrepareViewForTriggers( const RArray<TLbtTriggerId>& aTriggerIds, RDbView& /*aView*/ )
{
FUNC_ENTER("CLbtDbTriggersManager::PrepareViewForTriggersL");
TPtr sql = iSqlQuery->Des();
sql.Zero();
if( !aTriggerIds.Count() )
{
return KErrArgument;
}
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtDbFieldId );
if( aTriggerIds.Count() == 1 )
{
sql.Append( KLike );
sql.AppendNum( aTriggerIds[0] );
}
else
{
// Find the max and min of trigger ids so that we get only thos triggers
// that fall into that bracket
TInt min = 0xFFFFFFFF;
TInt max = KLbtNullTriggerId;
for(TInt i=0;i<aTriggerIds.Count();++i)
{
if(aTriggerIds[i] < min)
{
min = aTriggerIds[i];
}
if(aTriggerIds[i] > max)
{
max = aTriggerIds[i];
}
}
sql.Append( KLessThanEqualTo );
sql.AppendNum( max );
sql.Append( KAnd );
sql.Append( KLbtDbFieldId );
sql.Append( KGreaterThanEqualTo );
sql.AppendNum( min );
}
iView.Close();
TInt err = iView.Prepare( iDb, TDbQuery(sql, EDbCompareFolded),KDbUnlimitedWindow );
// This should evaluate the query fully
if ( err == KErrNone )
{
iView.Evaluate(iStatus);
SetActive();
return KErrNone;
}
else
{
iView.Close();
return err;
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::IsFilterForDBTriggersL
// ---------------------------------------------------------------------------
//
TBool CLbtDbTriggersManager::IsFilterForDBTriggersL( CLbtTriggerFilterBase* aFilter )
{
if( aFilter == NULL )
{
return ETrue;
}
if( aFilter->Type() == CLbtTriggerFilterBase::EFilterByAttribute )
{
CLbtTriggerFilterByAttribute* attributeFilter =
static_cast<CLbtTriggerFilterByAttribute*>(aFilter);
RArray<CLbtTriggerEntry::TType> triggerTypeArray;
attributeFilter->GetTypeArrayL( triggerTypeArray );
if( triggerTypeArray.Count() )
{
// If the trigger type does not have startup triggers then return EFalse
if( !attributeFilter->IsTriggerTypeInFilter(CLbtTriggerEntry::ETypeStartup) )
{
return EFalse;
}
}
triggerTypeArray.Close();
}
return ETrue;
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::PrepareViewForListingL
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::PrepareViewForListingL( RDbView& aView )
{
FUNC_ENTER("CLbtDbTriggersManager::PrepareViewsL");
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KTriggersTable );
// As of now,create trigger operation on db side is implemented synchronously.So using Synchronous version.
TInt err = iDbOperation->ExecuteSyncQuery( aView, sql );
if( err != KErrNone )
{
aView.Close();
User::Leave(err);
return;
}
}
// ---------------------------------------------------------------------------
// Callback method that gets called when SQL Evaluation is completed.
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::DbSqlOperationCompletedL( TInt error )
{
FUNC_ENTER("CLbtDbTriggersManager::DbSqlOperationCompleted");
switch( iCurrentOperation )
{
case EDbOpCreateTrigger:
{
if ( KErrNone == error )
{
TRAP(error, CreateTriggerInViewL());
}
User::RequestComplete(iClientReqStatus, error);
iClientReqStatus = NULL;
if(KErrNone == error)
{
CompactDbIfRequiredL();
}
iCurrentOperation = EDbOpNone;
}
break;
default:
break;
}
}
// ---------------------------------------------------------------------------
// CLbtDbTriggersManager::AppendTriggerInfo
//
// Appends the trigger info into the triggers modified array which is used for
// notifying observers
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::AppendTriggerInfo(CLbtContainerTriggerEntry* aEntry)
{
FUNC_ENTER("CLbtDbTriggersManager::AppendTriggerInfo");
const CLbtTriggerConditionArea* conditionBase =
static_cast<const CLbtTriggerConditionArea*>(aEntry->TriggerEntry()->GetCondition());
CLbtGeoAreaBase* areaBase = conditionBase->TriggerArea();
TLbtTriggerModifiedInfo info;
info.iTriggerId = aEntry->TriggerEntry()->Id();
info.iAreaType = areaBase->Type();
info.iManagerUi = aEntry->TriggerEntry()->ManagerUi();
TSecureId sid = aEntry->ExtendedTriggerInfo()->OwnerSid();
TUid ownerUid;
ownerUid.iUid = (TInt)(sid.iId);
info.iOwner = ownerUid;
CLbtTriggerEntry* triggerEntry = aEntry->TriggerEntry();
if( triggerEntry->Type() == CLbtTriggerEntry::ETypeStartup)
{
CLbtStartupTrigger* startupTrigger = static_cast<CLbtStartupTrigger*>(triggerEntry);
TSecureId secureId;
TBuf16<KMaxFileName> fileName;
startupTrigger->GetProcessId(fileName, secureId);
TUid startupUid;
startupUid.iUid = (TInt)(sid.iId);
info.iStartupProcess = startupUid;
}
else
{
info.iStartupProcess = KNullUid;
}
iIdArray.Append(info);
}
// -----------------------------------------------------------------------------
// CLbtDbTriggersManager::TriggersModified
// -----------------------------------------------------------------------------
//
void CLbtDbTriggersManager::TriggersModified(RArray<TLbtTriggerModifiedInfo>& aArray)
{
for( TInt i = 0;i<iIdArray.Count();i++ )
{
aArray.Append(iIdArray[i]);
}
iIdArray.Reset();
}
// -----------------------------------------------------------------------------
// CLbtDbTriggersManager::ProcessListTriggers
// -----------------------------------------------------------------------------
//
void CLbtDbTriggersManager::ProcessListTriggers( CLbtContainerTriggerEntry* aEntry,
TLbtTriggerAttributeFieldsMask aAttrMask,
TLbtTriggerDynamicInfoFieldsMask aDynInfoMask,
TLbtTriggerDataMask aDataMask )
{
FUNC_ENTER("CLbtDbTriggersManager::ProcessListTriggers");
TLbtTriggerDynamicInfo* info = aEntry->DynInfo();
CLbtStartupTrigger* clientEntry = static_cast<CLbtStartupTrigger*>( aEntry->TriggerEntry() );
if( !(aDynInfoMask & TLbtTriggerDynamicInfo::EValidityStatus) )
{
info->iValidity = TLbtTriggerDynamicInfo::EInvalid;
}
if( !(aDynInfoMask & TLbtTriggerDynamicInfo::EDistanceToLatestLocation) )
{
info->iDistanceToLatestLocation = 0;
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeId ) )
{
clientEntry->SetId(0);
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeName) )
{
TRAP_IGNORE(clientEntry->SetNameL(KNullDesC));
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeState) )
{
clientEntry->SetState(CLbtTriggerEntry::EStateEnabled);
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeRequestor) )
{
// TBD
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeManagerUi) )
{
TUid managerUi = TUid::Null();
clientEntry->SetManagerUi(managerUi);
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeCondition) )
{
CLbtTriggerConditionBase* condBase = clientEntry->GetCondition();
clientEntry->SetCondition(NULL);
}
if( !(aAttrMask & CLbtTriggerEntry::EAttributeStartUpProcessId) )
{
TSecureId sid(0);
clientEntry->SetProcessId( KNullDesC, sid );
}
if( !(aDataMask & CLbtContainerTriggerEntry::EContainerAttributeRectTriggerArea) )
{
}
}
//-------------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::CompactDbIfRequiredL
//-------------------------------------------------------------------------------------------------
//
void CLbtDbTriggersManager::CompactDbIfRequiredL()
{
FUNC_ENTER("CLbtDbTriggersManager::CompactDbIfRequiredL");
// First update the stats to get the accurate db size information
User::LeaveIfError(iDb.UpdateStats());
RDbDatabase::TSize size = iDb.Size();
TReal wastedBytes = size.iSize * static_cast<TReal>(100 - size.iUsage)/100;
// Check if the amount of legitimate data present in less than the minimum usage percentage
if( size.iUsage < KDatabaseMinUsagePercentage &&
wastedBytes > KDatabaseMaxWastageBytes )
{
TTime currentTime;
// Get the current time
currentTime.UniversalTime();
// Find the seconds we have to compact
TTimeIntervalSeconds seconds;
TInt error = currentTime.SecondsFrom(iTimeTillCompaction, seconds);
// If error is not equal to KErrNone that means that iTimeTillCompaction has not been set appropriately
if(seconds > KSecondsNeededForCompaction || error != KErrNone)
{
// Compaction is needed
iDbOperation->CompactDb();
}
}
}
//-------------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::HandleListTriggersEventL
//-------------------------------------------------------------------------------------------------
//
void CLbtDbTriggersManager::HandleListTriggersEventL( )
{
FUNC_ENTER("CLbtDbTriggersManager::HandleListTriggersEventL");
/**
* Once control reaches here it means that the Db Query
* "Select * From table Triggers" has been executed and
* the view contains all the rows.
*/
CLbtListTriggerOptions* listOptions = iFilter->ListOptions();
TLbtTriggerAttributeFieldsMask attrMask;
TLbtTriggerDynamicInfoFieldsMask dynInfoMask;
listOptions->GetRetrievedFields(attrMask,dynInfoMask);
TLbtTriggerDataMask dataMask = iFilter->DataMask();
TUid ownerSid;
TUid managerUi;
TSecureId startupSid;
TInt count = 0;
while( iView.AtRow() && count < KStepCount )
{
++count;
iView.GetL();
ownerSid.iUid = iView.ColUint32(ELbtDbFieldOwnerSid);
managerUi.iUid = iView.ColUint32(ELbtDbFieldManagerUiSid);
startupSid.iId = iView.ColUint32(ELbtDbFieldStartupSid);
if( LbtContainerUtilities::RunSecurityPolicy( ownerSid,
managerUi,
startupSid,
iClientSecurityPolicy ) )
{
CLbtContainerTriggerEntry* entry = RetrieveTriggerEntryFromDbL( iView );
TInt isFilterPresent = 0;
TBool isEntryRequested = EFalse;
iFilterBase->ProcessFilter(entry, isFilterPresent, isEntryRequested);
if(isFilterPresent > 0 && isEntryRequested)
{
ProcessListTriggers(entry,attrMask,dynInfoMask,dataMask);
iTriggers->Append(entry);
}
else
{
delete entry;
}
}
iView.NextL();
}
if( count >= KStepCount )
{
// Self complete to process next request
SelfComplete();
}
else // Operation is over
{
if(iTriggers->Count() == 0)
{
CompleteClientRequest( KErrNotFound );
}
else
{
CompleteClientRequest( KErrNone );
}
}
}
// ---------------------------------------------------------------------------
// Callback method that is called when an Incremental operation is executed
// on the database (like database compaction, recovery)
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::DbIncrementalOperationCompleted( TInt /*aError*/ )
{
FUNC_ENTER("CLbtDbTriggersManager::DbIncrementalOperationCompleted");
switch( iCurrentOperation )
{
case EDbOpCreateTrigger:
{
// Even if there is an error, it just means that Db Compaction
// failed. So lets try Create trigger once more even in case of
// failure. There is a remote possibility that some other process
// might have done some cleanup and created enough space for this
// trigger. So ignoring the error from compaction action here
// deliberately.
TInt error = KErrNone;
TRAP( error, HandleTriggerCreationEventL() );
if( error != KErrNone )
{
CompleteClientRequest( error );
}
}
break;
default:
{
// Notfy the client that we are ready to serve requests again
iObserver->NotifyTriggerStoreReadyToServe();
break;
}
}
}
// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CLbtDbTriggersManager::CLbtDbTriggersManager( )
: CActive(CActive::EPriorityStandard),
iDbOperation( NULL ),
iSqlQuery( NULL ),
iCurrentOperation( EDbOpNone ),
iOperationState( EOpStateNone ),
iFilterBase( NULL )
{
CActiveScheduler::Add(this);
iIdArray.Reset();
iCountOfEnabledAndValidTrigger=0;
}
// ---------------------------------------------------------------------------
// The 2nd phase Symbian Constructor
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::ConstructL()
{
FUNC_ENTER("CLbtDbTriggersManager::ConstructL");
// db has not been opened yet
iIsDbOpened = EFalse;
// Can't do much if the file server open fails. Hence just leave
// with that error code.
User::LeaveIfError(iFs.Connect());
// Obtain the Db file path
TFileName dbFile;
iFs.SessionPath(dbFile);
// Create the Database Directory ie the private directory of the process
iFs.MkDirAll(dbFile);
// Generate the Db file
dbFile.Append(KLbtDbName);
// Initialize the Database
TInt error = iDb.Open(iFs, dbFile);
if ( error == KErrNotFound )
{
// The Db does not exist. Create the Db file
User::LeaveIfError(iDb.Create(iFs, dbFile));
CreateTablesInDbL();
}
else
{
User::LeaveIfError( error );
}
// Successfully opened db
iIsDbOpened = ETrue;
// Create the Db Operation Active Object
iDbOperation = CLbtDbOperationAO::NewL(iDb, this);
// Allocate the SQL Query String
iSqlQuery = HBufC::NewL(KMaxSqlQueryLength);
iObserver = NULL;
// List the set of all enabled and valid triggers
RDbView view;
TPtr sql = iSqlQuery->Des();
sql.Zero();
sql.Append( KSelect );
sql.Append( KSelectAllFields );
sql.Append( KFrom );
sql.Append( KTriggersTable );
sql.Append( KWhere );
sql.Append( KLbtDbFieldValidity );
sql.Append( KLike );
sql.AppendNum( TLbtTriggerDynamicInfo::EValid );
sql.Append( KAnd );
sql.Append( KLbtDbFieldState );
sql.Append( KLike );
sql.AppendNum( CLbtTriggerEntry::EStateEnabled );
CleanupClosePushL( view );
User::LeaveIfError( iDbOperation->ExecuteSyncQuery( view, sql ) );
iCountOfEnabledAndValidTrigger = view.CountL();
CleanupStack::PopAndDestroy(1); // view
}
// ---------------------------------------------------------------------------
// Create the Table in the Database as part of initialization of Container
// ---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::CreateTablesInDbL( )
{
FUNC_ENTER("CLbtDbTriggersManager::CreateTablesInDbL");
CreateCommonTriggerAttributesTableL();
CreateCoordinateTriggersTableL();
CreateCellTriggersTableL();
CreateHybridTriggersTableL();
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::CreateCommonTriggerAttributesTableL
// --------------------------------------------------------------------------------------------
void CLbtDbTriggersManager::CreateCommonTriggerAttributesTableL()
{
CDbColSet* triggerColSet = CDbColSet::NewLC();
// Id
triggerColSet->AddL(TDbCol(KLbtDbFieldId, EDbColInt64));
// Name
triggerColSet->AddL(TDbCol(KLbtDbFieldName, EDbColText16, KLbtMaxNameLength - 1));
// Trigger Type
triggerColSet->AddL(TDbCol(KLbtDbFieldType, EDbColInt8));
// direction of Trigger (Entry type or Exit type)
triggerColSet->AddL(TDbCol(KLbtDbFieldDirection, EDbColInt8));
// SID of the Trigger Creator
triggerColSet->AddL(TDbCol(KLbtDbFieldOwnerSid, EDbColUint32));
// SID of the Manager UI for this trigger
triggerColSet->AddL(TDbCol(KLbtDbFieldManagerUiSid, EDbColUint32));
// Time to rearm a trigger
triggerColSet->AddL(TDbCol(KLbtDbFieldRearmTime, EDbColInt32));
// SID of the trigger handling process
triggerColSet->AddL(TDbCol(KLbtDbFieldStartupSid, EDbColUint32));
// Absolute path of the trigger handling process
triggerColSet->AddL(TDbCol(KLbtDbFieldStartupPath, EDbColText16));
// Commandline parameters for the trigger handling process
triggerColSet->AddL(TDbCol(KLbtDbFieldStartupCommandLine, EDbColText16));
// State of the trigger
triggerColSet->AddL(TDbCol(KLbtDbFieldState, EDbColInt8));
// Bool for trigger fire event
triggerColSet->AddL(TDbCol(KLbtDbFieldIsTriggerFired, EDbColBit));
// The distance of this trigger from the last acquired location in strategy
triggerColSet->AddL(TDbCol(KLbtDbFieldDistanceToLastLocation, EDbColReal32));
// Validity of the trigger
triggerColSet->AddL(TDbCol(KLbtDbFieldValidity, EDbColInt8));
// Trigger Fire on creation flag.
triggerColSet->AddL(TDbCol(KLbtDbFieldIsTriggerFireOnCreation, EDbColBit));
// Trigger Area type ( Cell/Circular)
triggerColSet->AddL(TDbCol(KLbtDbTriggerAreaType, EDbColInt8));
User::LeaveIfError( iDb.CreateTable( KTriggersTable, *triggerColSet ) );
// Create index key set based on Trigger Id
CDbKey* index = CDbKey::NewLC();
index->AddL(TDbKeyCol(KLbtDbFieldId));
index->AddL(TDbKeyCol(KLbtDbFieldOwnerSid));
User::LeaveIfError(iDb.CreateIndex(KTriggersIndexId, KTriggersTable, *index));
CleanupStack::PopAndDestroy( 2 ); // index & triggerColSet
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::CreateCoordinateTriggersTableL
// --------------------------------------------------------------------------------------------
void CLbtDbTriggersManager::CreateCoordinateTriggersTableL()
{
CDbColSet* circTriggerColSet = CDbColSet::NewLC();
// Id
circTriggerColSet->AddL(TDbCol(KLbtCircTrigDbFieldId, EDbColInt64));
// Trigger Condition center latitude
circTriggerColSet->AddL(TDbCol(KLbtDbFieldCenterLat, EDbColReal64));
// Trigger Condition center longitude
circTriggerColSet->AddL(TDbCol(KLbtDbFieldCenterLong, EDbColReal64));
// Trigger Condition radius
circTriggerColSet->AddL(TDbCol(KLbtDbFieldRadius, EDbColReal64));
// Trigger Condition Hysteresis radius
circTriggerColSet->AddL(TDbCol(KLbtDbFieldHysteresis, EDbColReal64));
// The Square approximation of the trigger condition area. Used by
// supervision for better supervision alogrithm.
circTriggerColSet->AddL(TDbCol(KLbtDbFieldAreaLeft, EDbColReal64));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldAreaRight, EDbColReal64));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldAreaTop, EDbColReal64));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldAreaBottom, EDbColReal64));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldTriggerFiredLat, EDbColReal64));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldTriggerFiredLong, EDbColReal64));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldTriggerFiredAlt, EDbColReal32));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldTriggerFiredHorizAcc, EDbColReal32));
circTriggerColSet->AddL(TDbCol(KLbtDbFieldTriggerFiredVertAcc, EDbColReal32));
// Cell id stream for cell ids of the area. Hybrid info
circTriggerColSet->AddL(TDbCol(KLbtDbFieldCellIdStream, EDbColLongText8));
User::LeaveIfError( iDb.CreateTable( KCircularTriggersTable, *circTriggerColSet ) );
// Create index key set based on Trigger Id
CDbKey* circindex = CDbKey::NewLC();
circindex->AddL( TDbKeyCol(KLbtCircTrigDbFieldId) );
User::LeaveIfError( iDb.CreateIndex(KCircTriggersIndexId, KCircularTriggersTable, *circindex) );
CleanupStack::PopAndDestroy( 2 ); // circindex & circTriggerColSet
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::CreateCellTriggersTableL
// --------------------------------------------------------------------------------------------
void CLbtDbTriggersManager::CreateCellTriggersTableL( )
{
CDbColSet* cellTriggerColSet = CDbColSet::NewLC();
// Cell Based Triggering : Create new col set for cell triggers and add fields
// Id
cellTriggerColSet->AddL(TDbCol(KLbtCellTrigDbFieldId, EDbColInt64));
// MCC
cellTriggerColSet->AddL(TDbCol(KLbtCellTrigDbCountryCode, EDbColUint32));
// MNC
cellTriggerColSet->AddL(TDbCol(KLbtCellTrigDbNetworkId, EDbColUint32));
// Network Type (GSM/WCDMA)
cellTriggerColSet->AddL(TDbCol(KLbtCellTrigDbNetworkType, EDbColInt8));
// LAC
cellTriggerColSet->AddL(TDbCol(KLbtCellTrigDbLAC, EDbColUint32));
// Cell ID
cellTriggerColSet->AddL(TDbCol(KLbtCellTrigDbCellId, EDbColUint32));
User::LeaveIfError( iDb.CreateTable( KCellTriggersTable, *cellTriggerColSet ) );
CleanupStack::PopAndDestroy( cellTriggerColSet );
// Create index key set based on Trigger Id
CDbKey* cellindex = CDbKey::NewLC();
cellindex->AddL(TDbKeyCol(KLbtCellTrigDbFieldId));
User::LeaveIfError(iDb.CreateIndex(KCellTriggersIndexId, KCellTriggersTable, *cellindex));
CleanupStack::PopAndDestroy(cellindex);
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::CreateHybridTriggersTableL
// --------------------------------------------------------------------------------------------
void CLbtDbTriggersManager::CreateHybridTriggersTableL()
{
// Hybrid Triggers table : Create new column set
CDbColSet* hybridTriggerColSet = CDbColSet::NewLC();
// Id
hybridTriggerColSet->AddL( TDbCol(KLbtHybridTrigDbFieldId, EDbColUint32) );
// Hybrid area base stream
hybridTriggerColSet->AddL( TDbCol(KLbtHybridDataStream, EDbColLongText8) );
User::LeaveIfError( iDb.CreateTable( KHybridTriggersTable, *hybridTriggerColSet ) );
CleanupStack::PopAndDestroy( hybridTriggerColSet );
// Create index key set based on Trigger Id
CDbKey* cellindex = CDbKey::NewLC();
cellindex->AddL( TDbKeyCol(KLbtHybridTrigDbFieldId) );
User::LeaveIfError( iDb.CreateIndex(KHybridTriggersIndexId, KHybridTriggersTable, *cellindex) );
CleanupStack::PopAndDestroy(cellindex);
}
// --------------------------------------------------------------------------------------------
// CLbtDbTriggersManager::CreateTriggerInViewL
// --------------------------------------------------------------------------------------------
void CLbtDbTriggersManager::CreateTriggerInViewL()
{
FUNC_ENTER("CLbtDbTriggersManager::CreateTriggerInViewL");
CLbtStartupTrigger* trigger = static_cast<CLbtStartupTrigger* >(iEntry->TriggerEntry());
TLbtTriggerDynamicInfo* dynInfo = iEntry->DynInfo();
CLbtExtendedTriggerInfo* extdInfo = iEntry->ExtendedTriggerInfo();
CLbtTriggerConditionArea* cond = static_cast<CLbtTriggerConditionArea* >(trigger->GetCondition());
CLbtGeoAreaBase * areaBase = cond->TriggerArea();
CLbtGeoCircle* area = static_cast<CLbtGeoCircle* >(cond->TriggerArea());
// Insert a Row in the View
iView.InsertL(); // Insert a row. Column order matches sql select statement
/* Cell Based Triggering : add fields in the various views based on the field values*/
iView.SetColL( ELbtDbFieldId, static_cast<TInt64>(trigger->Id()) );
iView.SetColL( ELbtDbFieldName, trigger->Name() );
iView.SetColL( ELbtDbFieldType, static_cast<TInt8>(trigger->Type()) );
iView.SetColL( ELbtDbFieldDirection, static_cast<TInt8>((cond->Direction())) );
iView.SetColL( ELbtDbFieldOwnerSid, extdInfo->OwnerSid().iId );
iView.SetColL( ELbtDbFieldManagerUiSid, static_cast<TUint32>(trigger->ManagerUi().iUid) );
iView.SetColL( ELbtDbFieldRearmTime, trigger->TimeToRearm() );
HBufC* startupProcFile = HBufC::NewLC( KMaxFileName );
TPtr startupFile = startupProcFile->Des();
TSecureId startupProcSid;
trigger->GetProcessId( startupFile, startupProcSid );
iView.SetColL( ELbtDbFieldStartupSid, startupProcSid );
iView.SetColL( ELbtDbFieldStartupPath, *startupProcFile );
CleanupStack::PopAndDestroy( startupProcFile );
iView.SetColL( ELbtDbFieldStartupCommandLine, trigger->CommandLine() );
iView.SetColL( ELbtDbFieldState, trigger->State() );
iView.SetColL(ELbtDbFieldIsTriggerFired, extdInfo->IsTriggerFired());
iView.SetColL(ELbtDbFieldDistanceToLastLocation, static_cast<TReal32>(0.0) );
iView.SetColL( ELbtDbFieldValidity, static_cast<TInt8>(dynInfo->iValidity) );
iView.SetColL( ELbtDbFieldIsTriggerFireOnCreation, extdInfo->IsTriggerFireOnCreation() );
/* add local enum */
iView.SetColL(ELbtDbTriggerAreaType,static_cast<TInt8>(areaBase->Type() ));
iView.PutL(); // Complete insertion
iView.Close();
switch(areaBase->Type())
{
case CLbtGeoAreaBase::ECircle:
{
AddGeoCircleIntoDbL(trigger);
break;
}
case CLbtGeoAreaBase::ECellular:
{
AddGeoCellIntoDbL(trigger);
break;
}
case CLbtGeoAreaBase::EHybrid:
{
AddGeoHybridIntoDbL(trigger);
break;
}
default:
{
break;
}
}
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::GetCountOfEnabledAndValidTriggers
//---------------------------------------------------------------------------
//
TInt CLbtDbTriggersManager::GetCountOfEnabledAndValidTriggers()
{
return iCountOfEnabledAndValidTrigger;
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::SetTimeTillCompaction
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::SetTimeTillCompaction(TTime aTime)
{
iTimeTillCompaction = aTime;
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::IsStoreBusy
//---------------------------------------------------------------------------
//
TBool CLbtDbTriggersManager::IsStoreBusy()
{
return iDbOperation->IsCompactionOngoing();
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::SetStoreChangeObserver
//---------------------------------------------------------------------------
//
void CLbtDbTriggersManager::SetStoreChangeObserver(MLbtTriggerStoreObserver* aObserver)
{
iObserver = aObserver;
}
//---------------------------------------------------------------------------
// CLbtDbTriggersManager::CancelCurrentOperation
//---------------------------------------------------------------------------
//
TInt CLbtDbTriggersManager::CancelCurrentOperation()
{
TInt error = KErrCancel;
switch( iCurrentOperation )
{
case EDbOpDeleteTriggers:
{
if( !iView.AtEnd() && !iView.AtBeginning() )
{
error = KLbtErrPartial;
}
break;
}
case EDbOpUpdateTriggersState:
{
if( !iView.AtEnd() && !iView.AtBeginning() )
{
error = KLbtErrPartial;
}
break;
}
}
CompleteClientRequest( KErrCancel );
Cancel();
return error;
}
// end of file