os/persistentdata/loggingservices/eventlogger/LogServ/src/LOGADD.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <s32file.h>
sl@0
    17
#include <logcntmodel.h>
sl@0
    18
#include <logengevents.h>
sl@0
    19
#include "LOGADD.H"
sl@0
    20
#include "logservpanic.h"
sl@0
    21
#include "LOGDUP.H"
sl@0
    22
#include "LOGQUERY.H"
sl@0
    23
#include "LogServRecentList.h"
sl@0
    24
#include "LogServDatabaseTransactionInterface.h"
sl@0
    25
#include "LogServResourceInterpreter.h"
sl@0
    26
#include "LogServCacheConfig.h"
sl@0
    27
#include "LogServDatabaseChangeInterface.h"
sl@0
    28
#include <centralrepository.h>
sl@0
    29
#include "LogServCacheStrings.h"
sl@0
    30
#include "LogServCacheTypes.h"
sl@0
    31
#include "LOGREPDEFS.H"
sl@0
    32
sl@0
    33
const TInt KMinimumNumberOfDigitsToMatch = 3;
sl@0
    34
sl@0
    35
////////////////////////////////////////////////////////////////////////////////////////////
sl@0
    36
// Local functions
sl@0
    37
sl@0
    38
#ifdef SYSLIBS_TEST
sl@0
    39
sl@0
    40
#pragma BullseyeCoverage off
sl@0
    41
sl@0
    42
static void LogStore32IntL(RFs& aFs, const TDesC& aFilePath, TInt aVal)
sl@0
    43
	{
sl@0
    44
	RFile file;
sl@0
    45
	User::LeaveIfError(file.Replace(aFs, aFilePath, EFileWrite));
sl@0
    46
	TPtrC8 p((const TUint8*)&aVal, sizeof(aVal));
sl@0
    47
	TInt err = file.Write(p);
sl@0
    48
	if(err == KErrNone)
sl@0
    49
		{
sl@0
    50
		err = file.Flush();
sl@0
    51
		}
sl@0
    52
	file.Close();
sl@0
    53
	User::LeaveIfError(err);
sl@0
    54
	}
sl@0
    55
sl@0
    56
static void LogStoreContactMatchCountAndNameFormatL(TInt aContactMatchCount, TLogContactNameFormat aContactNameFormat)
sl@0
    57
	{
sl@0
    58
	RFs fs;
sl@0
    59
	CleanupClosePushL(fs);
sl@0
    60
	User::LeaveIfError(fs.Connect());
sl@0
    61
sl@0
    62
	_LIT(KTestDir, "c:\\test\\");
sl@0
    63
	TInt err = fs.MkDir(KTestDir);
sl@0
    64
	if(err != KErrNone && err != KErrAlreadyExists)
sl@0
    65
		{
sl@0
    66
		User::Leave(err);
sl@0
    67
		}
sl@0
    68
	
sl@0
    69
	_LIT(KLogengTestFileNameCount, "c:\\test\\test_logengconfig_count.ini");
sl@0
    70
	LogStore32IntL(fs, KLogengTestFileNameCount, aContactMatchCount);
sl@0
    71
	
sl@0
    72
	_LIT(KLogengTestFileNameFormat, "c:\\test\\test_logengconfig_format.ini");
sl@0
    73
	LogStore32IntL(fs, KLogengTestFileNameFormat, (TInt)aContactNameFormat);
sl@0
    74
	
sl@0
    75
	CleanupStack::PopAndDestroy(&fs);
sl@0
    76
	}
sl@0
    77
sl@0
    78
#pragma BullseyeCoverage on
sl@0
    79
sl@0
    80
#endif //SYSLIBS_TEST
sl@0
    81
sl@0
    82
//This function reads logeng repository file and returns the integer value of the given key. 
sl@0
    83
