--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/devicediagnosticsfw/diagresultsdb/client/src/diagresultsdatabase.cpp Wed Sep 01 12:27:42 2010 +0100
@@ -0,0 +1,1114 @@
+/*
+* 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 RDiagResultsDatabase
+*
+*/
+
+
+
+// USER INCLUDE FILES
+
+#include "diagresultsdatabase.h"
+#include "diagresultsdatabaseitem.h"
+#include "diagresultsdbrecordinfoarraypacked.h"
+#include "diagresultsdatabasetestrecordinfo.h"
+#include "diagresultsdbprivatecrkeys.h"
+#include "diagresultsdbrecordengineparam.h"
+#include "diagresultsdatabasecommon.h"
+//#include <diagframeworkdebug.h>
+// SYSTEM INCLUDE FILES
+#include <s32mem.h>
+#include <centralrepository.h>
+
+const TInt KResultsDatabaseBufferLength = 0x700;
+const TInt KResultsDatabaseSubsessionBufferLength = 0x250;
+const TInt KResultsDatabaseGranuality = 50;
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C RDiagResultsDatabase::RDiagResultsDatabase():
+ iBuffer(NULL), iOpen(EFalse)
+ , iPtr( NULL, 0 )
+ {
+
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C RDiagResultsDatabase::~RDiagResultsDatabase()
+ {
+ if ( iBuffer )
+ {
+ iBuffer->Reset();
+ delete iBuffer;
+ iBuffer = NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Create connection to the results DB server
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::Connect( TUid aAppUid )
+ {
+ LOGME("RDiagResultsDatabase::Connect");
+ TRAPD( err, DoConnectL( aAppUid));
+
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Start server, create flat buffer and send request.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::DoConnectL (TUid aAppUid)
+ {
+ LOGME("RDiagResultsDatabase::DoConnectL");
+ if (iBuffer==NULL) {
+ iBuffer = CBufFlat::NewL(KResultsDatabaseGranuality);
+
+ if (iBuffer==NULL) {
+ User::Leave( KErrNoMemory );
+ }
+
+ iBuffer->ResizeL(KResultsDatabaseBufferLength);
+ }
+
+ TInt r = DiagResultsDbCommon::StartServer();
+ LOGME1("RDiagResultsDatabase::StartServer %d",r);
+ if( r==KErrNone )
+ // Use default message slots
+ r = CreateSession( KDiagResultsDatabaseServerName, Version() );
+ LOGME1("RDiagResultsDatabase::Createsession %d",r);
+ if ( r != KErrNone )
+ {
+ User::Leave (r);
+ }
+
+ iOpen = ETrue;
+
+ TPckgBuf<TUid> uid( aAppUid );
+ TInt srret = SendReceive (DiagResultsDbCommon::EConnect,TIpcArgs(&uid) );
+ LOGME1("Rsession sendreceive %d",srret);
+ if (srret != KErrNone)
+ User::Leave( srret );
+ }
+
+// ---------------------------------------------------------------------------
+// Close connection with the server.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::Close()
+ {
+ LOGME("RDiagResultsDatabase::Close");
+ if ( iOpen )
+ {
+ TInt err = SendReceive( DiagResultsDbCommon::EClose );
+ RHandleBase::Close();
+ iOpen = EFalse;
+ delete iBuffer;
+ iBuffer = NULL;
+ return err;
+ }
+ else
+ {
+ iOpen = EFalse;
+ return KErrNone;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the version of this server.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TVersion RDiagResultsDatabase::Version() const
+ {
+ return( TVersion( KDiagResultsDatabaseServerMajor,
+ KDiagResultsDatabaseServerMinor,
+ KDiagResultsDatabaseServerBuild ) );
+ }
+
+// ---------------------------------------------------------------------------
+// Returns test record count.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetRecordCount( TUint& aCount ) const
+ {
+ TPckgBuf<TUint> pckg;
+ TInt error = SendReceive( DiagResultsDbCommon::EGetRecordCount, TIpcArgs(&pckg) );
+ aCount = pckg();
+
+ return error;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Fetch maximum number of test records from the central repository.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetDatabaseMaximumSize( TInt& aMaxSize )
+ {
+ TRAPD( err, DoGetDatabaseMaximumSizeL( aMaxSize ) );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Fetch maximum number of test records from the central repository.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::DoGetDatabaseMaximumSizeL( TInt& aMaxSize )
+ {
+ CRepository* cr = CRepository::NewLC( KCRUidDiagnosticsResults );
+
+ User::LeaveIfError( cr->Get( KDiagDatabaseMaxRecordCount, aMaxSize ) );
+
+ CleanupStack::PopAndDestroy( cr );
+ }
+
+// ---------------------------------------------------------------------------
+// Get available record uids.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetRecordUids(
+ CArrayFixFlat<TUid>& aSortedRecordUidArray ) const
+ {
+ TRAPD( err, DoGetRecordUidsL( aSortedRecordUidArray ));
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Resize buffer and then start query. Overflow means that the buffer was not
+// large enough.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::DoGetRecordUidsL(
+ CArrayFixFlat<TUid>& aSortedRecordUidArray ) const
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0) );
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::EGetRecordList,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::EGetRecordList,
+ TIpcArgs(&ptr) );
+ }
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ RBufReadStream readStream ( *iBuffer );
+ CleanupClosePushL( readStream ) ;
+ TInt count = readStream.ReadInt16L();
+
+ for ( TInt i = 0; i < count; ++i )
+ {
+ aSortedRecordUidArray.AppendL ( TUid::Uid( readStream.ReadInt32L()) );
+ }
+
+ CleanupStack::PopAndDestroy( &readStream );
+ }
+
+// ---------------------------------------------------------------------------
+// Returns last completed record.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetLastRecord( TUid& aRecordUid ) const
+ {
+ TPckgBuf<TUid> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::EGetLastRecord,
+ TIpcArgs(&pckg) );
+ aRecordUid = pckg();
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Get last incomplete record. It could suspended or application crashed
+// when running the test.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetLastNotCompletedRecord (
+ TUid& aRecordUid ) const
+ {
+ TPckgBuf<TUid> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::EGetLastNotCompletedRecord,
+ TIpcArgs(&pckg) );
+ aRecordUid = pckg();
+ return err;
+
+ }
+
+// ---------------------------------------------------------------------------
+// Get all test record overviews.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetAllRecordInfos (
+ CArrayFixFlat<TDiagResultsDatabaseTestRecordInfo>& aInfoArray)
+ {
+ TRAPD( err, DoGetAllRecordInfosL( aInfoArray ));
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Send client request to the server. If overflow, then resize buffer and
+// try again.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::DoGetAllRecordInfosL (
+ CArrayFixFlat<TDiagResultsDatabaseTestRecordInfo>& aInfoArray)
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0) );
+
+ TInt ret = SendReceive( DiagResultsDbCommon::EGetRecordInfoList,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::EGetRecordInfoList,
+ TIpcArgs(&ptr) );
+ }
+
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ TDiagResultsDbRecordInfoArrayPacked packedArray( iBuffer );
+ packedArray.UnpackArrayL( aInfoArray );
+ }
+
+// ---------------------------------------------------------------------------
+// Asynchronous get last results.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void RDiagResultsDatabase::InitiateGetLastResults (
+ const CArrayFixFlat<TUid>& aUidArray,
+ TRequestStatus& aStatus )
+ {
+ TRAPD( error, WriteArrayIntoBufferL( aUidArray ));
+
+ if ( error != KErrNone )
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete( status, error );
+ return;
+ }
+
+
+ iPtr.Set( iBuffer->Ptr(0) );
+
+ SendReceive( DiagResultsDbCommon::EInitiateGetLastResults,
+ TIpcArgs( &iPtr ),
+ aStatus);
+ }
+
+// ---------------------------------------------------------------------------
+// Write Array into Buffer:
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::WriteArrayIntoBufferL( const CArrayFixFlat<TUid>& aUidArray )
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseBufferLength );
+
+ RBufWriteStream writeStream ( *iBuffer );
+ CleanupClosePushL( writeStream );
+
+ writeStream.WriteInt8L( aUidArray.Count() );
+
+ for ( TInt i=0; i < aUidArray.Count(); ++i )
+ {
+ writeStream.WriteInt32L( aUidArray[i].iUid );
+ }
+
+ writeStream.CommitL();
+
+ CleanupStack::PopAndDestroy();
+ }
+
+// ---------------------------------------------------------------------------
+// Cancel asynchronous request.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void RDiagResultsDatabase::CancelInitiateGetLastResults () const
+ {
+ SendReceive( DiagResultsDbCommon::ECancelInitiateGetLastResults );
+ }
+
+// ---------------------------------------------------------------------------
+// See InitiateGetLastResults. After InitiateGetLastResults finishes ok,
+// this method can be called to retrieve data.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetLastResults (
+ RPointerArray<CDiagResultsDatabaseItem>& aResults ) const
+ {
+ TRAPD( err, DoGetLastResultsL( aResults ) );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Resize buffer and make the request. Data is serialized in the buffer so it
+// must be read using a read stream.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::DoGetLastResultsL (
+ RPointerArray<CDiagResultsDatabaseItem>& aResults ) const
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0));
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::EGetLastResults,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
+ ptr.Set ( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::EGetLastResults,
+ TIpcArgs(&ptr) );
+ }
+
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ RBufReadStream readStream ( *iBuffer );
+ TInt count = readStream.ReadInt16L();
+
+ for ( TInt i = 0; i < count; ++i )
+ {
+
+ TUint8 value = readStream.ReadUint8L();
+ if ( value == 0 )
+ {
+ aResults.AppendL( NULL );
+ }
+ else
+ {
+ aResults.AppendL (CDiagResultsDatabaseItem::NewL( readStream ) );
+ }
+ }
+
+ readStream.Close();
+ }
+
+
+// ---------------------------------------------------------------------------
+// Initiate asynchronous operation.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void RDiagResultsDatabase::InitiateGetLastResult ( TUid aTestPluginUid,
+ TRequestStatus& aStatus )
+ {
+ TPckgBuf<TUid> uidpckg( aTestPluginUid );
+
+ SendReceive( DiagResultsDbCommon::EInitiateGetSingleLastResult,
+ TIpcArgs( &uidpckg ),
+ aStatus);
+ }
+
+
+// ---------------------------------------------------------------------------
+// Get last result that was fetched using InitiateGetLastResult method.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabase::GetLastResult (
+ CDiagResultsDatabaseItem*& aItem )
+ {
+
+ TRAPD( err, DoGetLastResultL( aItem ) );
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Leaving version of the function.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabase::DoGetLastResultL (
+ CDiagResultsDatabaseItem*& aItem )
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0));
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::EGetSingleLastResult,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
+ ptr.Set ( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::EGetSingleLastResult,
+ TIpcArgs(&ptr) );
+ }
+
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ RBufReadStream readStream ( *iBuffer );
+
+ TInt count = readStream.ReadInt8L();
+
+ if ( count == 0 )
+ {
+ aItem = NULL;
+ }
+ else
+ {
+ aItem = CDiagResultsDatabaseItem::NewL ( readStream );
+ }
+
+ readStream.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// Subsession constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C RDiagResultsDatabaseRecord::RDiagResultsDatabaseRecord():
+ iBuffer(NULL),
+ iOpen(EFalse)
+ ,iPtr( NULL, 0 )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Subsession destructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C RDiagResultsDatabaseRecord::~RDiagResultsDatabaseRecord()
+ {
+ if ( iBuffer )
+ {
+ iBuffer->Reset();
+ delete iBuffer;
+ iBuffer = NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Checks if connection is already open.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::Connect(
+ RDiagResultsDatabase& aSession,
+ TUid aRecordId,
+ TBool aReadOnly )
+ {
+ LOGME("RDiagResultsDatabaseRecord::Connect");
+ if ( iOpen )
+ {
+ return KErrAlreadyExists;
+ }
+
+ TRAPD( err, DoConnectL( aSession, aRecordId, aReadOnly ) );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Creates the flat buffer and connects the subsession to a test record.
+// The test record must exist.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoConnectL(
+ RDiagResultsDatabase& aSession,
+ TUid aRecordId,
+ TBool aReadOnly )
+ {
+ LOGME("RDiagResultsDatabaseRecord::DoConnectL");
+ if (iBuffer==NULL)
+ {
+ iBuffer = CBufFlat::NewL(KResultsDatabaseGranuality);
+
+ if (iBuffer==NULL) {
+ User::Leave( KErrNoMemory );
+ }
+
+ iBuffer->ResizeL(KResultsDatabaseSubsessionBufferLength);
+ }
+
+ iOpen = ETrue;
+
+ TPckgBuf<TUid> uid( aRecordId );
+ TPckgBuf<TBool> readonlyPckg( aReadOnly );
+ User::LeaveIfError( CreateSubSession( aSession,
+ DiagResultsDbCommon::EConnectSubsession,
+ TIpcArgs(&uid, &readonlyPckg) ));
+ }
+
+
+// ---------------------------------------------------------------------------
+// Create a new subsession and create a new test record.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::CreateNewRecord (
+ RDiagResultsDatabase& aSession,
+ TUid& aRecordId,
+ CDiagResultsDbRecordEngineParam& aEngineParam )
+ {
+ if ( iOpen )
+ {
+ return KErrAlreadyExists;
+ }
+
+ TRAPD( err, DoCreateNewRecordL( aSession, aRecordId, aEngineParam) );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Get parameters that are needed when resuming test session.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::GetEngineParam(
+ CDiagResultsDbRecordEngineParam*& aEngineParam ) const
+ {
+ TRAPD(err, DoGetEngineParamL( aEngineParam ) );
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Leaving version of GetEngineParam. Serialize EngineParam class.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoGetEngineParamL(
+ CDiagResultsDbRecordEngineParam*& aEngineParam ) const
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0) );
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetEngineParam,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size()
+ + KResultsDatabaseSubsessionBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::ESubsessionGetEngineParam,
+ TIpcArgs(&ptr) );
+ }
+
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ //Stream contains the serialized array
+ RBufReadStream readStream ( *iBuffer );
+ CleanupClosePushL ( readStream );
+
+ //Construct new test result.
+ CDiagResultsDbRecordEngineParam* params =
+ CDiagResultsDbRecordEngineParam::NewL( readStream );
+ aEngineParam = params;
+
+ CleanupStack::PopAndDestroy( &readStream );
+
+ iBuffer->Delete(0, iBuffer->Size() );
+ }
+// ---------------------------------------------------------------------------
+// Create the flat buffer and create the subsession.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoCreateNewRecordL (
+ RDiagResultsDatabase& aSession,
+ TUid& aRecordId,
+ CDiagResultsDbRecordEngineParam& aEngineParam )
+ {
+ if (iBuffer==NULL) {
+ iBuffer = CBufFlat::NewL(KResultsDatabaseGranuality);
+
+ if (iBuffer==NULL) {
+ User::Leave( KErrNoMemory );
+ }
+
+ iBuffer->ResizeL(KResultsDatabaseSubsessionBufferLength);
+ }
+
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0) );
+
+ TRAPD( error, WriteEngineParamIntoBufferL( aEngineParam ) );
+
+ while ( error == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseSubsessionBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ TRAP( error, WriteEngineParamIntoBufferL( aEngineParam) );
+ }
+
+ User::LeaveIfError ( error );
+
+ TPckgBuf<TUid> pckg;
+
+ TInt err = CreateSubSession( aSession,
+ DiagResultsDbCommon::ESubsessionCreateNewRecord,
+ TIpcArgs(&pckg, &ptr) );
+ aRecordId = pckg();
+ if ( err == KErrNone )
+ {
+ iOpen = ETrue;
+ }
+
+ User::LeaveIfError( err );
+ }
+
+// ---------------------------------------------------------------------------
+// Write engine parameters into the buffer.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::WriteEngineParamIntoBufferL(
+ CDiagResultsDbRecordEngineParam& aEngineParam )
+ {
+ RBufWriteStream writeStream ( *iBuffer );
+ CleanupClosePushL( writeStream );
+
+ aEngineParam.ExternalizeL( writeStream );
+
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy();
+ }
+
+// ---------------------------------------------------------------------------
+// Close the subsession.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void RDiagResultsDatabaseRecord::Close()
+ {
+ if ( iOpen )
+ {
+ CloseSubSession( DiagResultsDbCommon::ECloseSubsession );
+ }
+
+ iOpen = EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+
+// See ResumeTestRecord.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::Suspend()
+ {
+ return SendReceive ( DiagResultsDbCommon::ESubsessionSuspend );
+ }
+
+// ---------------------------------------------------------------------------
+// Has this test record been suspended.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::IsSuspended( TBool& aSuspended ) const
+ {
+ TPckgBuf<TBool> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::ESubsessionIsSuspended,
+ TIpcArgs(&pckg) );
+ aSuspended = pckg();
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns test record Id that this subsession represents.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestRecordId(
+ TUid& aRecordUid ) const
+ {
+ TPckgBuf<TUid> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::ESubsessionGetTestRecordId,
+ TIpcArgs(&pckg) );
+ aRecordUid = pckg();
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Test record completion.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::TestCompleted(
+ TBool aFullyComplete )
+ {
+ TPckgBuf<TBool> pckg (aFullyComplete);
+ return SendReceive ( DiagResultsDbCommon::ESubsessionTestCompleted,
+ TIpcArgs(&pckg) );
+ }
+
+// ---------------------------------------------------------------------------
+// GetStatus returns current record status.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::GetStatus(
+ TRecordStatus& aRecordStatus ) const
+ {
+ TPckgBuf<TRecordStatus> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::ESubsessionGetStatus,
+ TIpcArgs(&pckg) );
+ aRecordStatus = pckg();
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Indicates has the subsession been written into the DB file.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::IsTestCompleted(
+ TBool& aCompleted ) const
+ {
+ TPckgBuf<TBool> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::ESubsessionIsTestCompleted,
+ TIpcArgs(&pckg) );
+ aCompleted = pckg();
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Returns record overview.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::GetRecordInfo (
+ TDiagResultsDatabaseTestRecordInfo& aInfo ) const
+ {
+ TPckgBuf<TDiagResultsDatabaseTestRecordInfo> pckg;
+ TInt err = SendReceive( DiagResultsDbCommon::ESubsessionGetRecordInfo,
+ TIpcArgs(&pckg) );
+ aInfo = pckg();
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Get all test plug-in uids that are stored in the test record.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestUids (
+ CArrayFixFlat<TUid>& aTestUidArray ) const
+ {
+ TRAPD( err, DoGetTestUidsL( aTestUidArray ));
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Resize flat buffer, make the request. If flat buffer is not large enough
+// grow the size and make the request again.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoGetTestUidsL (
+ CArrayFixFlat<TUid>& aTestUidArray ) const
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0) );
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestUids,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() +
+ KResultsDatabaseSubsessionBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestUids,
+ TIpcArgs(&ptr) );
+ }
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ RBufReadStream readStream ( *iBuffer );
+ CleanupClosePushL( readStream );
+ TInt count = readStream.ReadInt16L();
+
+ for ( TInt i = 0; i < count; ++i )
+ {
+ aTestUidArray.AppendL ( TUid::Uid( readStream.ReadInt32L() ));
+ }
+
+ CleanupStack::PopAndDestroy( &readStream );
+ }
+
+// ---------------------------------------------------------------------------
+// Store one test result into the test record. The method does not write
+// anything.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::LogTestResult (
+ TRequestStatus& aStatus,
+ const CDiagResultsDatabaseItem& aResultItem )
+ {
+ TRAPD(err, DoLogTestResultL( aStatus, aResultItem ) );
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Cancel LogTestResultL.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void RDiagResultsDatabaseRecord::CancelLogTestResult() const
+ {
+ SendReceive( DiagResultsDbCommon::ESubsessionCancelLogTestResult );
+ }
+
+// ---------------------------------------------------------------------------
+// Resize flat buffer and serialize the object that needs to be transferred.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoLogTestResultL (
+ TRequestStatus& aStatus,
+ const CDiagResultsDatabaseItem& aResultItem )
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+
+ //Make sure that the buffer is big enough for the item.
+ iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
+
+ TRAPD( error, WriteDatabaseItemIntoBufferL( aResultItem ));
+
+ while ( error == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() + aResultItem.Size() );
+ TRAP( error, WriteDatabaseItemIntoBufferL( aResultItem ));
+ }
+
+ if ( error != KErrNone )
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete( status, error );
+ return;
+ }
+
+ //Note that iPtr has to be member variable. If a new TPtr8 is defined in
+ //here it can go out of scope i.e. reading will fail in the server side.
+ //Synchronous SendReceive would not have that problem.
+ iPtr.Set( iBuffer->Ptr(0) );
+ SendReceive( DiagResultsDbCommon::ESubsessionLogTestResult,
+ TIpcArgs(&iPtr), aStatus );
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Write CDiagResultsDatabaseItem into a buffer.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::WriteDatabaseItemIntoBufferL(
+ const CDiagResultsDatabaseItem& aResultItem )
+ {
+ RBufWriteStream writeStream ( *iBuffer );
+ CleanupClosePushL( writeStream );
+ aResultItem.ExternalizeL( writeStream );
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy();
+ }
+
+// ---------------------------------------------------------------------------
+// Get test results of the test record.
+// ---------------------------------------------------------------------------
+//
+ EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestResults (
+ RPointerArray<CDiagResultsDatabaseItem>& aResultsArray ) const
+ {
+
+ TRAPD( err, DoGetTestResultsL( aResultsArray ) );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Retrieve test results. Server serializes data into the flat buffer.
+// Read stream can be used to deserialize data.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoGetTestResultsL (
+ RPointerArray<CDiagResultsDatabaseItem>& aResultsArray ) const
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0));
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResults,
+ TIpcArgs(&ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size() +
+ KResultsDatabaseSubsessionBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResults,
+ TIpcArgs(&ptr) );
+ }
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ RBufReadStream readStream ( *iBuffer );
+ TInt count = readStream.ReadInt16L();
+
+ for ( TInt i = 0; i < count; ++i )
+ {
+ aResultsArray.AppendL (CDiagResultsDatabaseItem::NewL( readStream ) );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Get only one result from the test record.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestResult (
+ TUid aPluginUid,
+ CDiagResultsDatabaseItem*& aResultItem ) const
+ {
+ TRAPD( err, DoGetTestResultL ( aPluginUid, aResultItem ) );
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Resize flat buffer and use read stream to retrieve data into DB item.
+// ---------------------------------------------------------------------------
+//
+void RDiagResultsDatabaseRecord::DoGetTestResultL (
+ TUid aPluginUid,
+ CDiagResultsDatabaseItem*& aResultItem ) const
+ {
+ iBuffer->Delete( 0, iBuffer->Size() );
+ iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
+
+ TPtr8 ptr ( iBuffer->Ptr(0) );
+ TPckgBuf<TUid> uid( aPluginUid );
+ //Now ask server to serialize object into this buffer
+ TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResult,
+ TIpcArgs(&uid, &ptr) );
+
+ while ( ret == KErrOverflow )
+ {
+ iBuffer->ResizeL( iBuffer->Size()
+ + KResultsDatabaseSubsessionBufferLength );
+ ptr.Set( iBuffer->Ptr(0) );
+ ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResult,
+ TIpcArgs(&uid, &ptr) );
+ }
+
+ if ( ret != KErrNone )
+ {
+ User::Leave (ret);
+ }
+
+ //Stream contains the serialized array
+ RBufReadStream readStream ( *iBuffer );
+ CleanupClosePushL( readStream );
+
+ //Construct new test result.
+ CDiagResultsDatabaseItem* item =
+ CDiagResultsDatabaseItem::NewL( readStream );
+ aResultItem = item;
+
+ CleanupStack::PopAndDestroy( &readStream );
+
+ iBuffer->Delete(0, iBuffer->Size() );
+ }
+
+// ---------------------------------------------------------------------------
+// Starts server if it's not already running.
+// ---------------------------------------------------------------------------
+//
+TInt DiagResultsDbCommon::StartServer()
+ {
+ LOGME("DiagResultsDbCommon::StartServer");
+ TInt res(KErrNone);
+ // create server - if one of this name does not already exist
+ TFindServer findServer(KDiagResultsDatabaseServerName);
+ TFullName name;
+ if (findServer.Next(name)!=KErrNone) // we don't exist already
+ {
+ TRequestStatus status;
+ RProcess server;
+ // Create the server process
+ res = server.Create(KDiagResultsDatabaseServerExe, KNullDesC);
+
+ if( res!=KErrNone ) // thread created ok - now start it going
+ {
+ return res;
+ }
+
+ server.Rendezvous( status );
+ if( status != KRequestPending )
+ {
+ server.Kill(0); // abort start-up
+ }
+ else
+ {
+ server.Resume(); // // wait for server start-up.
+ }
+
+ // Wait until the completion of the server creation
+ User::WaitForRequest( status );
+ if( status != KErrNone )
+ {
+ server.Close();
+ return status.Int();
+ }
+ // Server created successfully
+ server.Close(); // we're no longer interested in the other process
+ }
+ LOGME1("startserver %d",res);
+ return res;
+ }
+
+// ---------------------------------------------------------------------------
+// DLL entry point
+// ---------------------------------------------------------------------------
+//
+#ifndef EKA2
+GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
+ {
+ return(KErrNone);
+ }
+#endif
+
+