devicediagnostics/devdiagapp/src/devdiagexecutionresults_old.cpp
changeset 0 3ce708148e4d
equal deleted inserted replaced
-1:000000000000 0:3ce708148e4d
       
     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:  This class encapsulates test results from live execution runs
       
    15 *                as well as logged results and presents a common interface for
       
    16 *                both.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // System Include Files
       
    22 #include <centralrepository.h>                  // CRepository
       
    23 #include <drmserviceapi.h>                      // CDrmServiceApi
       
    24 #include <diagenginecommon.h>                   // MDiagEngineCommon
       
    25 #include <diagpluginexecplan.h>                 // CDiagPluginExecPlan
       
    26 #include <diagexecplanentry.h>                  // MDiagExecPlanEntry
       
    27 #include <diagresultsdatabaseitem.h>            // CDiagResultsDatabaseItem
       
    28 #include <diagplugin.h>                         // MDiagPlugin
       
    29 #include <diagtestplugin.h>                     // MDiagTestPlugin
       
    30 #include <diagpluginpool.h>                     // CDiagPluginPool
       
    31 #include <diagresultsdatabasetestrecordinfo.h>  // TDiagResultsDatabaseTestRecordInfo
       
    32 #include <diagresultsdatabase.h>                // RDiagResultsDatabase,
       
    33                                                 // RDiagResultsDatabaseRecord
       
    34 #include <diagframeworkdebug.h>                 // Debugging Macros
       
    35 
       
    36 // User Include Files
       
    37 #include "DevDiagExecutionResults.h"            // CDevDiagExecResults
       
    38 #include "DevDiagApp.hrh"                    // UID definition
       
    39 #include "DevDiag.pan"                 // Panic
       
    40 #include "phonedoctorprivatecrkeys.h"           // CR Key ID Definitions
       
    41 
       
    42 // Local Constants
       
    43 const TInt KRecordsArrayGranularity = ( 5 );
       
    44 
       
    45 // Local Data Types
       
    46 typedef CArrayFixFlat< TDiagResultsDatabaseTestRecordInfo > CDatabaseRecordInfoArray;
       
    47 
       
    48 
       
    49 // ============================ MEMBER FUNCTIONS =============================
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // From nested class CDevDiagExecResults::CResult.
       
    53 // Static two-phase constructor.
       
    54 // ---------------------------------------------------------------------------
       
    55 //
       
    56 CDevDiagExecResults::CResult* CDevDiagExecResults::CResult::NewL(
       
    57     const MDiagPlugin& aPlugin )
       
    58     {
       
    59     CResult* self = CResult::NewLC( aPlugin );
       
    60     CleanupStack::Pop( self );
       
    61     return self;
       
    62     }
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 // From nested class CDevDiagExecResults::CResult.
       
    66 // Static two-phase constructor.
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 CDevDiagExecResults::CResult* CDevDiagExecResults::CResult::NewLC(
       
    70     const MDiagPlugin& aPlugin )
       
    71     {
       
    72     CResult* self = new ( ELeave ) CResult( aPlugin );
       
    73     CleanupStack::PushL( self );
       
    74     self->ConstructL();
       
    75     return self;
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // From nested class CDevDiagExecResults::CResult.
       
    80 // Destructor.
       
    81 // ---------------------------------------------------------------------------
       
    82 //
       
    83 CDevDiagExecResults::CResult::~CResult()
       
    84     {
       
    85     delete iResult;
       
    86     iResult = NULL;
       
    87     }
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // From nested class CDevDiagExecResults::CResult.
       
    91 // Return the test result.  This may be NULL if the test has not been run.
       
    92 // ---------------------------------------------------------------------------
       
    93 //
       
    94 const CDiagResultsDatabaseItem* CDevDiagExecResults::CResult::Result() const
       
    95     {
       
    96     return iResult;
       
    97     }
       
    98 
       
    99 // ---------------------------------------------------------------------------
       
   100 // From nested class CDevDiagExecResults::CResult.
       
   101 // Return a reference to the plugin for this result.
       
   102 // ---------------------------------------------------------------------------
       
   103 //
       
   104 const MDiagPlugin& CDevDiagExecResults::CResult::Plugin() const
       
   105     {
       
   106     return iPlugin;
       
   107     }
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // From nested class CDevDiagExecResults::CResult.
       
   111 // Return the execution error code.
       
   112 // ---------------------------------------------------------------------------
       
   113 //
       
   114 TInt CDevDiagExecResults::CResult::ExecStatus() const
       
   115     {
       
   116     return iExecStatus;
       
   117     }
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // From nested class CDevDiagExecResults::CResult.
       
   121 // Return the current execution step for this result.
       
   122 // ---------------------------------------------------------------------------
       
   123 //
       
   124 TUint CDevDiagExecResults::CResult::CurrentStep() const
       
   125     {
       
   126     return iCurrentStep;
       
   127     }
       
   128 
       
   129 // ---------------------------------------------------------------------------
       
   130 // From nested class CDevDiagExecResults::CResult.
       
   131 // Return the total execution steps for this result.
       
   132 // ---------------------------------------------------------------------------
       
   133 //
       
   134 TUint CDevDiagExecResults::CResult::TotalSteps() const
       
   135     {
       
   136     return iTotalSteps;
       
   137     }
       
   138 
       
   139 // ---------------------------------------------------------------------------
       
   140 // From nested class CDevDiagExecResults::CResult.
       
   141 // This function takes ownership of a result object.
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 void CDevDiagExecResults::CResult::SetResult(
       
   145     CDiagResultsDatabaseItem* aResult,
       
   146     TInt aError )
       
   147     {
       
   148     // Sanity check.
       
   149     if ( iResult )
       
   150         {
       
   151         delete iResult;
       
   152         }
       
   153 
       
   154     // Set the result and error code Ownership of the result is transferred.
       
   155     iResult = aResult;
       
   156     iExecStatus = aError;
       
   157     }
       
   158 
       
   159 // ---------------------------------------------------------------------------
       
   160 // From nested class CDevDiagExecResults::CResult.
       
   161 // Set the progress information for this result.
       
   162 // ---------------------------------------------------------------------------
       
   163 //
       
   164 void CDevDiagExecResults::CResult::SetProgress( TUint aCurrentStep,
       
   165                                                 TUint aTotalSteps )
       
   166     {
       
   167     iCurrentStep = aCurrentStep;
       
   168     iTotalSteps = aTotalSteps;
       
   169     }
       
   170 
       
   171 // ---------------------------------------------------------------------------
       
   172 // From nested class CDevDiagExecResults::CResult.
       
   173 // The default constructor.
       
   174 // ---------------------------------------------------------------------------
       
   175 //
       
   176 CDevDiagExecResults::CResult::CResult( const MDiagPlugin& aPlugin )
       
   177 :   iPlugin( aPlugin )
       
   178     {
       
   179     }
       
   180 
       
   181 // ---------------------------------------------------------------------------
       
   182 // From nested class CDevDiagExecResults::CResult.
       
   183 // The second phase constructor.
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 void CDevDiagExecResults::CResult::ConstructL()
       
   187     {
       
   188     }
       
   189 
       
   190 
       
   191 // ============================ MEMBER FUNCTIONS =============================
       
   192 
       
   193 // ---------------------------------------------------------------------------
       
   194 // Static two-phase constructor.
       
   195 // ---------------------------------------------------------------------------
       
   196 //
       
   197 CDevDiagExecResults* CDevDiagExecResults::NewL(
       
   198     TUid aRecordId,
       
   199     CDiagPluginPool& aPluginPool,
       
   200     RDiagResultsDatabase& aDbSession,
       
   201     MDiagEngineCommon* aDiagEngine )
       
   202     {
       
   203     LOGSTRING3( "CDevDiagExecResults::NewL( %d, 0x%x )",
       
   204                 aRecordId.iUid,
       
   205                 aDiagEngine )
       
   206 
       
   207     CDevDiagExecResults* self = CDevDiagExecResults::NewLC( aRecordId,
       
   208                                                             aPluginPool,
       
   209                                                             aDbSession,
       
   210                                                             aDiagEngine );
       
   211     CleanupStack::Pop( self );
       
   212     return self;
       
   213     }
       
   214 
       
   215 // ---------------------------------------------------------------------------
       
   216 // Static two-phase constructor.
       
   217 // ---------------------------------------------------------------------------
       
   218 //
       
   219 CDevDiagExecResults* CDevDiagExecResults::NewLC(
       
   220     TUid aRecordId,
       
   221     CDiagPluginPool& aPluginPool,
       
   222     RDiagResultsDatabase& aDbSession,
       
   223     MDiagEngineCommon* aDiagEngine )
       
   224     {
       
   225     LOGSTRING3( "CDevDiagExecResults::NewLC( %d, 0x%x )",
       
   226                 aRecordId.iUid,
       
   227                 aDiagEngine )
       
   228 
       
   229     CDevDiagExecResults* self = new ( ELeave ) CDevDiagExecResults(
       
   230         aRecordId,
       
   231         aPluginPool,
       
   232         aDbSession,
       
   233         aDiagEngine );
       
   234     CleanupStack::PushL( self );
       
   235     self->ConstructL();
       
   236     return self;
       
   237     }
       
   238 
       
   239 // ---------------------------------------------------------------------------
       
   240 // Destructor.
       
   241 // ---------------------------------------------------------------------------
       
   242 //
       
   243 CDevDiagExecResults::~CDevDiagExecResults()
       
   244     {
       
   245     LOGSTRING( "CDevDiagExecResults::~CDevDiagExecResults()" )
       
   246     iResults.ResetAndDestroy();
       
   247     }
       
   248 
       
   249 // ---------------------------------------------------------------------------
       
   250 // This function is called during live execution to transfer ownership of a
       
   251 // test result.
       
   252 // ---------------------------------------------------------------------------
       
   253 //
       
   254 void CDevDiagExecResults::AddEntryL( CDiagResultsDatabaseItem* aResult,
       
   255                                      TInt aStatus )
       
   256     {
       
   257     LOGSTRING3( "CDevDiagExecResults::AddEntryL( 0x%x, %d )",
       
   258                 aResult,
       
   259                 aStatus )
       
   260 
       
   261     // This is only valid for live executions.
       
   262     if ( iType != ETypeExecution )
       
   263         {
       
   264         delete aResult;
       
   265         User::Leave( KErrCompletion );
       
   266         }
       
   267 
       
   268     // Assign the result object to the corresponding item in the local array.
       
   269     iResults[ CurrentIndexL() ]->SetResult( aResult, aStatus );
       
   270 
       
   271     // Update the completed step counter.
       
   272     if ( iResults[ CurrentIndexL() ]->Plugin().Type() ==
       
   273         MDiagPlugin::ETypeTestPlugin )
       
   274         {
       
   275         iCompletedSteps += static_cast< const MDiagTestPlugin& >(
       
   276             iResults[ CurrentIndexL() ]->Plugin() ).TotalSteps();
       
   277         }
       
   278     iCurrentPluginStep = 0;
       
   279     }
       
   280 
       
   281 // ---------------------------------------------------------------------------
       
   282 // This function is called during live execution to transfer ownership of a
       
   283 // test result.
       
   284 // ---------------------------------------------------------------------------
       
   285 //
       
   286 void CDevDiagExecResults::SetProgressL( TUint aCurrentStep, TUint aTotalSteps )
       
   287     {
       
   288     LOGSTRING3( "CDevDiagExecResults::SetProgressL( %d, %d )",
       
   289             aCurrentStep,
       
   290             aTotalSteps )
       
   291 
       
   292     // This is only valid for live executions.
       
   293     if ( iType != ETypeExecution )
       
   294         {
       
   295         return;
       
   296         }
       
   297 
       
   298     // Assign the progress to the corresponding item in the local array.
       
   299     iResults[ CurrentIndexL() ]->SetProgress( aCurrentStep, aTotalSteps );
       
   300 
       
   301     // Update the current step counter.
       
   302     if ( iResults[ CurrentIndexL() ]->Plugin().Type() ==
       
   303         MDiagPlugin::ETypeTestPlugin )
       
   304         {
       
   305         iCurrentPluginStep = aCurrentStep;
       
   306         }
       
   307     else
       
   308         {
       
   309         iCurrentPluginStep = 0;
       
   310         }
       
   311     }
       
   312 
       
   313 // ---------------------------------------------------------------------------
       
   314 // This function returns the corresponding results item from the local array.
       
   315 // ---------------------------------------------------------------------------
       
   316 //
       
   317 CDevDiagExecResults::CResult& CDevDiagExecResults::operator[] ( TInt aIndex )
       
   318     {
       
   319     return *iResults[ aIndex ];
       
   320     }
       
   321 
       
   322 // ---------------------------------------------------------------------------
       
   323 // This function returns the corresponding results item from the local array.
       
   324 // ---------------------------------------------------------------------------
       
   325 //
       
   326 const CDevDiagExecResults::CResult& CDevDiagExecResults::operator[] (
       
   327     TInt aIndex ) const
       
   328     {
       
   329     return *iResults[ aIndex ];
       
   330     }
       
   331 
       
   332 // ---------------------------------------------------------------------------
       
   333 // This function returns the current item from the local array.  For results
       
   334 // which are from execution, this is the current execution item.  For results
       
   335 // which are from the database, this is always the last item.
       
   336 // ---------------------------------------------------------------------------
       
   337 //
       
   338 CDevDiagExecResults::CResult& CDevDiagExecResults::CurrentItemL()
       
   339     {
       
   340     return *iResults[ CurrentIndexL() ];
       
   341     }
       
   342 
       
   343 // ---------------------------------------------------------------------------
       
   344 // This function returns the current item from the local array.  For results
       
   345 // which are from execution, this is the current execution item.  For results
       
   346 // which are from the database, this is always the last item.
       
   347 // ---------------------------------------------------------------------------
       
   348 //
       
   349 const CDevDiagExecResults::CResult& CDevDiagExecResults::CurrentItemL() const
       
   350     {
       
   351     return *iResults[ CurrentIndexL() ];
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // This function returns the number of items in the local array.
       
   356 // ---------------------------------------------------------------------------
       
   357 //
       
   358 TInt CDevDiagExecResults::Count() const
       
   359     {
       
   360     return iResults.Count();
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // This function returns the index of the currently-executing item.
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 TUint CDevDiagExecResults::CurrentIndexL() const
       
   368     {
       
   369     // For live execution, the index from the execution plan is returned.
       
   370     if ( iType == ETypeExecution )
       
   371         {
       
   372         TUint index = 0;
       
   373         index = iDiagEngine->ExecutionPlanL().CurrentIndex();
       
   374         return index;
       
   375         }
       
   376 
       
   377     // For logged test results, the last index is returned.
       
   378     return iResults.Count() - 1;
       
   379     }
       
   380 
       
   381 // ---------------------------------------------------------------------------
       
   382 // This utility function allows the result view to check if testing is
       
   383 // complete so that it can cancel the progress dialog.
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 TBool CDevDiagExecResults::IsLastTestL() const
       
   387     {
       
   388     return ( CurrentIndexL() == ( Count() - 1 ) );
       
   389     }
       
   390 
       
   391 // ---------------------------------------------------------------------------
       
   392 // This utility function checks to see if a test is being executed / was
       
   393 // executed as a dependency.
       
   394 // ---------------------------------------------------------------------------
       
   395 //
       
   396 TBool CDevDiagExecResults::IsDependencyL( TInt aIndex ) const
       
   397     {
       
   398     __ASSERT_ALWAYS( ( aIndex < Count() ), Panic( EPDApplicationGeneral ) );
       
   399 
       
   400     // For live execution, get the information from the execution plan.
       
   401     if ( iType == ETypeExecution )
       
   402         {
       
   403         TBool dependent = EFalse;
       
   404         dependent = iDiagEngine->ExecutionPlanL()[ aIndex ].AsDependency();
       
   405         return dependent;
       
   406         }
       
   407 
       
   408     // For logged test results, get the information from the test result.  The
       
   409     // NULL check is needed in case the plugin failed during running and did
       
   410     // not report a result.
       
   411     if ( iResults[ aIndex ]->Result() )
       
   412         {
       
   413         return iResults[ aIndex ]->Result()->WasDependency();
       
   414         }
       
   415     else
       
   416         {
       
   417         return EFalse;
       
   418         }
       
   419     }
       
   420 
       
   421 // ---------------------------------------------------------------------------
       
   422 // This function locks "execution" style results from further changes, by
       
   423 // changing the results type and clearing the reference to the engine.
       
   424 // ---------------------------------------------------------------------------
       
   425 //
       
   426 void CDevDiagExecResults::Finalize()
       
   427     {
       
   428     LOGSTRING( "CDevDiagExecResults::Finalize()" )
       
   429 
       
   430     iDiagEngine = NULL;
       
   431     iType = ETypeLog;
       
   432     iCompletedSteps = iTotalSteps;
       
   433     iCurrentPluginStep = 0;
       
   434     }
       
   435 
       
   436 // ---------------------------------------------------------------------------
       
   437 // This function returns the total number of steps for all items in the
       
   438 // execution results.
       
   439 // ---------------------------------------------------------------------------
       
   440 //
       
   441 TInt CDevDiagExecResults::TotalExecutionSteps() const
       
   442     {
       
   443     return iTotalSteps;
       
   444     }
       
   445 
       
   446 // ---------------------------------------------------------------------------
       
   447 // This function returns the current execution step based on all items in the
       
   448 // execution results.
       
   449 // ---------------------------------------------------------------------------
       
   450 //
       
   451 TInt CDevDiagExecResults::CurrentExecutionStep() const
       
   452     {
       
   453     return iCompletedSteps + iCurrentPluginStep;
       
   454     }
       
   455 
       
   456 // ---------------------------------------------------------------------------
       
   457 // Gets information about the test log.
       
   458 // ---------------------------------------------------------------------------
       
   459 //
       
   460 void CDevDiagExecResults::GetSessionInformationL( TInt& aSessionNumber,
       
   461                                                   TInt& aTimeInterval,
       
   462                                                   TTime& aStartTime,
       
   463                                                   TTime& aEndTime ) const
       
   464     {
       
   465     LOGSTRING( "CDevDiagExecResults::GetSessionInformationL()" )
       
   466 
       
   467     // Get the time interval from the Central Repository.
       
   468     CRepository* repository = CRepository::NewLC( KCRUidPhoneDoctor );
       
   469     User::LeaveIfError( repository->Get( KPDAppMaxUseTime, aTimeInterval ) );
       
   470     CleanupStack::PopAndDestroy( repository );
       
   471 
       
   472     // Get the list of database records.
       
   473     CDatabaseRecordInfoArray* oldRecords =
       
   474         new ( ELeave ) CDatabaseRecordInfoArray( KRecordsArrayGranularity );
       
   475     CleanupStack::PushL( oldRecords );
       
   476     User::LeaveIfError( iDbSession.GetAllRecordInfos( *oldRecords ) );
       
   477 
       
   478     // Get the current DRM time.
       
   479     TTime currentTime( TInt64( 0 ) );
       
   480     DRM::CDrmServiceApi* drmApi = DRM::CDrmServiceApi::NewLC();
       
   481     TInt timeZone = 0;
       
   482     DRMClock::ESecurityLevel secLevel = DRMClock::KInsecure;
       
   483     User::LeaveIfError( drmApi->GetSecureTime( currentTime,
       
   484                                                timeZone,
       
   485                                                secLevel ) );
       
   486     CleanupStack::PopAndDestroy( drmApi );
       
   487 
       
   488     // Go through the records list.
       
   489     aSessionNumber = 0;
       
   490     for ( TInt i = 0; i < oldRecords->Count(); i++ )
       
   491         {
       
   492         TDiagResultsDatabaseTestRecordInfo record = (*oldRecords)[ i ];
       
   493 
       
   494         // If this record matches the one we have execution results for, store
       
   495         // its start and end time.
       
   496         if ( record.iRecordId == iRecordId )
       
   497             {
       
   498             aStartTime = record.iStartTime;
       
   499             aEndTime = record.iFinishTime;
       
   500             }
       
   501 
       
   502         // Check the time interval that this record occured in.
       
   503         TTimeIntervalSeconds timeDifference( 0 );
       
   504         currentTime.SecondsFrom( record.iDrmStartTime, timeDifference );
       
   505         if ( timeDifference.Int() <= aTimeInterval )
       
   506             {
       
   507             aSessionNumber++;
       
   508             }
       
   509         }
       
   510 
       
   511     // Free the records information.
       
   512     CleanupStack::PopAndDestroy( oldRecords );
       
   513     }
       
   514 
       
   515 // ---------------------------------------------------------------------------
       
   516 // The default constructor.
       
   517 // ---------------------------------------------------------------------------
       
   518 //
       
   519 CDevDiagExecResults::CDevDiagExecResults( TUid aRecordId,
       
   520                                           CDiagPluginPool& aPluginPool,
       
   521                                           RDiagResultsDatabase& aDbSession,
       
   522                                           MDiagEngineCommon* aDiagEngine )
       
   523 :   iRecordId( aRecordId ),
       
   524     iPluginPool( aPluginPool ),
       
   525     iDbSession( aDbSession ),
       
   526     iDiagEngine( aDiagEngine )
       
   527     {
       
   528     LOGSTRING3( "CDevDiagExecResults::CDevDiagExecResults( %d, 0x%x )",
       
   529                 aRecordId.iUid,
       
   530                 aDiagEngine )
       
   531 
       
   532     }
       
   533 
       
   534 // ---------------------------------------------------------------------------
       
   535 // The second phase constructor.
       
   536 // ---------------------------------------------------------------------------
       
   537 //
       
   538 void CDevDiagExecResults::ConstructL()
       
   539     {
       
   540     LOGSTRING( "CDevDiagExecResults::ConstructL()" )
       
   541 
       
   542     // There are two types of results: (1) Current Execution, and (2) Logs.
       
   543 
       
   544     // (1) If a pointer to the diagnostics engine was provided, then it is
       
   545     // assumed that the results are from a live execution and this object will
       
   546     // wait for the results to be assigned .
       
   547     if ( iDiagEngine )
       
   548         {
       
   549         // This is the "current execution" type.
       
   550         iType = ETypeExecution;
       
   551         const MDiagPluginExecPlan& execPlan = iDiagEngine->ExecutionPlanL();
       
   552 
       
   553         // Add an entry for every item in the plan.
       
   554         TUint numItems = execPlan.Count();
       
   555         for ( TUint i = 0; i < numItems; i++ )
       
   556             {
       
   557             CResult* result = CResult::NewLC( execPlan[i].Plugin() );
       
   558             iResults.AppendL( result );
       
   559             CleanupStack::Pop( result );
       
   560 
       
   561             // Update the total step counter with this plugin's information.
       
   562             if ( execPlan[i].Plugin().Type() == MDiagPlugin::ETypeTestPlugin )
       
   563                 {
       
   564                 iTotalSteps += static_cast< const MDiagTestPlugin& >(
       
   565                     execPlan[i].Plugin() ).TotalSteps();
       
   566                 }
       
   567             }
       
   568         }
       
   569     // (2) If no pointer to the diagnostics engine was provided, then all the
       
   570     // results which correspond to the record id will be looked up from the
       
   571     // results database.
       
   572     else
       
   573         {
       
   574         // This is the "logged" type.
       
   575         iType = ETypeLog;
       
   576 
       
   577         // Get the record's results from the database.
       
   578         RDiagResultsDatabaseRecord dbRecord;
       
   579         User::LeaveIfError( dbRecord.Connect( iDbSession, iRecordId ) );
       
   580         CleanupClosePushL( dbRecord );
       
   581         RPointerArray< CDiagResultsDatabaseItem > logResults;
       
   582         CleanupClosePushL( logResults );
       
   583         User::LeaveIfError( dbRecord.GetTestResults( logResults ) );
       
   584 
       
   585         // Add an entry for each result item.
       
   586         TUint numItems = logResults.Count();
       
   587         for ( TUint i = 0; i < numItems; i++ )
       
   588             {
       
   589             MDiagPlugin* plugin = NULL;
       
   590             TInt err = iPluginPool.FindPlugin( logResults[i]->TestUid(),
       
   591                                                plugin );
       
   592 
       
   593             // If a matching plugin was not found for this result, we just
       
   594             // skip over it, because we can't do anything useful with it.
       
   595             // This case should only occur if a plugin logged results
       
   596             // previously, but was later removed from the phone.
       
   597             if ( err != KErrNone )
       
   598                 {
       
   599                 continue; //lint !e960 A continue makes sense here.
       
   600                 }
       
   601 
       
   602             CResult* result = CResult::NewLC( *plugin );
       
   603 
       
   604             // Ownership of the results item is transferred.
       
   605             result->SetResult( logResults[i], KErrNone );
       
   606             logResults[i] = NULL;
       
   607 
       
   608             iResults.AppendL( result );
       
   609             CleanupStack::Pop( result );
       
   610             }
       
   611 
       
   612         CleanupStack::Pop(); // logResults
       
   613         CleanupStack::PopAndDestroy(); // dbRecord
       
   614         logResults.ResetAndDestroy();
       
   615 
       
   616         // Set dummy numbers for the execution steps.
       
   617         iTotalSteps = 1;
       
   618         iCompletedSteps = 1;
       
   619         }
       
   620     }
       
   621 
       
   622 // End of File