static TInt LogGetRepositoryValueL(CRepository& aRepository, TInt aKey)
sl@0
    84
	{		
sl@0
    85
	TInt val = -1;		
sl@0
    86
	User::LeaveIfError(aRepository.Get(aKey, val));
sl@0
    87
	return val;
sl@0
    88
	}
sl@0
    89
sl@0
    90
static void LogGetContactmatchCountAndNameFormatL(TInt& aContactMatchCount, TLogContactNameFormat& aContactNameFormat)
sl@0
    91
	{
sl@0
    92
	CRepository* repository = NULL;
sl@0
    93
	TRAPD(err, repository = CRepository::NewL(KUidLogengRepository));		
sl@0
    94
	if(err == KErrNone)
sl@0
    95
		{
sl@0
    96
		CleanupStack::PushL(repository);
sl@0
    97
		aContactMatchCount = LogGetRepositoryValueL(*repository, KContactMatchCountRepKey);
sl@0
    98
		aContactNameFormat = static_cast <TLogContactNameFormat> (LogGetRepositoryValueL(*repository, KContactNameFormatRepKey));
sl@0
    99
		CleanupStack::PopAndDestroy(repository);
sl@0
   100
		}
sl@0
   101
	else if(err == KErrCorrupt)
sl@0
   102
		{
sl@0
   103
		__ASSERT_DEBUG(!repository, User::Invariant());
sl@0
   104
		User::Leave(err);
sl@0
   105
		}
sl@0
   106
	else
sl@0
   107
		{
sl@0
   108
		__ASSERT_DEBUG(!repository, User::Invariant());
sl@0
   109
		aContactMatchCount = KLogContactMatchCount;
sl@0
   110
		aContactNameFormat = KLogContactNameFormat;
sl@0
   111
		}
sl@0
   112
	#ifdef SYSLIBS_TEST
sl@0
   113
	LogStoreContactMatchCountAndNameFormatL(aContactMatchCount, aContactNameFormat);
sl@0
   114
	#endif	
sl@0
   115
	}
sl@0
   116
sl@0
   117
////////////////////////////////////////////////////////////////////////////////////////////
sl@0
   118
// CLogAddEvent class
sl@0
   119
sl@0
   120
CLogAddEvent::CLogAddEvent(MLogServDatabaseTransactionInterface& aDatabase, TInt aPriority) :
sl@0
   121
	CLogActive(aPriority), 
sl@0
   122
	iDatabase(aDatabase)
sl@0
   123
	{
sl@0
   124
	}
sl@0
   125
sl@0
   126
CLogAddEvent::~CLogAddEvent()
sl@0
   127
	{
sl@0
   128
	Cancel();
sl@0
   129
	
sl@0
   130
	CloseContactsPlugin();
sl@0
   131
sl@0
   132
	delete iDuplicate;
sl@0
   133
	delete iDuplicateFilter;
sl@0
   134
	}
sl@0
   135
sl@0
   136
CLogAddEvent* CLogAddEvent::NewL(MLogServDatabaseTransactionInterface& aDatabase, TInt aPriority)
sl@0
   137
	{
sl@0
   138
	CLogAddEvent* self = new(ELeave) CLogAddEvent(aDatabase, aPriority);
sl@0
   139
	CleanupStack::PushL(self);
sl@0
   140
	self->ConstructL();
sl@0
   141
	CleanupStack::Pop(self);
sl@0
   142
	return self;
sl@0
   143
	}
sl@0
   144
sl@0
   145
void CLogAddEvent::ConstructL()
sl@0
   146
	{
sl@0
   147
	iDuplicate = CLogDuplicate::NewL(iDatabase, Priority());
sl@0
   148
	iDuplicateFilter = CLogFilter::NewL();
sl@0
   149
	::LogGetContactmatchCountAndNameFormatL(iContactMatchCount, iContactNameFormat);
sl@0
   150
	}
sl@0
   151
sl@0
   152
//This method will open contacts database (if not opened yet), only if the value of 
sl@0
   153
