/*
* 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