--- a/devicediagnosticsfw/diagresultsdb/server/src/diagresultsdbtestrecordsubsession.cpp Thu Aug 19 10:44:50 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,645 +0,0 @@
-/*
-* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Class definition of
-*
-*/
-
-
-#include "diagresultsdatabasecommon.h"
-#include "diagresultsdbsession.h"
-#include "diagresultsdbtestrecordsubsession.h"
-#include "diagresultsdbtestrecord.h"
-#include "diagresultsdbtestrecordhandle.h"
-#include "diagresultsdbrecordengineparam.h"
-#include "diagresultsdatabase.h"
-
-#include <s32mem.h>
-
-//this matches the size in the client side.
-const TInt KResultsDatabaseSubsessionBufferLength = 0x250;
-const TInt KResultsDatabaseSubsessionGranuality = 50;
-
-// ---------------------------------------------------------------------------
-// NewL.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbTestRecordSubsession* CDiagResultsDbTestRecordSubsession::NewL(
- CDiagResultsDbSession* aSession,
- CDiagResultsDbTestRecordHandle* aTestRecordHandle,
- TBool aReadonly
- )
- {
- CDiagResultsDbTestRecordSubsession* self = new( ELeave )
- CDiagResultsDbTestRecordSubsession( aSession,
- aTestRecordHandle,
- aReadonly
- );
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop();
- return self;
- }
-
-// ---------------------------------------------------------------------------
-// Destructor. Checks has the test record been written into the DB.
-// If it hasn't been written, destructor writes the data.
-// This situation happens when for example client dies suddenly.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbTestRecordSubsession::~CDiagResultsDbTestRecordSubsession()
- {
- delete iTestRecordHandle;
- iTestRecordHandle = NULL;
-
- if ( iBuffer )
- {
- iBuffer->Reset();
- delete iBuffer;
- iBuffer = NULL;
- }
- }
-
-// ---------------------------------------------------------------------------
-// ConstructL. Creates the server side buffer.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::ConstructL()
- {
- // buffer for IPC. Objects are transmitted in this buffer.
- // Size of the buffer has to be selected carefully.
- // It should be 'large enough' but not too large.
- // If you see too many overflows, increase the size.
- // Subsession buffer can be smaller than the session buffer
- iBuffer = CBufFlat::NewL( KResultsDatabaseSubsessionGranuality );
- iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
- }
-
-
-// ---------------------------------------------------------------------------
-// Handles subsession requests.
-// ---------------------------------------------------------------------------
-//
-TBool CDiagResultsDbTestRecordSubsession::DispatchMessageL(
- const RMessage2& aMessage)
- {
- TInt function = aMessage.Function();
- switch( function )
- {
- case DiagResultsDbCommon::ESubsessionGetTestRecordId:
- {
- TPckgBuf<TUid> uid( iTestRecordHandle->RecordInfo().iRecordId);
- aMessage.Write( 0, uid );
- return EFalse;
- }
-
- case DiagResultsDbCommon::ESubsessionTestCompleted: //SYNC
- {
- iMsg = aMessage;
-
- CompleteTestRecordL( aMessage );
-
- aMessage.Complete( KErrNone );
-
- //Do compacting after subsession is completed to
- //minimize disk space usage
- if ( iSession->SessionHasWritten() )
- {
- iSession->Store().CompactDatabase();
- }
-
- //Not asynchronous, but this prevents calling Complete again.
- return ETrue;
- }
-
- case DiagResultsDbCommon::ESubsessionGetStatus:
- {
- GetStatusL ( aMessage );
- return EFalse;
- }
- case DiagResultsDbCommon::ESubsessionSuspend: //SYNC
- {
- iMsg = aMessage;
-
- SuspendTestRecordL( aMessage );
-
- aMessage.Complete( KErrNone );
-
- //Do compacting after subsession is completed to
- //minimize disk space usage
- if ( iSession->SessionHasWritten() )
- {
- iSession->Store().CompactDatabase();
- }
-
- //Not asynchronous, but this prevents calling Complete again.
- return ETrue;
- }
-
- case DiagResultsDbCommon::ESubsessionIsTestCompleted:
- {
- TPckgBuf<TBool> pckg ( Completed() );
- aMessage.Write( 0, pckg );
- return EFalse;
- }
- case DiagResultsDbCommon::ESubsessionGetRecordInfo:
- {
- TPckgBuf<TDiagResultsDatabaseTestRecordInfo> pckg(
- iTestRecordHandle->RecordInfo());
- aMessage.Write( 0, pckg );
- return EFalse;
- }
- case DiagResultsDbCommon::ESubsessionGetTestUids:
- {
- GetTestUidsL( aMessage );
- return EFalse;
- }
-
- case DiagResultsDbCommon::ESubsessionIsSuspended:
- {
- TBool suspended = EFalse;
- if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
- TDiagResultsDatabaseTestRecordInfo::ESuspended )
- {
- suspended = ETrue;
- }
-
- TPckgBuf<TBool> pckg ( suspended );
- aMessage.Write( 0, pckg );
- return EFalse;
- }
-
- case DiagResultsDbCommon::ESubsessionGetEngineParam:
- {
- GetEngineParamL( aMessage );
- return EFalse;
- }
-
- case DiagResultsDbCommon::ESubsessionLogTestResult: //ASYNC
- {
- iMsg = aMessage;
- iCompletedLogTest = EFalse;
- LogTestResultL( aMessage );
- return ETrue;
- }
-
- case DiagResultsDbCommon::ESubsessionCancelLogTestResult:
- {
- CancelLogTestResult( aMessage );
-
- return EFalse;
- }
-
- case DiagResultsDbCommon::ESubsessionGetTestResult:
- {
- GetTestResultL( aMessage );
- return EFalse;
- }
-
- case DiagResultsDbCommon::ESubsessionGetTestResults:
- {
- GetTestResultsL( iTestRecordHandle, aMessage );
- return EFalse;
- }
- default:
- break;
- }
- aMessage.Panic( _L("DiagSrv panic: unknown command"),
- DiagResultsDbCommon::EBadRequest );
- return EFalse;
- }
-
-
-// ---------------------------------------------------------------------------
-// Returns record complete status.
-// ---------------------------------------------------------------------------
-//
-TBool CDiagResultsDbTestRecordSubsession::Completed() const
- {
- TBool completed = EFalse;
-
- if ( iTestRecordHandle->RecordInfo().iCompleted )
- {
- completed = ETrue;
- }
- return completed;
- }
-
-
-// ---------------------------------------------------------------------------
-// Maps server side status into user side status.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::GetStatusL ( const RMessage2& aMessage )
- {
-
- RDiagResultsDatabaseRecord::TRecordStatus status;
-
- if ( iTestRecordHandle->RecordInfo().iCompleted )
- {
-
- if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
- TDiagResultsDatabaseTestRecordInfo::EOpen )
- {
-
- status = RDiagResultsDatabaseRecord::EPartiallyCompleted;
- }
- else if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
- TDiagResultsDatabaseTestRecordInfo::ESuspended )
- {
- status = RDiagResultsDatabaseRecord::EPartiallyCompleted;
- }
- else if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
- TDiagResultsDatabaseTestRecordInfo::ECompleted )
- {
- status = RDiagResultsDatabaseRecord::ECompleted;
- }
- else
- {
- User::Panic( _L("DiagDbServer error"), DiagResultsDbCommon::EGetStatusPanic);
- status = RDiagResultsDatabaseRecord::ECrashed;
- }
- }
- else // iCompleted == EFalse
- {
- if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
- TDiagResultsDatabaseTestRecordInfo::EOpen )
- {
- if ( iSession->SessionHasWritten() )
- {
- status = RDiagResultsDatabaseRecord::EOpen;
- }
- else
- {
- status = RDiagResultsDatabaseRecord::ECrashed;
- }
- }
- else if ( iTestRecordHandle->RecordInfo().iRecordStatus ==
- TDiagResultsDatabaseTestRecordInfo::ESuspended )
- {
- status = RDiagResultsDatabaseRecord::ESuspended;
- }
- // TDiagResultsDatabaseTestRecordInfo::ECompleted is not valid combination either
- else
- {
- User::Panic( _L("DiagDbServer error"), DiagResultsDbCommon::EGetStatusPanic);
- status = RDiagResultsDatabaseRecord::ECrashed;
- }
- }
-
- TPckgBuf<RDiagResultsDatabaseRecord::TRecordStatus> pckg( status );
- aMessage.Write( 0, pckg );
- }
-
-// ---------------------------------------------------------------------------
-// Constructor.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbTestRecordSubsession::CDiagResultsDbTestRecordSubsession(
- CDiagResultsDbSession* aSession,
- CDiagResultsDbTestRecordHandle* aTestRecordHandle,
- TBool aReadonly
- ):
- iSession( aSession ), iTestRecordHandle( aTestRecordHandle ),
- iReadonly (aReadonly), iCompletedLogTest( EFalse )
- {
-
- }
-
-// ---------------------------------------------------------------------------
-// Read-only subsession or not
-// ---------------------------------------------------------------------------
-//
-TBool CDiagResultsDbTestRecordSubsession::ReadonlySubsession() const
- {
- return iReadonly;
- }
-
-// ---------------------------------------------------------------------------
-// Retrieve session params.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::GetEngineParamL( const RMessage2& aMessage )
- {
- iSession->ReadBufferL( aMessage, 0, iBuffer );
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL( stream );
-
- iTestRecordHandle->GetEngineParam().ExternalizeL( stream );
-
- stream.CommitL();
-
- CleanupStack::PopAndDestroy( &stream );
-
- // if client buffer is not big enough
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
- {
- User::Leave( KErrOverflow );
- }
-
- aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space
- }
-
-
-// ---------------------------------------------------------------------------
-// Log data into the store. This does not write data into the file.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::LogTestResultL(
- const RMessage2& aMessage )
- {
- if ( Completed() )
- {
- User::Leave( KErrAlreadyExists );
- }
-
- if ( ReadonlySubsession() )
- {
- User::Leave( KErrAccessDenied );
- }
-
- //Writing anymore results into suspended record is considered as resume
- iTestRecordHandle->RecordInfo().iRecordStatus =
- TDiagResultsDatabaseTestRecordInfo::EOpen;
-
- iSession->ReadBufferL( aMessage, 0, iBuffer );
-
- RBufReadStream stream( *iBuffer );
- CleanupClosePushL ( stream );
-
- CDiagResultsDatabaseItem * item =
- CDiagResultsDatabaseItem::NewL ( stream );
- CleanupStack::PushL( item );
-
- //Update handle + write data into the file. Handle and DB must be in sync.
- TInt error = iSession->Store().CompleteTestResult( ETrue,
- *iTestRecordHandle,
- *item );
-
- //item has been written, so delete the object
- CleanupStack::PopAndDestroy( item );
- CleanupStack::PopAndDestroy( &stream );
-
- iCompletedLogTest = ETrue;
-
- // LogTestResult is asynchronous.
- if( error == KErrNone )
- {
- iSession->HasWritten();
- aMessage.Complete( KErrNone );
- }
- else
- {
- if ( error == KErrDiskFull )
- {
- iSession->DoNotCompact();
- }
-
- aMessage.Complete ( error );
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// Cancel LogTestResultL.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::CancelLogTestResult(
- const RMessage2& /*aMessage*/ )
- {
- if (!iMsg.IsNull() && !iCompletedLogTest )
- {
- iMsg.Complete( KErrCancel ); //Complete client's request.
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// Returns the test record.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbTestRecordHandle* CDiagResultsDbTestRecordSubsession::CurrentTestRecordHandle()
- {
- return iTestRecordHandle;
- }
-
-// ---------------------------------------------------------------------------
-// Finds one test result and serialize it. If it is not found, return KErrNone
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::GetTestResultL(
- const RMessage2& aMessage )
- {
- iSession->ReadBufferL( aMessage, 1, iBuffer );
-
- TPckgBuf<TUid> uidpckg;
- aMessage.Read(0, uidpckg);
- TUid testUid = uidpckg();
-
- //Find right stream Id from the handle
- TStreamId id;
- TInt error = iTestRecordHandle->MatchingStreamId( testUid, id );
-
- User::LeaveIfError ( error );
-
- CDiagResultsDatabaseItem* item =
- iSession->Store().OpenExistingTestResultL( id );
- CleanupStack::PushL( item );
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL( stream );
- item->ExternalizeL( stream );
- stream.CommitL();
- CleanupStack::PopAndDestroy( &stream );
-
- CleanupStack::PopAndDestroy( item );
-
- if ( iBuffer->Size() == 0 ) // Item was not found
- {
- User::Leave ( KErrNotFound );
- }
-
- // if client buffer is not big enough
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(1) )
- {
- User::Leave( KErrOverflow );
- }
-
- aMessage.Write( 1, iBuffer->Ptr(0) ); //write to client's address space
-
- }
-
-// ---------------------------------------------------------------------------
-// Complete test record i.e. write it to file in parts.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::CompleteTestRecordL(
- const RMessage2& aMessage )
- {
- if ( Completed() )
- {
- User::Leave( KErrAlreadyExists );
- }
- if ( ReadonlySubsession() )
- {
- User::Leave( KErrAccessDenied );
- }
-
- TPckgBuf<TBool> completeFullyPckg;
- aMessage.Read(0, completeFullyPckg);
- TBool completeFully = completeFullyPckg();
-
- if ( completeFully )
- {
- iTestRecordHandle->RecordInfo().iRecordStatus =
- TDiagResultsDatabaseTestRecordInfo::ECompleted;
-
- iTestRecordHandle->RecordInfo().iCompleted = ETrue;
- }
- else // partial complete. iRecordStatus is not changed.
- {
- iTestRecordHandle->RecordInfo().iCompleted = ETrue;
- }
-
- //Cleanup is not necessary if logging failed.
- TInt error = iSession->Store().CompleteRecord( *iTestRecordHandle );
-
- if ( error == KErrDiskFull )
- {
- iSession->DoNotCompact();
- }
-
- User::LeaveIfError ( error );
-
- iSession->HasWritten();
-
- iSession->Store().CleanUpDatabaseL( ETrue );
- }
-
-
-// ---------------------------------------------------------------------------
-// Suspend test record i.e. write it to file in parts.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::SuspendTestRecordL(
- const RMessage2& /*aMessage*/ )
- {
- if ( Completed() )
- {
- User::Leave( KErrAlreadyExists );
- }
- if ( ReadonlySubsession() )
- {
- User::Leave( KErrAccessDenied );
- }
-
- iTestRecordHandle->RecordInfo().iRecordStatus =
- TDiagResultsDatabaseTestRecordInfo::ESuspended;
-
- iTestRecordHandle->RecordInfo().iCompleted = EFalse;
-
- TInt error = iSession->Store().CompleteRecord( *iTestRecordHandle );
-
- if ( error == KErrDiskFull )
- {
- iSession->DoNotCompact();
- }
-
- User::LeaveIfError ( error );
-
- iSession->Store().CleanUpDatabaseL( ETrue );
-
- iSession->HasWritten();
- }
-
-// ---------------------------------------------------------------------------
-// Observers function. Observers store after CompleteTestRecordL has been
-// called.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::CompletedRecordL( TInt aError )
- {
- iMsg.Complete( aError ); // complete async function
- }
-
-
-// ---------------------------------------------------------------------------
-// Get test results of a test record.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::GetTestResultsL(
- CDiagResultsDbTestRecordHandle* aHandle,
- const RMessage2& aMessage )
- {
- iSession->ReadBufferL( aMessage, 0, iBuffer );
-
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL ( stream );
- stream.WriteInt16L( aHandle->Count() );
-
- CDiagResultsDbTestRecord* testrecord =
- iSession->Store().OpenExistingRecordL( TUid::Uid(aHandle->RecordId().Value()), ETrue );
- CleanupStack::PushL (testrecord);
-
- for ( TInt i = 0; i < aHandle->Count(); ++i )
- {
- const CDiagResultsDatabaseItem& item = (*testrecord)[i];
- item.ExternalizeL( stream );
- }
-
- CleanupStack::PopAndDestroy( testrecord );
-
- // if client buffer is not big enough
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
- {
- User::Leave( KErrOverflow );
- }
-
- aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space
-
- CleanupStack::PopAndDestroy( &stream );
- }
-
-// ---------------------------------------------------------------------------
-// Get UIDs of test results that are stored inside the test record.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbTestRecordSubsession::GetTestUidsL(
- const RMessage2& aMessage )
- {
- iSession->ReadBufferL( aMessage, 0, iBuffer );
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL( stream );
-
- //Write how many uids there are.
- stream.WriteInt16L( iTestRecordHandle->Count() );
-
- for (TInt i = 0; i < iTestRecordHandle->Count(); ++i)
- {
- stream.WriteInt32L( iTestRecordHandle->Get(i).iTestUid.iUid ) ;
- }
-
- // if client buffer is not big enough
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
- {
- User::Leave( KErrOverflow );
- }
-
-
- aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space
-
- CleanupStack::PopAndDestroy( &stream );
- }