//iContactMatchCount is not 0.
sl@0
   154
//Se how iContactMatchCount data member is initialised.
sl@0
   155
TBool CLogAddEvent::PerformContactMatchL()
sl@0
   156
	{
sl@0
   157
	if (iContactMatchCount <= 0 || iEvent->Contact() != KLogNullContactId)
sl@0
   158
		return EFalse;
sl@0
   159
	
sl@0
   160
	if (iContactPlugin)
sl@0
   161
		return ETrue;
sl@0
   162
	
sl@0
   163
	// Attempt to load plugin
sl@0
   164
	TRAPD( err, iContactPlugin=CLogCntModel::NewL());
sl@0
   165
sl@0
   166
	// If plugin doesn't exist this is equivalent to matching being disabled so we don't leave
sl@0
   167
	// for KErrNotFound
sl@0
   168
	if(err==KEComErrNoInterfaceIdentified)
sl@0
   169
		{
sl@0
   170
		// Disable contacts matching so that we don't keep attempting to match
sl@0
   171
		iContactMatchCount = 0;
sl@0
   172
		// Plugin doesn't exist
sl@0
   173
		return EFalse;
sl@0
   174
		}
sl@0
   175
sl@0
   176
	User::LeaveIfError(err);
sl@0
   177
	
sl@0
   178
	// Open the DB
sl@0
   179
	OpenContactsL();
sl@0
   180
	
sl@0
   181
	return ETrue;
sl@0
   182
	}
sl@0
   183
sl@0
   184
void CLogAddEvent::StartL(CLogEvent& aEvent, const CLogServRecentList* aRecentList, TRequestStatus& aStatus, const RMessage2& aMessage)
sl@0
   185
	{
sl@0
   186
	__ASSERT_ALWAYS(!IsActive(), Panic(ELogAlreadyActive1));
sl@0
   187
sl@0
   188
	LOGTEXT("CLogAddEvent::StartL()");
sl@0
   189
sl@0
   190
	// Store event details which were obtained from the client side
sl@0
   191
	iEvent = &aEvent;
sl@0
   192
	iState = ELogAddEvent;
sl@0
   193
	
sl@0
   194
	if (!iDatabase.DTIIsAllowed(EWriteOp, aMessage, iEvent->EventType()))
sl@0
   195
		{
sl@0
   196
		User::Leave(KErrPermissionDenied);
sl@0
   197
		}
sl@0
   198
sl@0
   199
	if (PerformContactMatchL())
sl@0
   200
		iState = ELogSetContactAndRemoteParty; // Go look for a matching contact
sl@0
   201
sl@0
   202
	iRecentList = aRecentList;
sl@0
   203
	iEventAdded = EFalse;
sl@0
   204
sl@0
   205
	// Setup the event's time (UTC)
sl@0
   206
	TTime time;
sl@0
   207
	time.UniversalTime();
sl@0
   208
	iEvent->SetTime(time);
sl@0
   209
sl@0
   210
	// Save the observer's request status and set it to KRequestPending
sl@0
   211
	Queue(aStatus);
sl@0
   212
sl@0
   213
	// Start this objects RunL chain
sl@0
   214
	TRequestStatus* status = &iStatus;
sl@0
   215
	User::RequestComplete(status, KErrNone);
sl@0
   216
	SetActive();
sl@0
   217
	}
sl@0
   218
	
sl@0
   219
