devicediagnosticsfw/diagresultsdb/client/src/diagresultsdatabase.cpp
branchRCL_3
changeset 25 b183ec05bd8c
parent 24 13d7c31c74e0
child 26 19bba8228ff0
equal deleted inserted replaced
24:13d7c31c74e0 25:b183ec05bd8c
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class definition of RDiagResultsDatabase
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // USER INCLUDE FILES
       
    21 
       
    22 #include "diagresultsdatabase.h"
       
    23 #include "diagresultsdatabaseitem.h"
       
    24 #include "diagresultsdbrecordinfoarraypacked.h"
       
    25 #include "diagresultsdatabasetestrecordinfo.h"
       
    26 #include "diagresultsdbprivatecrkeys.h"
       
    27 #include "diagresultsdbrecordengineparam.h"
       
    28 #include "diagresultsdatabasecommon.h"
       
    29 //#include <diagframeworkdebug.h>
       
    30 // SYSTEM INCLUDE FILES
       
    31 #include <s32mem.h> 
       
    32 #include <centralrepository.h> 
       
    33 
       
    34 const TInt KResultsDatabaseBufferLength = 0x700;
       
    35 const TInt KResultsDatabaseSubsessionBufferLength = 0x250;
       
    36 const TInt KResultsDatabaseGranuality = 50;
       
    37 
       
    38 // ======== MEMBER FUNCTIONS ========
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // Constructor.
       
    42 // ---------------------------------------------------------------------------
       
    43 //
       
    44 EXPORT_C RDiagResultsDatabase::RDiagResultsDatabase(): 
       
    45          iBuffer(NULL), iOpen(EFalse)
       
    46        , iPtr( NULL, 0 )
       
    47     {
       
    48     
       
    49     }
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // Destructor.
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 EXPORT_C RDiagResultsDatabase::~RDiagResultsDatabase()
       
    56     {
       
    57     if ( iBuffer )
       
    58         {
       
    59         iBuffer->Reset();
       
    60         delete iBuffer;
       
    61         iBuffer = NULL;    
       
    62         }
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // Create connection to the results DB server
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 EXPORT_C TInt RDiagResultsDatabase::Connect( TUid aAppUid )
       
    70     {
       
    71     LOGME("RDiagResultsDatabase::Connect");
       
    72 	TRAPD( err, DoConnectL( aAppUid));
       
    73 	
       
    74 	return err;
       
    75     }
       
    76 
       
    77 // ---------------------------------------------------------------------------
       
    78 // Start server, create flat buffer and send request.
       
    79 // ---------------------------------------------------------------------------
       
    80 //
       
    81 void RDiagResultsDatabase::DoConnectL (TUid aAppUid)
       
    82     {
       
    83     LOGME("RDiagResultsDatabase::DoConnectL");
       
    84     if (iBuffer==NULL) {
       
    85 		iBuffer = CBufFlat::NewL(KResultsDatabaseGranuality);
       
    86 		
       
    87 		if (iBuffer==NULL) {
       
    88 			User::Leave( KErrNoMemory );
       
    89 		}
       
    90 		
       
    91 		iBuffer->ResizeL(KResultsDatabaseBufferLength);
       
    92 	}
       
    93     
       
    94     TInt r = DiagResultsDbCommon::StartServer();
       
    95     LOGME1("RDiagResultsDatabase::StartServer %d",r);
       
    96 	if( r==KErrNone )
       
    97 	    // Use default message slots
       
    98 		r = CreateSession( KDiagResultsDatabaseServerName, Version() );
       
    99 	LOGME1("RDiagResultsDatabase::Createsession %d",r); 
       
   100 	if ( r != KErrNone )
       
   101 	    {
       
   102 	    User::Leave (r);
       
   103 	    }
       
   104 	
       
   105 	iOpen = ETrue;
       
   106 	
       
   107     TPckgBuf<TUid> uid( aAppUid );
       
   108     TInt srret = SendReceive (DiagResultsDbCommon::EConnect,TIpcArgs(&uid) );
       
   109     LOGME1("Rsession sendreceive %d",srret);
       
   110     if (srret != KErrNone)
       
   111 	User::Leave( srret );
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // Close connection with the server.
       
   116 // ---------------------------------------------------------------------------
       
   117 //
       
   118 EXPORT_C TInt RDiagResultsDatabase::Close()
       
   119     {
       
   120     LOGME("RDiagResultsDatabase::Close");
       
   121     if ( iOpen )
       
   122         {
       
   123         TInt err = SendReceive( DiagResultsDbCommon::EClose );
       
   124         RHandleBase::Close();
       
   125         iOpen = EFalse;
       
   126         delete iBuffer;
       
   127         iBuffer = NULL;
       
   128         return err;    
       
   129         }
       
   130     else 
       
   131         {
       
   132         iOpen = EFalse;
       
   133         return KErrNone;
       
   134         }
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // Returns the version of this server.
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 EXPORT_C TVersion RDiagResultsDatabase::Version() const
       
   142     {
       
   143     return( TVersion( KDiagResultsDatabaseServerMajor, 
       
   144                       KDiagResultsDatabaseServerMinor,
       
   145 		              KDiagResultsDatabaseServerBuild ) );
       
   146     }
       
   147 
       
   148 // ---------------------------------------------------------------------------
       
   149 // Returns test record count.
       
   150 // ---------------------------------------------------------------------------
       
   151 //
       
   152 EXPORT_C TInt RDiagResultsDatabase::GetRecordCount( TUint& aCount ) const
       
   153     {
       
   154 	TPckgBuf<TUint> pckg;
       
   155 	TInt error = SendReceive( DiagResultsDbCommon::EGetRecordCount, TIpcArgs(&pckg) );
       
   156 	aCount = pckg();
       
   157 	
       
   158 	return error;
       
   159     }
       
   160 
       
   161 
       
   162 // ---------------------------------------------------------------------------
       
   163 // Fetch maximum number of test records from the central repository.
       
   164 // ---------------------------------------------------------------------------
       
   165 //
       
   166 EXPORT_C TInt RDiagResultsDatabase::GetDatabaseMaximumSize( TInt& aMaxSize )
       
   167     {
       
   168     TRAPD( err, DoGetDatabaseMaximumSizeL( aMaxSize ) );
       
   169     return err;
       
   170     }
       
   171 
       
   172 // ---------------------------------------------------------------------------
       
   173 // Fetch maximum number of test records from the central repository.
       
   174 // ---------------------------------------------------------------------------
       
   175 //
       
   176 void RDiagResultsDatabase::DoGetDatabaseMaximumSizeL( TInt& aMaxSize )
       
   177     {
       
   178     CRepository* cr = CRepository::NewLC( KCRUidDiagnosticsResults );
       
   179         
       
   180     User::LeaveIfError( cr->Get( KDiagDatabaseMaxRecordCount, aMaxSize ) );
       
   181     
       
   182     CleanupStack::PopAndDestroy( cr );
       
   183     }
       
   184 
       
   185 // ---------------------------------------------------------------------------
       
   186 // Get available record uids.
       
   187 // ---------------------------------------------------------------------------
       
   188 //
       
   189 EXPORT_C TInt RDiagResultsDatabase::GetRecordUids( 
       
   190             CArrayFixFlat<TUid>& aSortedRecordUidArray ) const
       
   191     {
       
   192     TRAPD( err, DoGetRecordUidsL( aSortedRecordUidArray ));
       
   193     return err;
       
   194     }
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 // Resize buffer and then start query. Overflow means that the buffer was not
       
   198 // large enough.
       
   199 // ---------------------------------------------------------------------------
       
   200 //    
       
   201 void RDiagResultsDatabase::DoGetRecordUidsL( 
       
   202                            CArrayFixFlat<TUid>& aSortedRecordUidArray ) const
       
   203     {
       
   204     iBuffer->Delete( 0, iBuffer->Size() );
       
   205     iBuffer->ResizeL( KResultsDatabaseBufferLength );
       
   206     
       
   207     TPtr8 ptr ( iBuffer->Ptr(0) );
       
   208     //Now ask server to serialize object into this buffer
       
   209     TInt ret = SendReceive( DiagResultsDbCommon::EGetRecordList, 
       
   210                             TIpcArgs(&ptr) );
       
   211     
       
   212     while ( ret == KErrOverflow )
       
   213         {
       
   214         iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
       
   215         ptr.Set( iBuffer->Ptr(0) );
       
   216         ret = SendReceive( DiagResultsDbCommon::EGetRecordList, 
       
   217                            TIpcArgs(&ptr) );
       
   218         }
       
   219     if ( ret != KErrNone )
       
   220         {
       
   221         User::Leave (ret);
       
   222         }
       
   223         
       
   224     RBufReadStream readStream ( *iBuffer );   
       
   225     CleanupClosePushL( readStream ) ;
       
   226     TInt count = readStream.ReadInt16L();
       
   227     
       
   228     for ( TInt i = 0; i < count; ++i )
       
   229         {
       
   230         aSortedRecordUidArray.AppendL ( TUid::Uid( readStream.ReadInt32L()) );
       
   231         }
       
   232    
       
   233    CleanupStack::PopAndDestroy( &readStream );
       
   234     }    
       
   235 
       
   236 // ---------------------------------------------------------------------------
       
   237 // Returns last completed record.
       
   238 // ---------------------------------------------------------------------------
       
   239 //
       
   240 EXPORT_C TInt RDiagResultsDatabase::GetLastRecord( TUid& aRecordUid ) const
       
   241     {
       
   242     TPckgBuf<TUid> pckg;
       
   243 	TInt err = SendReceive( DiagResultsDbCommon::EGetLastRecord, 
       
   244 	                        TIpcArgs(&pckg) );
       
   245 	aRecordUid = pckg();
       
   246 	return err;
       
   247     }
       
   248     
       
   249 
       
   250 // ---------------------------------------------------------------------------
       
   251 // Get last incomplete record. It could suspended or application crashed
       
   252 // when running the test.
       
   253 // ---------------------------------------------------------------------------
       
   254 //       
       
   255 EXPORT_C TInt RDiagResultsDatabase::GetLastNotCompletedRecord ( 
       
   256                                                     TUid& aRecordUid ) const
       
   257     {
       
   258     TPckgBuf<TUid> pckg;
       
   259     TInt err = SendReceive( DiagResultsDbCommon::EGetLastNotCompletedRecord, 
       
   260 	                        TIpcArgs(&pckg) );
       
   261 	aRecordUid = pckg();
       
   262 	return err;
       
   263                                                         
       
   264     }
       
   265 
       
   266 // ---------------------------------------------------------------------------
       
   267 // Get all test record overviews.
       
   268 // ---------------------------------------------------------------------------
       
   269 //
       
   270 EXPORT_C TInt RDiagResultsDatabase::GetAllRecordInfos ( 
       
   271             CArrayFixFlat<TDiagResultsDatabaseTestRecordInfo>& aInfoArray) 
       
   272     {
       
   273     TRAPD( err, DoGetAllRecordInfosL( aInfoArray ));
       
   274     return err;
       
   275     }
       
   276 
       
   277 // ---------------------------------------------------------------------------
       
   278 // Send client request to the server. If overflow, then resize buffer and
       
   279 // try again. 
       
   280 // ---------------------------------------------------------------------------
       
   281 //
       
   282 void RDiagResultsDatabase::DoGetAllRecordInfosL ( 
       
   283             CArrayFixFlat<TDiagResultsDatabaseTestRecordInfo>& aInfoArray) 
       
   284     {
       
   285     iBuffer->Delete( 0, iBuffer->Size() );
       
   286     iBuffer->ResizeL( KResultsDatabaseBufferLength );
       
   287     
       
   288     TPtr8 ptr ( iBuffer->Ptr(0) );
       
   289     
       
   290     TInt ret = SendReceive( DiagResultsDbCommon::EGetRecordInfoList, 
       
   291                             TIpcArgs(&ptr) );
       
   292     
       
   293     while ( ret == KErrOverflow )
       
   294         {
       
   295         iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
       
   296         ptr.Set( iBuffer->Ptr(0) );
       
   297         ret = SendReceive( DiagResultsDbCommon::EGetRecordInfoList, 
       
   298                            TIpcArgs(&ptr) );
       
   299         }
       
   300     
       
   301     if ( ret != KErrNone )
       
   302         {
       
   303         User::Leave (ret);
       
   304         }
       
   305             
       
   306     TDiagResultsDbRecordInfoArrayPacked packedArray( iBuffer );    
       
   307     packedArray.UnpackArrayL( aInfoArray );
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // Asynchronous get last results.
       
   312 // ---------------------------------------------------------------------------
       
   313 //
       
   314 EXPORT_C void RDiagResultsDatabase::InitiateGetLastResults ( 
       
   315                                           const CArrayFixFlat<TUid>& aUidArray,
       
   316                                           TRequestStatus& aStatus )
       
   317     {    
       
   318     TRAPD( error, WriteArrayIntoBufferL( aUidArray ));
       
   319     
       
   320     if ( error != KErrNone )
       
   321         {         
       
   322         TRequestStatus* status = &aStatus;
       
   323         User::RequestComplete( status, error );
       
   324         return;
       
   325         }
       
   326     
       
   327             
       
   328     iPtr.Set( iBuffer->Ptr(0) );
       
   329     
       
   330 	SendReceive( DiagResultsDbCommon::EInitiateGetLastResults, 
       
   331 	             TIpcArgs( &iPtr ), 
       
   332 	             aStatus);
       
   333     }
       
   334 
       
   335 // ---------------------------------------------------------------------------
       
   336 // Write Array into Buffer:
       
   337 // ---------------------------------------------------------------------------
       
   338 //    
       
   339 void RDiagResultsDatabase::WriteArrayIntoBufferL( const CArrayFixFlat<TUid>& aUidArray )
       
   340     {
       
   341     iBuffer->Delete( 0, iBuffer->Size() );
       
   342     iBuffer->ResizeL( KResultsDatabaseBufferLength );     
       
   343 
       
   344     RBufWriteStream writeStream ( *iBuffer );
       
   345     CleanupClosePushL( writeStream );
       
   346         
       
   347     writeStream.WriteInt8L( aUidArray.Count() );
       
   348     
       
   349     for ( TInt i=0; i < aUidArray.Count(); ++i )
       
   350         {
       
   351         writeStream.WriteInt32L( aUidArray[i].iUid );
       
   352         }
       
   353      
       
   354     writeStream.CommitL();  
       
   355     
       
   356     CleanupStack::PopAndDestroy();
       
   357     }
       
   358     
       
   359 // ---------------------------------------------------------------------------
       
   360 // Cancel asynchronous request.
       
   361 // ---------------------------------------------------------------------------
       
   362 //
       
   363 EXPORT_C void RDiagResultsDatabase::CancelInitiateGetLastResults () const
       
   364     {
       
   365     SendReceive( DiagResultsDbCommon::ECancelInitiateGetLastResults );
       
   366     }
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // See InitiateGetLastResults. After InitiateGetLastResults finishes ok, 
       
   370 // this method can be called to retrieve data.
       
   371 // ---------------------------------------------------------------------------
       
   372 //    
       
   373 EXPORT_C TInt RDiagResultsDatabase::GetLastResults ( 
       
   374                     RPointerArray<CDiagResultsDatabaseItem>& aResults ) const
       
   375     {
       
   376     TRAPD( err, DoGetLastResultsL( aResults ) );
       
   377     return err;
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------------------------
       
   381 // Resize buffer and make the request. Data is serialized in the buffer so it 
       
   382 // must be read using a read stream.
       
   383 // ---------------------------------------------------------------------------
       
   384 //
       
   385 void RDiagResultsDatabase::DoGetLastResultsL ( 
       
   386                     RPointerArray<CDiagResultsDatabaseItem>& aResults ) const
       
   387     {
       
   388     iBuffer->Delete( 0, iBuffer->Size() );
       
   389     iBuffer->ResizeL( KResultsDatabaseBufferLength );
       
   390     
       
   391     TPtr8 ptr ( iBuffer->Ptr(0));
       
   392     //Now ask server to serialize object into this buffer
       
   393     TInt ret = SendReceive( DiagResultsDbCommon::EGetLastResults, 
       
   394                             TIpcArgs(&ptr) );
       
   395     
       
   396     while ( ret == KErrOverflow )
       
   397         {
       
   398         iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
       
   399         ptr.Set ( iBuffer->Ptr(0) );
       
   400         ret = SendReceive( DiagResultsDbCommon::EGetLastResults, 
       
   401                            TIpcArgs(&ptr) );
       
   402         }
       
   403         
       
   404     if ( ret != KErrNone )
       
   405         {
       
   406         User::Leave (ret);
       
   407         }
       
   408         
       
   409     RBufReadStream readStream ( *iBuffer );    
       
   410     TInt count = readStream.ReadInt16L();
       
   411     
       
   412     for ( TInt i = 0; i < count; ++i )
       
   413         {
       
   414         
       
   415         TUint8 value = readStream.ReadUint8L();
       
   416         if ( value == 0 )
       
   417             {
       
   418             aResults.AppendL( NULL );
       
   419             }
       
   420         else 
       
   421             {
       
   422             aResults.AppendL (CDiagResultsDatabaseItem::NewL( readStream ) );
       
   423             }
       
   424         }
       
   425         
       
   426     readStream.Close();    
       
   427     }
       
   428 
       
   429 
       
   430 // ---------------------------------------------------------------------------
       
   431 // Initiate asynchronous operation. 
       
   432 // ---------------------------------------------------------------------------
       
   433 //
       
   434 EXPORT_C void RDiagResultsDatabase::InitiateGetLastResult ( TUid aTestPluginUid, 
       
   435                                       TRequestStatus& aStatus )
       
   436     {
       
   437     TPckgBuf<TUid> uidpckg( aTestPluginUid );
       
   438     
       
   439     SendReceive( DiagResultsDbCommon::EInitiateGetSingleLastResult, 
       
   440 	             TIpcArgs( &uidpckg ), 
       
   441 	             aStatus);
       
   442     }
       
   443     
       
   444 
       
   445 // ---------------------------------------------------------------------------
       
   446 // Get last result that was fetched using InitiateGetLastResult method.
       
   447 // ---------------------------------------------------------------------------
       
   448 //
       
   449 EXPORT_C TInt RDiagResultsDatabase::GetLastResult ( 
       
   450                                        CDiagResultsDatabaseItem*& aItem )    
       
   451     {
       
   452     
       
   453     TRAPD( err, DoGetLastResultL( aItem ) );
       
   454     return err;            
       
   455     }
       
   456     
       
   457 
       
   458 // ---------------------------------------------------------------------------
       
   459 // Leaving version of the function.
       
   460 // ---------------------------------------------------------------------------
       
   461 //    
       
   462 void RDiagResultsDatabase::DoGetLastResultL ( 
       
   463                                         CDiagResultsDatabaseItem*& aItem )    
       
   464     {    
       
   465     iBuffer->Delete( 0, iBuffer->Size() );
       
   466     iBuffer->ResizeL( KResultsDatabaseBufferLength );
       
   467      	              
       
   468     TPtr8 ptr ( iBuffer->Ptr(0));
       
   469     //Now ask server to serialize object into this buffer
       
   470     TInt ret = SendReceive( DiagResultsDbCommon::EGetSingleLastResult, 
       
   471                             TIpcArgs(&ptr) );
       
   472     
       
   473     while ( ret == KErrOverflow )
       
   474         {
       
   475         iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseBufferLength );
       
   476         ptr.Set ( iBuffer->Ptr(0) );
       
   477         ret = SendReceive( DiagResultsDbCommon::EGetSingleLastResult, 
       
   478                            TIpcArgs(&ptr) );
       
   479         }
       
   480         
       
   481     if ( ret != KErrNone )
       
   482         {
       
   483         User::Leave (ret);
       
   484         }
       
   485         
       
   486     RBufReadStream readStream ( *iBuffer );  
       
   487     
       
   488     TInt count = readStream.ReadInt8L();  
       
   489    
       
   490     if ( count == 0 )
       
   491         {
       
   492         aItem = NULL;
       
   493         }
       
   494     else 
       
   495         {
       
   496         aItem = CDiagResultsDatabaseItem::NewL ( readStream );    
       
   497         }
       
   498           
       
   499     readStream.Close();
       
   500     }
       
   501     
       
   502 // ---------------------------------------------------------------------------
       
   503 // Subsession constructor.
       
   504 // ---------------------------------------------------------------------------
       
   505 //
       
   506 EXPORT_C RDiagResultsDatabaseRecord::RDiagResultsDatabaseRecord(): 
       
   507                                         iBuffer(NULL), 
       
   508                                         iOpen(EFalse)
       
   509                                         ,iPtr( NULL, 0 )
       
   510     {
       
   511     }
       
   512 
       
   513 // ---------------------------------------------------------------------------
       
   514 // Subsession destructor.
       
   515 // ---------------------------------------------------------------------------
       
   516 //
       
   517 EXPORT_C RDiagResultsDatabaseRecord::~RDiagResultsDatabaseRecord()
       
   518     {
       
   519      if ( iBuffer )
       
   520         {
       
   521         iBuffer->Reset();
       
   522         delete iBuffer;
       
   523         iBuffer = NULL;
       
   524         }
       
   525     }
       
   526 
       
   527 // ---------------------------------------------------------------------------
       
   528 // Checks if connection is already open.
       
   529 // ---------------------------------------------------------------------------
       
   530 //
       
   531 EXPORT_C TInt RDiagResultsDatabaseRecord::Connect( 
       
   532             RDiagResultsDatabase& aSession,
       
   533             TUid aRecordId,
       
   534             TBool aReadOnly ) 
       
   535     {
       
   536     LOGME("RDiagResultsDatabaseRecord::Connect");
       
   537     if ( iOpen )
       
   538         {
       
   539         return KErrAlreadyExists;
       
   540         }
       
   541     
       
   542     TRAPD( err, DoConnectL( aSession, aRecordId, aReadOnly ) );
       
   543     return err;
       
   544     }
       
   545 
       
   546 // ---------------------------------------------------------------------------
       
   547 // Creates the flat buffer and connects the subsession to a test record.
       
   548 // The test record must exist.
       
   549 // ---------------------------------------------------------------------------
       
   550 //
       
   551 void RDiagResultsDatabaseRecord::DoConnectL( 
       
   552             RDiagResultsDatabase& aSession,
       
   553             TUid aRecordId,
       
   554             TBool aReadOnly ) 
       
   555     {
       
   556     LOGME("RDiagResultsDatabaseRecord::DoConnectL");
       
   557     if (iBuffer==NULL)
       
   558 		{
       
   559 		iBuffer = CBufFlat::NewL(KResultsDatabaseGranuality);
       
   560 		
       
   561 		if (iBuffer==NULL) {
       
   562 			User::Leave( KErrNoMemory );
       
   563 		}
       
   564 		
       
   565 		iBuffer->ResizeL(KResultsDatabaseSubsessionBufferLength);
       
   566 		}
       
   567     
       
   568     iOpen = ETrue;
       
   569     
       
   570     TPckgBuf<TUid> uid( aRecordId );
       
   571     TPckgBuf<TBool> readonlyPckg( aReadOnly );
       
   572     User::LeaveIfError( CreateSubSession( aSession, 
       
   573                                       DiagResultsDbCommon::EConnectSubsession, 
       
   574                                       TIpcArgs(&uid, &readonlyPckg) ));
       
   575     }
       
   576 
       
   577 
       
   578 // ---------------------------------------------------------------------------
       
   579 // Create a new subsession and create a new test record.
       
   580 // ---------------------------------------------------------------------------
       
   581 //
       
   582 EXPORT_C TInt RDiagResultsDatabaseRecord::CreateNewRecord (
       
   583                                             RDiagResultsDatabase& aSession, 
       
   584                                             TUid& aRecordId,
       
   585                                             CDiagResultsDbRecordEngineParam& aEngineParam )
       
   586     {
       
   587     if ( iOpen )
       
   588         {
       
   589         return KErrAlreadyExists;
       
   590         }
       
   591         
       
   592     TRAPD( err, DoCreateNewRecordL( aSession, aRecordId, aEngineParam) );
       
   593     return err;
       
   594     }
       
   595 
       
   596 // ---------------------------------------------------------------------------
       
   597 // Get parameters that are needed when resuming test session.
       
   598 // ---------------------------------------------------------------------------
       
   599 //
       
   600 EXPORT_C TInt RDiagResultsDatabaseRecord::GetEngineParam( 
       
   601                         CDiagResultsDbRecordEngineParam*& aEngineParam ) const
       
   602     {
       
   603     TRAPD(err, DoGetEngineParamL( aEngineParam ) );
       
   604     return err;
       
   605     }
       
   606 
       
   607 
       
   608 // ---------------------------------------------------------------------------
       
   609 // Leaving version of GetEngineParam. Serialize EngineParam class.
       
   610 // ---------------------------------------------------------------------------
       
   611 //
       
   612 void RDiagResultsDatabaseRecord::DoGetEngineParamL( 
       
   613                         CDiagResultsDbRecordEngineParam*& aEngineParam ) const
       
   614     {
       
   615     iBuffer->Delete( 0, iBuffer->Size() );
       
   616     iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
       
   617 	
       
   618     TPtr8 ptr ( iBuffer->Ptr(0) );
       
   619     //Now ask server to serialize object into this buffer
       
   620     TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetEngineParam, 
       
   621                                                  TIpcArgs(&ptr) );
       
   622     
       
   623     while ( ret == KErrOverflow )
       
   624         {
       
   625         iBuffer->ResizeL( iBuffer->Size() 
       
   626                                 + KResultsDatabaseSubsessionBufferLength );
       
   627         ptr.Set( iBuffer->Ptr(0) );                                
       
   628         ret = SendReceive( DiagResultsDbCommon::ESubsessionGetEngineParam, 
       
   629                            TIpcArgs(&ptr) );
       
   630         }
       
   631     
       
   632     if ( ret != KErrNone )
       
   633         {
       
   634         User::Leave (ret);
       
   635         }
       
   636      
       
   637     //Stream contains the serialized array
       
   638     RBufReadStream readStream ( *iBuffer );
       
   639     CleanupClosePushL ( readStream );
       
   640     
       
   641     //Construct new test result.
       
   642     CDiagResultsDbRecordEngineParam* params = 
       
   643                                 CDiagResultsDbRecordEngineParam::NewL( readStream );
       
   644     aEngineParam = params;
       
   645    
       
   646     CleanupStack::PopAndDestroy( &readStream );
       
   647     
       
   648     iBuffer->Delete(0, iBuffer->Size() );      
       
   649     }     
       
   650 // ---------------------------------------------------------------------------
       
   651 // Create the flat buffer and create the subsession.
       
   652 // ---------------------------------------------------------------------------
       
   653 //
       
   654 void RDiagResultsDatabaseRecord::DoCreateNewRecordL (
       
   655             RDiagResultsDatabase& aSession,
       
   656             TUid& aRecordId,
       
   657             CDiagResultsDbRecordEngineParam& aEngineParam )
       
   658     {
       
   659      if (iBuffer==NULL) {
       
   660 		iBuffer = CBufFlat::NewL(KResultsDatabaseGranuality);
       
   661 		
       
   662 		if (iBuffer==NULL) {
       
   663 			User::Leave( KErrNoMemory );
       
   664 		}
       
   665 		
       
   666 		iBuffer->ResizeL(KResultsDatabaseSubsessionBufferLength);
       
   667     }
       
   668         
       
   669     iBuffer->Delete( 0, iBuffer->Size() );
       
   670     iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
       
   671     
       
   672     TPtr8 ptr ( iBuffer->Ptr(0) );    
       
   673         
       
   674     TRAPD( error, WriteEngineParamIntoBufferL( aEngineParam ) );
       
   675      
       
   676     while ( error == KErrOverflow )
       
   677         {
       
   678         iBuffer->ResizeL( iBuffer->Size() + KResultsDatabaseSubsessionBufferLength ); 
       
   679         ptr.Set( iBuffer->Ptr(0) );
       
   680         TRAP( error, WriteEngineParamIntoBufferL( aEngineParam) );
       
   681         }
       
   682         
       
   683     User::LeaveIfError ( error );
       
   684     
       
   685     TPckgBuf<TUid> pckg;
       
   686     
       
   687     TInt err = CreateSubSession( aSession, 
       
   688                               DiagResultsDbCommon::ESubsessionCreateNewRecord, 
       
   689                               TIpcArgs(&pckg, &ptr) );
       
   690     aRecordId = pckg();
       
   691     if ( err == KErrNone )
       
   692         {
       
   693         iOpen = ETrue;
       
   694         }
       
   695         
       
   696     User::LeaveIfError( err );
       
   697     }
       
   698 
       
   699 // ---------------------------------------------------------------------------
       
   700 // Write engine parameters into the buffer.
       
   701 // ---------------------------------------------------------------------------
       
   702 //
       
   703 void RDiagResultsDatabaseRecord::WriteEngineParamIntoBufferL( 
       
   704                 CDiagResultsDbRecordEngineParam& aEngineParam ) 
       
   705     {
       
   706     RBufWriteStream writeStream ( *iBuffer );
       
   707     CleanupClosePushL( writeStream );
       
   708     
       
   709     aEngineParam.ExternalizeL( writeStream );
       
   710     
       
   711     writeStream.CommitL();
       
   712     CleanupStack::PopAndDestroy();    
       
   713     }
       
   714 
       
   715 // ---------------------------------------------------------------------------
       
   716 // Close the subsession.
       
   717 // ---------------------------------------------------------------------------
       
   718 //
       
   719 EXPORT_C void RDiagResultsDatabaseRecord::Close()
       
   720     {
       
   721     if ( iOpen )
       
   722         {
       
   723         CloseSubSession( DiagResultsDbCommon::ECloseSubsession );    
       
   724         }
       
   725         
       
   726     iOpen = EFalse;
       
   727     }
       
   728 
       
   729 // ---------------------------------------------------------------------------
       
   730 
       
   731 // See ResumeTestRecord.
       
   732 // ---------------------------------------------------------------------------
       
   733 //
       
   734 EXPORT_C TInt RDiagResultsDatabaseRecord::Suspend()
       
   735     {
       
   736     return SendReceive ( DiagResultsDbCommon::ESubsessionSuspend );
       
   737     }
       
   738     
       
   739 // ---------------------------------------------------------------------------
       
   740 // Has this test record been suspended. 
       
   741 // ---------------------------------------------------------------------------
       
   742 //  
       
   743 EXPORT_C TInt RDiagResultsDatabaseRecord::IsSuspended( TBool& aSuspended ) const
       
   744     {
       
   745     TPckgBuf<TBool> pckg;
       
   746 	TInt err = SendReceive( DiagResultsDbCommon::ESubsessionIsSuspended, 
       
   747 	                        TIpcArgs(&pckg) );
       
   748 	aSuspended = pckg();
       
   749 	return err;
       
   750     }
       
   751 
       
   752 // ---------------------------------------------------------------------------
       
   753 // Returns test record Id that this subsession represents.
       
   754 // ---------------------------------------------------------------------------
       
   755 //
       
   756 EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestRecordId( 
       
   757                                                 TUid& aRecordUid ) const
       
   758     {
       
   759     TPckgBuf<TUid> pckg;
       
   760 	TInt err = SendReceive( DiagResultsDbCommon::ESubsessionGetTestRecordId, 
       
   761 	                        TIpcArgs(&pckg) );
       
   762 	aRecordUid = pckg();
       
   763 	return err;
       
   764     }
       
   765 
       
   766 
       
   767 // ---------------------------------------------------------------------------
       
   768 // Test record completion. 
       
   769 // ---------------------------------------------------------------------------
       
   770 //
       
   771 EXPORT_C TInt RDiagResultsDatabaseRecord::TestCompleted( 
       
   772                                                 TBool aFullyComplete )
       
   773     {
       
   774     TPckgBuf<TBool> pckg (aFullyComplete);
       
   775     return SendReceive ( DiagResultsDbCommon::ESubsessionTestCompleted, 
       
   776                          TIpcArgs(&pckg) );
       
   777     }
       
   778 
       
   779 // ---------------------------------------------------------------------------
       
   780 // GetStatus returns current record status.
       
   781 // ---------------------------------------------------------------------------
       
   782 //
       
   783 EXPORT_C TInt RDiagResultsDatabaseRecord::GetStatus( 
       
   784                                         TRecordStatus& aRecordStatus ) const
       
   785     {
       
   786     TPckgBuf<TRecordStatus> pckg;
       
   787 	TInt err = SendReceive( DiagResultsDbCommon::ESubsessionGetStatus, 
       
   788 	                        TIpcArgs(&pckg) );
       
   789 	aRecordStatus = pckg();
       
   790 	return err;
       
   791     }
       
   792 
       
   793 // ---------------------------------------------------------------------------
       
   794 // Indicates has the subsession been written into the DB file.
       
   795 // ---------------------------------------------------------------------------
       
   796 //
       
   797 EXPORT_C TInt RDiagResultsDatabaseRecord::IsTestCompleted( 
       
   798                                                     TBool& aCompleted ) const
       
   799     {
       
   800     TPckgBuf<TBool> pckg;
       
   801 	TInt err = SendReceive( DiagResultsDbCommon::ESubsessionIsTestCompleted, 
       
   802 	                        TIpcArgs(&pckg) );
       
   803 	aCompleted = pckg();
       
   804 	return err;
       
   805     }
       
   806 
       
   807 
       
   808 // ---------------------------------------------------------------------------
       
   809 // Returns record overview.
       
   810 // ---------------------------------------------------------------------------
       
   811 //
       
   812 EXPORT_C TInt RDiagResultsDatabaseRecord::GetRecordInfo ( 
       
   813         TDiagResultsDatabaseTestRecordInfo& aInfo ) const
       
   814     {
       
   815     TPckgBuf<TDiagResultsDatabaseTestRecordInfo> pckg;
       
   816 	TInt err = SendReceive( DiagResultsDbCommon::ESubsessionGetRecordInfo, 
       
   817 	                        TIpcArgs(&pckg) );
       
   818 	aInfo = pckg();
       
   819 	return err;
       
   820     }
       
   821 
       
   822 // ---------------------------------------------------------------------------
       
   823 // Get all test plug-in uids that are stored in the test record. 
       
   824 // ---------------------------------------------------------------------------
       
   825 //
       
   826 EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestUids ( 
       
   827                                     CArrayFixFlat<TUid>& aTestUidArray ) const
       
   828     {    
       
   829     TRAPD( err, DoGetTestUidsL( aTestUidArray ));
       
   830     return err;
       
   831     }
       
   832 
       
   833 // ---------------------------------------------------------------------------
       
   834 // Resize flat buffer, make the request. If flat buffer is not large enough
       
   835 // grow the size and make the request again.
       
   836 // ---------------------------------------------------------------------------
       
   837 //
       
   838 void RDiagResultsDatabaseRecord::DoGetTestUidsL ( 
       
   839                                     CArrayFixFlat<TUid>& aTestUidArray ) const
       
   840     {
       
   841     iBuffer->Delete( 0, iBuffer->Size() );
       
   842     iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
       
   843     
       
   844     TPtr8 ptr ( iBuffer->Ptr(0) );
       
   845     //Now ask server to serialize object into this buffer
       
   846     TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestUids, 
       
   847                             TIpcArgs(&ptr) );
       
   848     
       
   849     while ( ret == KErrOverflow )
       
   850         {
       
   851         iBuffer->ResizeL( iBuffer->Size() + 
       
   852                                 KResultsDatabaseSubsessionBufferLength );
       
   853         ptr.Set( iBuffer->Ptr(0) );                                
       
   854         ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestUids, 
       
   855                            TIpcArgs(&ptr) );
       
   856         }
       
   857     if ( ret != KErrNone )
       
   858         {
       
   859         User::Leave (ret);
       
   860         }
       
   861         
       
   862     RBufReadStream readStream ( *iBuffer );  
       
   863     CleanupClosePushL( readStream );
       
   864     TInt count = readStream.ReadInt16L();
       
   865     
       
   866     for ( TInt i = 0; i < count; ++i )
       
   867         {
       
   868         aTestUidArray.AppendL ( TUid::Uid( readStream.ReadInt32L() ));
       
   869         }
       
   870    
       
   871     CleanupStack::PopAndDestroy( &readStream );
       
   872     } 
       
   873 
       
   874 // ---------------------------------------------------------------------------
       
   875 // Store one test result into the test record. The method does not write 
       
   876 // anything.
       
   877 // ---------------------------------------------------------------------------
       
   878 //
       
   879 EXPORT_C TInt RDiagResultsDatabaseRecord::LogTestResult ( 
       
   880             TRequestStatus& aStatus,  
       
   881             const CDiagResultsDatabaseItem& aResultItem )
       
   882     {
       
   883     TRAPD(err, DoLogTestResultL( aStatus, aResultItem ) );
       
   884     return err;
       
   885     }
       
   886 
       
   887 
       
   888 // ---------------------------------------------------------------------------
       
   889 // Cancel LogTestResultL.
       
   890 // ---------------------------------------------------------------------------
       
   891 //
       
   892 EXPORT_C void RDiagResultsDatabaseRecord::CancelLogTestResult() const
       
   893     {
       
   894     SendReceive( DiagResultsDbCommon::ESubsessionCancelLogTestResult );
       
   895     }
       
   896 
       
   897 // ---------------------------------------------------------------------------
       
   898 // Resize flat buffer and serialize the object that needs to be transferred.
       
   899 // ---------------------------------------------------------------------------
       
   900 //
       
   901 void RDiagResultsDatabaseRecord::DoLogTestResultL ( 
       
   902             TRequestStatus& aStatus, 
       
   903             const CDiagResultsDatabaseItem& aResultItem )
       
   904     {
       
   905     iBuffer->Delete( 0, iBuffer->Size() );
       
   906     
       
   907     //Make sure that the buffer is big enough for the item.
       
   908     iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );  
       
   909                                                
       
   910     TRAPD( error, WriteDatabaseItemIntoBufferL( aResultItem ));
       
   911     
       
   912     while ( error == KErrOverflow )
       
   913         {
       
   914         iBuffer->ResizeL( iBuffer->Size() + aResultItem.Size() ); 
       
   915         TRAP( error, WriteDatabaseItemIntoBufferL( aResultItem ));
       
   916         }
       
   917             
       
   918     if ( error != KErrNone )
       
   919         {
       
   920         TRequestStatus* status = &aStatus;
       
   921         User::RequestComplete( status, error );
       
   922         return;
       
   923         }
       
   924     
       
   925     //Note that iPtr has to be member variable. If a new TPtr8 is defined in 
       
   926     //here it can go out of scope i.e. reading will fail in the server side.
       
   927     //Synchronous SendReceive would not have that problem.
       
   928     iPtr.Set( iBuffer->Ptr(0) );
       
   929 	SendReceive( DiagResultsDbCommon::ESubsessionLogTestResult, 
       
   930 	                        TIpcArgs(&iPtr), aStatus );
       
   931 
       
   932     }
       
   933 
       
   934 
       
   935 // ---------------------------------------------------------------------------
       
   936 // Write CDiagResultsDatabaseItem into a buffer.
       
   937 // ---------------------------------------------------------------------------
       
   938 //  
       
   939 void RDiagResultsDatabaseRecord::WriteDatabaseItemIntoBufferL( 
       
   940                                  const CDiagResultsDatabaseItem& aResultItem )
       
   941     {
       
   942     RBufWriteStream writeStream ( *iBuffer );
       
   943     CleanupClosePushL( writeStream );
       
   944     aResultItem.ExternalizeL( writeStream );
       
   945     writeStream.CommitL();
       
   946     CleanupStack::PopAndDestroy();
       
   947     }
       
   948 
       
   949 // ---------------------------------------------------------------------------
       
   950 // Get test results of the test record. 
       
   951 // ---------------------------------------------------------------------------
       
   952 //    
       
   953  EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestResults ( 
       
   954                 RPointerArray<CDiagResultsDatabaseItem>& aResultsArray ) const
       
   955     {
       
   956 
       
   957     TRAPD( err, DoGetTestResultsL( aResultsArray ) );
       
   958     return err;
       
   959     }  
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // Retrieve test results. Server serializes data into the flat buffer. 
       
   963 // Read stream can be used to deserialize data.
       
   964 // ---------------------------------------------------------------------------
       
   965 //
       
   966 void RDiagResultsDatabaseRecord::DoGetTestResultsL ( 
       
   967                 RPointerArray<CDiagResultsDatabaseItem>& aResultsArray ) const
       
   968     {
       
   969     iBuffer->Delete( 0, iBuffer->Size() );
       
   970     iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
       
   971     
       
   972     TPtr8 ptr ( iBuffer->Ptr(0));
       
   973     //Now ask server to serialize object into this buffer
       
   974     TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResults, 
       
   975                             TIpcArgs(&ptr) );
       
   976     
       
   977     while ( ret == KErrOverflow )
       
   978         {
       
   979         iBuffer->ResizeL( iBuffer->Size() + 
       
   980                           KResultsDatabaseSubsessionBufferLength );
       
   981         ptr.Set( iBuffer->Ptr(0) ); 
       
   982         ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResults, 
       
   983                            TIpcArgs(&ptr) );
       
   984         }
       
   985     if ( ret != KErrNone )
       
   986         {
       
   987         User::Leave (ret);
       
   988         }
       
   989         
       
   990     RBufReadStream readStream ( *iBuffer );    
       
   991     TInt count = readStream.ReadInt16L();
       
   992     
       
   993     for ( TInt i = 0; i < count; ++i )
       
   994         {
       
   995         aResultsArray.AppendL (CDiagResultsDatabaseItem::NewL( readStream ) );
       
   996         }
       
   997     }
       
   998 
       
   999 // ---------------------------------------------------------------------------
       
  1000 // Get only one result from the test record.
       
  1001 // ---------------------------------------------------------------------------
       
  1002 //
       
  1003 EXPORT_C TInt RDiagResultsDatabaseRecord::GetTestResult ( 
       
  1004             TUid aPluginUid, 
       
  1005             CDiagResultsDatabaseItem*& aResultItem ) const
       
  1006     {    
       
  1007     TRAPD( err, DoGetTestResultL ( aPluginUid, aResultItem ) );
       
  1008     return err;
       
  1009     }
       
  1010 
       
  1011 // ---------------------------------------------------------------------------
       
  1012 // Resize flat buffer and use read stream to retrieve data into DB item.
       
  1013 // ---------------------------------------------------------------------------
       
  1014 //
       
  1015 void RDiagResultsDatabaseRecord::DoGetTestResultL ( 
       
  1016             TUid aPluginUid, 
       
  1017             CDiagResultsDatabaseItem*& aResultItem ) const
       
  1018     {
       
  1019     iBuffer->Delete( 0, iBuffer->Size() );
       
  1020     iBuffer->ResizeL( KResultsDatabaseSubsessionBufferLength );
       
  1021 	
       
  1022     TPtr8 ptr ( iBuffer->Ptr(0) );
       
  1023     TPckgBuf<TUid> uid( aPluginUid );
       
  1024     //Now ask server to serialize object into this buffer
       
  1025     TInt ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResult, 
       
  1026                                                  TIpcArgs(&uid, &ptr) );
       
  1027     
       
  1028     while ( ret == KErrOverflow )
       
  1029         {
       
  1030         iBuffer->ResizeL( iBuffer->Size() 
       
  1031                                 + KResultsDatabaseSubsessionBufferLength );
       
  1032         ptr.Set( iBuffer->Ptr(0) );                              
       
  1033         ret = SendReceive( DiagResultsDbCommon::ESubsessionGetTestResult, 
       
  1034                            TIpcArgs(&uid, &ptr) );
       
  1035         }
       
  1036     
       
  1037     if ( ret != KErrNone )
       
  1038         {
       
  1039         User::Leave (ret);
       
  1040         }
       
  1041      
       
  1042     //Stream contains the serialized array
       
  1043     RBufReadStream readStream ( *iBuffer );
       
  1044     CleanupClosePushL( readStream );
       
  1045     
       
  1046     //Construct new test result.
       
  1047     CDiagResultsDatabaseItem* item = 
       
  1048                                 CDiagResultsDatabaseItem::NewL( readStream );
       
  1049     aResultItem = item;
       
  1050     
       
  1051     CleanupStack::PopAndDestroy( &readStream );
       
  1052     
       
  1053     iBuffer->Delete(0, iBuffer->Size() );      
       
  1054     }               
       
  1055                               
       
  1056 // ---------------------------------------------------------------------------
       
  1057 // Starts server if it's not already running. 
       
  1058 // ---------------------------------------------------------------------------
       
  1059 //
       
  1060 TInt DiagResultsDbCommon::StartServer()
       
  1061     {
       
  1062     LOGME("DiagResultsDbCommon::StartServer");
       
  1063 	TInt res(KErrNone);
       
  1064 	// create server - if one of this name does not already exist
       
  1065 	TFindServer findServer(KDiagResultsDatabaseServerName);
       
  1066 	TFullName name;
       
  1067 	if (findServer.Next(name)!=KErrNone) // we don't exist already
       
  1068 		{
       
  1069 		TRequestStatus status;
       
  1070 		RProcess server;
       
  1071 		// Create the server process
       
  1072 		res = server.Create(KDiagResultsDatabaseServerExe, KNullDesC);		
       
  1073 
       
  1074 		if( res!=KErrNone ) // thread created ok - now start it going
       
  1075 			{
       
  1076 			return res;
       
  1077 			}
       
  1078 
       
  1079 		server.Rendezvous( status );
       
  1080 		if( status != KRequestPending )
       
  1081 		    {
       
  1082 		    server.Kill(0); // abort start-up
       
  1083 		    }
       
  1084         else
       
  1085             {
       
  1086             server.Resume(); // // wait for server start-up.
       
  1087             }
       
  1088                 
       
  1089 		// Wait until the completion of the server creation
       
  1090 		User::WaitForRequest( status );
       
  1091 		if( status != KErrNone )
       
  1092 			{
       
  1093 			server.Close();
       
  1094 			return status.Int();
       
  1095 			}
       
  1096 		// Server created successfully
       
  1097 		server.Close(); // we're no longer interested in the other process
       
  1098 		}
       
  1099 	LOGME1("startserver %d",res);
       
  1100     return res;
       
  1101     }
       
  1102     
       
  1103 // ---------------------------------------------------------------------------
       
  1104 // DLL entry point
       
  1105 // ---------------------------------------------------------------------------
       
  1106 //
       
  1107 #ifndef EKA2
       
  1108 GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
       
  1109 	{
       
  1110 	return(KErrNone);
       
  1111    	}
       
  1112 #endif
       
  1113 
       
  1114