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