void CLogAddEvent::SetEventContact()
sl@0
   220
    {
sl@0
   221
    // Start by converting the phone number text into a number
sl@0
   222
    // check we've got a long enough number to be worth checking
sl@0
   223
    if(iEvent->Number().Length() >= KMinimumNumberOfDigitsToMatch)
sl@0
   224
        {
sl@0
   225
        // now search for a contact by looking up the phone number
sl@0
   226
        TLogContactItemId contactId = KLogNullContactId;
sl@0
   227
        TRAPD(err, contactId = iContactPlugin->MatchPhoneNumberL(iEvent->Number(), iContactMatchCount));
sl@0
   228
        
sl@0
   229
        if(err == KErrNone)
sl@0
   230
            {
sl@0
   231
            // we have at least one match
sl@0
   232
            if(contactId != KLogNullContactId)
sl@0
   233
                {
sl@0
   234
                // we have a match so set the contact id
sl@0
   235
                iEvent->SetContact(contactId);
sl@0
   236
                }
sl@0
   237
            }
sl@0
   238
        }
sl@0
   239
    iEvent->SetFlags(KLogEventContactSearched);
sl@0
   240
    }
sl@0
   241
sl@0
   242
void CLogAddEvent::SetRemoteParty()
sl@0
   243
    {
sl@0
   244
    // Get the contact id
sl@0
   245
    TLogContactItemId  contactId = iEvent->Contact();
sl@0
   246
    if((contactId != KLogNullContactId) && (iEvent->RemoteParty().Length() == 0))
sl@0
   247
        {
sl@0
   248
        // Look it up and get the remote party info
sl@0
   249
        // Setup buffer to contain concatenated result
sl@0
   250
        TBuf<128> buf;
sl@0
   251
        // Go get the info
sl@0
   252
        TRAPD(err, iContactPlugin->ReadContactNameL(contactId, buf, iContactNameFormat));
sl@0
   253
sl@0
   254
        if(err == KErrNotFound)
sl@0
   255
            {
sl@0
   256
            // Couldn't find the contact with that id so set it to NULL
sl@0
   257
            iEvent->SetContact(KLogNullContactId);
sl@0
   258
            }
sl@0
   259
        else
sl@0
   260
            {
sl@0
   261
            // Found it so fill in remote party
sl@0
   262
            iEvent->SetRemoteParty(buf);
sl@0
   263
            }
sl@0
   264
        }
sl@0
   265
    }
sl@0
   266
sl@0
   267
void CLogAddEvent::GetConfigL()
sl@0
   268
    {
sl@0
   269
    iConfig = iDatabase.DTICacheConfig().Config();
sl@0
   270
    if(iConfig.iMaxLogSize == 0)
sl@0
   271
      {
sl@0
   272
      LOGTEXT("CLogAddEvent::DoRunL() - logging disabled");
sl@0
   273
      User::Leave(KErrNotSupported);
sl@0
   274
      }
sl@0
   275
    }
sl@0
   276
sl@0
   277
TLogTypeId CLogAddEvent::SetDescriptionL()
sl@0
   278
    {
sl@0
   279
    const TLogServCacheTypeEntry& entry = iDatabase.DTICacheTypes().FindByUid(iEvent->EventType());
sl@0
   280
    if(entry.iEventTypeId == KLogNullTypeId)
sl@0
   281
        {
sl@0
   282
        LOGTEXT("CLogAddEvent::DoRunL() - type not found");
sl@0
   283
        User::Leave(KErrNotFound);
sl@0
   284
        }
sl@0
   285
    if(!entry.iEventType->LoggingEnabled())
sl@0
   286
        {
sl@0
   287
        LOGTEXT("CLogAddEvent::DoRunL() - type not enabled");
sl@0
   288
        User::Leave(KErrNotSupported);
sl@0
   289
        }
sl@0
   290
    iEvent->SetDescription(entry.iEventType->Description());
sl@0
   291
    return entry.iEventTypeId;
sl@0
   292
    }
sl@0
   293
    
sl@0
   294
TBool CLogAddEvent::DetectDuplicateEventsL()
sl@0
   295
    {
sl@0
   296
    TBool rc = EFalse;
sl@0
   297
    if(iRecentList)
sl@0
   298
        {
sl@0
   299
        iRecentList->GetFilter(*iEvent, *iDuplicateFilter);
sl@0
   300
        rc = iDuplicate->StartL(iEvent->Id(), iRecentList->Id(), *iDuplicateFilter, iStatus);
sl@0
   301
        }
sl@0
   302
    return rc;
sl@0
   303
    }
sl@0
   304
sl@0
   305
void CLogAddEvent::DoRunL()
sl@0
   306
	{
sl@0
   307
	LOGTEXT3("CLogAddEvent::DoRunL(%d), state = %d", iStatus.Int(), iState);
sl@0
   308
sl@0
   309
	switch (iState)
sl@0
   310
		{
sl@0
   311
		case ELogSetContactAndRemoteParty:
sl@0
   312
			{
sl@0
   313
			SetEventContact();
sl@0
   314
			SetRemoteParty();
sl@0
   315
			TRequestStatus* status = &iStatus;
sl@0
   316
			User::RequestComplete(status, KErrNone);
sl@0
   317
			iState = ELogAddEvent;
sl@0
   318
			SetActive();
sl@0
   319
			break;
sl@0
   320
			}
sl@0
   321
		case ELogAddEvent:
sl@0
   322
			{
sl@0
   323
			GetConfigL();
sl@0
   324
			TLogTypeId typeId = SetDescriptionL();
sl@0
   325
			RLogEventDbTable tbl;
sl@0
   326
			tbl.OpenLC(iDatabase.DTIDatabase());
sl@0
   327
			::LogPurgeMainL(iDatabase, tbl, iConfig.iMaxLogSize, 1);
sl@0
   328
			DoAddEventL(tbl, typeId, iDatabase.DTICacheStrings().GetIdL(iEvent->Direction()), iDatabase.DTICacheStrings().GetIdL(iEvent->Status()));
sl@0
   329
            CleanupStack::PopAndDestroy();//tbl
sl@0
   330
			iEventAdded = ETrue;
sl@0
   331
			if(DetectDuplicateEventsL())
sl@0
   332
			    {
sl@0
   333
                iState = ELogPurgeRecent;
sl@0
   334
                SetActive();
sl@0
   335
                break;
sl@0
   336
			    }
sl@0
   337
			iState = ELogPurgeRecent;
sl@0
   338
			TRequestStatus* status = &iStatus;
sl@0
   339
			User::RequestComplete(status, KErrNone);
sl@0
   340
			SetActive();
sl@0
   341
			break;
sl@0
   342
			}
sl@0
   343
		case ELogPurgeRecent:
sl@0
   344
			{
sl@0
   345
			// Delete old recent events
sl@0
   346
			if (iRecentList)
sl@0
   347
				{
sl@0
   348
				RArray<TLogId> logIds;
sl@0
   349
				::LogGetRecentEventsLC(iDatabase, iRecentList->Id(), iConfig.iMaxRecentLogSize, logIds); 
sl@0
   350
				::LogPurgeRecentEventsL(iDatabase, logIds);
sl@0
   351
				CleanupStack::PopAndDestroy(&logIds);
sl@0
   352
				}
sl@0
   353
			}
sl@0
   354
			break;
sl@0
   355
		default:
sl@0
   356
			__ASSERT_DEBUG(ETrue, Panic(ELogBadState1));
sl@0
   357
            break;
sl@0
   358
		}
sl@0
   359
sl@0
   360
	LOGTEXT("CLogAddEvent::DoRunL() - end");
sl@0
   361
	}
sl@0
   362
sl@0
   363
void CLogAddEvent::DoCancel()
sl@0
   364
	{
sl@0
   365
	iDuplicate->Cancel();
sl@0
   366
	CLogActive::DoCancel();
sl@0
   367
	}
sl@0
   368
sl@0
   369
void CLogAddEvent::DoAddEventL(RLogEventDbTable& aTbl, TLogTypeId aTypeId, TLogStringId aDirectionId, TLogStringId aStatusId)
sl@0
   370
	{
sl@0
   371
	LOGTEXT("CLogAddEvent::DoAddEventL()");
sl@0
   372
sl@0
   373
	// Insert a new record
sl@0
   374
	aTbl.InsertL();
sl@0
   375
sl@0
   376
	aTbl.SetColL(RLogEventDbTable::iTypeColNo, (TUint32)aTypeId);
sl@0
   377
sl@0
   378
	if (iEvent->RemoteParty().Length() > 0)
sl@0
   379
		aTbl.SetColL(RLogEventDbTable::iRemotePartyColNo, iEvent->RemoteParty());
sl@0
   380
sl@0
   381
	if (iEvent->Direction().Length() > 0)
sl@0
   382
		aTbl.SetColL(RLogEventDbTable::iDirectionColNo, (TUint32)aDirectionId);
sl@0
   383
sl@0
   384
	aTbl.SetColL(RLogEventDbTable::iTimeColNo, iEvent->Time());
sl@0
   385
	aTbl.SetColL(RLogEventDbTable::iDurationTypeColNo, (TInt32)iEvent->DurationType());
sl@0
   386
sl@0
   387
	if (iEvent->DurationType() != KLogNullDurationType)
sl@0
   388
		aTbl.SetColL(RLogEventDbTable::iDurationColNo, iEvent->Duration());
sl@0
   389
sl@0
   390
	if (iEvent->Status().Length() > 0)
sl@0
   391
		aTbl.SetColL(RLogEventDbTable::iStatusColNo, (TUint32)aStatusId);
sl@0
   392
sl@0
   393
	if (iEvent->Subject().Length() > 0)
sl@0
   394
		aTbl.SetColL(RLogEventDbTable::iSubjectColNo, iEvent->Subject());
sl@0
   395
sl@0
   396
	if (iEvent->Number().Length() > 0)
sl@0
   397
		aTbl.SetColL(RLogEventDbTable::iNumberColNo, iEvent->Number());
sl@0
   398
sl@0
   399
	if (iEvent->Contact() != KLogNullContactId)
sl@0
   400
		aTbl.SetColL(RLogEventDbTable::iContactColNo, iEvent->Contact());
sl@0
   401
sl@0
   402
	if (iEvent->Link() != KLogNullLink)
sl@0
   403
		aTbl.SetColL(RLogEventDbTable::iLinkColNo, iEvent->Link());
sl@0
   404
sl@0
   405
	if (iEvent->Data().Length() > 0)
sl@0
   406
		aTbl.SetColL(RLogEventDbTable::iDataColNo, iEvent->Data());
sl@0
   407
sl@0
   408
	// Set the flags
sl@0
   409
	TInt bit = KLogFlagsCount;
sl@0
   410
	while(bit--)
sl@0
   411
		{
sl@0
   412
		aTbl.SetColL(RLogEventDbTable::iFlagColNo[bit], (TUint32)((iEvent->Flags() & 0x1 << bit) ? 1 : 0));
sl@0
   413
		}
sl@0
   414
sl@0
   415
	if (iRecentList)
sl@0
   416
		{
sl@0
   417
		__ASSERT_DEBUG(iRecentList->Id() != KLogNullRecentList, Panic(ELogNullRecentList));
sl@0
   418
		aTbl.SetColL(RLogEventDbTable::iRecentColNo, (TInt32)iRecentList->Id());
sl@0
   419
		}
sl@0
   420
sl@0
   421
#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM	
sl@0
   422
	if(iEvent->SimId() != KLogNullSimId)
sl@0
   423
		{
sl@0
   424
		aTbl.SetColL(RLogEventDbTable::iSimIdColNo, iEvent->SimId());
sl@0
   425
		}
sl@0
   426
	else
sl@0
   427
		{
sl@0
   428
		aTbl.SetColNullL(RLogEventDbTable::iSimIdColNo);
sl@0
   429
		}
sl@0
   430
#endif
sl@0
   431
	
sl@0
   432
	// Assign event id and end the rowset operation
sl@0
   433
	const TLogId newId = aTbl.ColInt32(RLogEventDbTable::iIdColNo);
sl@0
   434
	iEvent->SetId(newId);
sl@0
   435
	aTbl.PutL();
sl@0
   436
sl@0
   437
	// Tell change interface about the addition
sl@0
   438
	iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventAdded, newId);
sl@0
   439
sl@0
   440
	LOGTEXT("CLogAddEvent::DoAddEventL() - end");
sl@0
   441
	}
sl@0
   442
sl@0
   443
void CLogAddEvent::DoComplete(TInt& aStatus)
sl@0
   444
	{
sl@0
   445
	LOGTEXT2("CLogAddEvent::DoComplete(%d)", aStatus);
sl@0
   446
sl@0
   447
	if	(iDatabase.DTIInTransaction())
sl@0
   448
		{
sl@0
   449
		LOGTEXT2("CLogAddEvent::DoComplete() - in transaction: %d", aStatus);
sl@0
   450
		if (aStatus == KErrNone)
sl@0
   451
			aStatus = iDatabase.DTICommitAndEnd();
sl@0
   452
sl@0
   453
		LOGTEXT2("CLogAddEvent::DoComplete() - checking for need to rollback: %d", aStatus);
sl@0
   454
		if (aStatus < KErrNone)
sl@0
   455
			iDatabase.DTIRollBack();
sl@0
   456
		}
sl@0
   457
	else
sl@0
   458
		{
sl@0
   459
		if	(iEventAdded)
sl@0
   460
			aStatus = KErrNone;
sl@0
   461
		}
sl@0
   462
sl@0
   463
	LOGTEXT2("CLogAddEvent::DoComplete() - final status value is: %d", aStatus);
sl@0
   464
	}
sl@0
   465
sl@0
   466
//Opens the default contacts database.
sl@0
   467
void CLogAddEvent::OpenContactsL()
sl@0
   468
	{
sl@0
   469
	//Sometimes, after a sequence of OpenContactsL()/CloseContacts() calls the Contacts server crashes
sl@0
   470
	//and OpenContactsL() leaves with error -15. In order to avoid that the following delay has been added.
sl@0
   471
	//(something related to Contacts server state machine)
sl@0
   472
    User::After(1000);
sl@0
   473
	// Attempt to open DB
sl@0
   474
	TRAPD(err,iContactPlugin->OpenContactsL());
sl@0
   475
	if(KErrNone!=err)
sl@0
   476
		{
sl@0
   477
		if(err == KErrServerTerminated)
sl@0
   478
		    {
sl@0
   479
		    RDebug::Print(_L("+++LogEng, LogAdd.cpp, Contacts server crashed!\r\n"));
sl@0
   480
		    }
sl@0
   481
		// If DB doesn't open delete plugin
sl@0
   482
		delete iContactPlugin;
sl@0
   483
		iContactPlugin = NULL;
sl@0
   484
		User::Leave(err);
sl@0
   485
		}
sl@0
   486
	}
sl@0
   487
sl@0
   488
//Closes the default contacts database and deletes the plugin.
sl@0
   489
void CLogAddEvent::CloseContactsPlugin()
sl@0
   490
	{
sl@0
   491
	if(iContactPlugin)
sl@0
   492
		{
sl@0
   493
		iContactPlugin->CloseContacts();
sl@0
   494
		delete iContactPlugin;
sl@0
   495
		iContactPlugin = NULL;
sl@0
   496
		//REComSession::FinalClose() call moved here from logcntmodel.cpp.
sl@0
   497
		//The in-source documentation of REComSession::FinalClose() notes that: 
sl@0
   498
		//"It must never be called from within a plug-in implementations class 
sl@0
   499
		//destructor, especially following a DestroyImplementation() ". 
sl@0
   500
		//That was the case before the function call was moved here.
sl@0
   501
	    REComSession::FinalClose();
sl@0
   502
		}
sl@0
   503
	}