gssettingsuis/Gs/GSFramework/src/GSWatchDog.cpp
branchRCL_3
changeset 25 7e0eff37aedb
equal deleted inserted replaced
24:8ee96d21d9bf 25:7e0eff37aedb
       
     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: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include    <bldvariant.hrh>
       
    21 #include    <featmgr.h>
       
    22 #include    <centralrepository.h>
       
    23 
       
    24 // USER INCLUDES
       
    25 #include    "GSWatchDog.h"
       
    26 #include    "GsLogger.h"
       
    27 #include    "settingsinternalcrkeys.h"
       
    28 #include    "SettingsPrivateCRKeys.h"
       
    29 
       
    30 #include    <eikenv.h>
       
    31 #include    <s32mem.h>
       
    32 #include    <centralrepository.h>
       
    33 
       
    34 using namespace NCentralRepositoryConstants;
       
    35 
       
    36 // CONSTANTS
       
    37 
       
    38 
       
    39 // ========================= MEMBER FUNCTIONS ================================
       
    40 
       
    41 // ----------------------------------------------------------------------------
       
    42 // CGSWatchDog::NewL
       
    43 //
       
    44 // EPOC two-phased constructor
       
    45 // ----------------------------------------------------------------------------
       
    46 //
       
    47 CGSWatchDog* CGSWatchDog::NewL()
       
    48     {
       
    49     CGSWatchDog* self = new( ELeave ) CGSWatchDog;
       
    50     CleanupStack::PushL( self );
       
    51     self->ConstructL();
       
    52     CleanupStack::Pop( self );
       
    53     return self;
       
    54     }
       
    55 
       
    56 
       
    57 // ----------------------------------------------------------------------------
       
    58 // CGSWatchDog::ConstructL
       
    59 //
       
    60 // EPOC default constructor can leave.
       
    61 // ----------------------------------------------------------------------------
       
    62 //
       
    63 void CGSWatchDog::ConstructL()
       
    64     {
       
    65     __GSLOGSTRING( "[CGSWatchDog] ConstructL()" );
       
    66     iStore = CRepository::NewL( KCRUidMiscSettings );
       
    67 
       
    68     // Read last stored state for watchdog...
       
    69     ReadStateL();
       
    70 
       
    71     // If GS crashed last time, activate watchdog, reset run counter. Watchdog
       
    72     // will be active as long as exit was not clean (panicked).
       
    73     if( !WasCleanExitL() &&
       
    74         iWatchdogActivationLimit != KGSWatchdogActivationDisabled  )
       
    75         {
       
    76         iCrashCounter++;
       
    77         iIsActive = ETrue;
       
    78 
       
    79 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
    80     #pragma message("-CGSWachDog verbose traces activated-")
       
    81     User::InfoPrint( _L("Watchdog activated!") );
       
    82 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
    83 
       
    84         if( iQuarantine.Count() > 0 )
       
    85             {
       
    86             for( TInt i = 0; i < iQuarantine.Count(); i++ )
       
    87                 {
       
    88                 // If plugin is not already in blacklist, move it there from
       
    89                 // quarantinelist.
       
    90                 if( !IsInBlackList( iQuarantine[i] ) )
       
    91                     {
       
    92                     TGSPluginQuarantine quarantinedPlugin;
       
    93                     quarantinedPlugin.iRunsAfterCrash = 0;
       
    94                     quarantinedPlugin.iUid = iQuarantine[i];
       
    95                     iBlackList.AppendL( quarantinedPlugin );
       
    96                     iQuarantine.Remove( i );
       
    97                     }
       
    98                 }
       
    99             }
       
   100         }
       
   101      else
       
   102         {
       
   103         iIsActive = EFalse;
       
   104         iCrashCounter = 0;
       
   105 
       
   106 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
   107     User::InfoPrint( _L("Watchdog disabled.") );
       
   108 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
   109 
       
   110         // Clean run -> empty quarantine.
       
   111         iQuarantine.Reset();
       
   112         }
       
   113 
       
   114     // Continue normal progress, set application to run state...
       
   115     iGSAppRunning = ETrue;
       
   116 
       
   117     // Store watchdog state at this point as panic will not call normal
       
   118     // destructors and data would be otherwise lost in case of panic.
       
   119     StoreStateL();
       
   120     }
       
   121 
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // CGSWatchDog::CGSWatchDog
       
   125 //
       
   126 // C++ constructor
       
   127 // ---------------------------------------------------------------------------
       
   128 CGSWatchDog::CGSWatchDog()
       
   129     {
       
   130     }
       
   131 
       
   132 
       
   133 
       
   134 // ---------------------------------------------------------------------------
       
   135 // CGSWatchDog::~CGSWatchDog
       
   136 //
       
   137 // Destructor
       
   138 // ---------------------------------------------------------------------------
       
   139 CGSWatchDog::~CGSWatchDog()
       
   140     {
       
   141     // Update all blacklisted plugins in case no crash FIRST, then store...
       
   142     UpdateBlackListedPluginRunCounters();
       
   143     TRAP_IGNORE( StoreStateL(); );
       
   144     iBlackList.Close();
       
   145     iQuarantine.Close();
       
   146     delete iStore;
       
   147     }
       
   148 
       
   149 
       
   150 // ---------------------------------------------------------------------------
       
   151 // CGSWatchDog::Quarantine
       
   152 //
       
   153 //
       
   154 // ---------------------------------------------------------------------------
       
   155 void CGSWatchDog::QuarantineL( TUid aPluginUid )
       
   156     {
       
   157     if( iIsActive )
       
   158         {
       
   159         iQuarantine.AppendL( aPluginUid );
       
   160         StoreQuarantineL(); // Store to persistent storage
       
   161 
       
   162 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
   163     __GSLOGSTRING1( "[CGSWatchDog] Quarantined:0x%X", aPluginUid.iUid );
       
   164 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
   165 
       
   166         }
       
   167     }
       
   168 
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // CGSWatchDog::RemoveFromQuarantine
       
   172 //
       
   173 //
       
   174 // ---------------------------------------------------------------------------
       
   175 void CGSWatchDog::RemoveFromQuarantineL( TUid aPluginUid )
       
   176     {
       
   177     if( iIsActive )
       
   178         {
       
   179         for( TInt i = 0; i < iQuarantine.Count(); i++ )
       
   180             {
       
   181             if( iQuarantine[i] == aPluginUid )
       
   182                 {
       
   183                 iQuarantine.Remove( i );
       
   184 
       
   185 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
   186     __GSLOGSTRING1( "[CGSWatchDog] Removed from quarantine:0x%X", aPluginUid.iUid );
       
   187 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
   188 
       
   189                 StoreQuarantineL();
       
   190                 break;
       
   191                 }
       
   192             }
       
   193         }
       
   194     }
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 // CGSWatchDog::WasCleanExit
       
   198 //
       
   199 //
       
   200 // ---------------------------------------------------------------------------
       
   201 TBool CGSWatchDog::WasCleanExitL()
       
   202     {
       
   203     return !iGSAppRunning;
       
   204     }
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // CGSWatchDog::ReportCleanExit
       
   208 //
       
   209 //
       
   210 // ---------------------------------------------------------------------------
       
   211 void CGSWatchDog::ReportCleanExitL()
       
   212     {
       
   213     iGSAppRunning = EFalse;
       
   214     iStore->Set( KWatchDogGSRunning, iGSAppRunning );
       
   215     }
       
   216 
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // CGSWatchDog::IsInBlackList
       
   220 //
       
   221 //
       
   222 // ---------------------------------------------------------------------------
       
   223 TBool CGSWatchDog::IsInBlackList( TUid aPluginUid )
       
   224     {
       
   225     TBool found = EFalse;
       
   226     if( iIsActive )
       
   227         {
       
   228         for( TInt i = 0; i < iBlackList.Count(); i++ )
       
   229             {
       
   230             if( iBlackList[i].iUid == aPluginUid )
       
   231                 {
       
   232                 found = ETrue;
       
   233                 break;
       
   234                 }
       
   235             }
       
   236         }
       
   237     
       
   238     return found;
       
   239     }
       
   240 
       
   241 
       
   242 // ---------------------------------------------------------------------------
       
   243 // CGSWatchDog::StoreStateL
       
   244 //
       
   245 //
       
   246 // ---------------------------------------------------------------------------
       
   247 void CGSWatchDog::StoreStateL()
       
   248     {
       
   249     //iStore->Set( KWatchDogIsActive,         iIsActive );
       
   250     iStore->Set( KWatchDogGSRunning,        iGSAppRunning );
       
   251     iStore->Set( KWatchDogCrashCounter,     iCrashCounter );
       
   252     iStore->Set( KWatchdogActivationLimit,  iWatchdogActivationLimit );
       
   253     iStore->Set( KWatchdogMaxPluginBlackListedRuns,   iMaxPluginBlackListedRuns );
       
   254 
       
   255     StoreQuarantineL();
       
   256     StoreBlackListL();
       
   257 
       
   258 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
   259     // The following is just for debug trace:
       
   260     __GSLOGSTRING( "[CGSWatchDog] Storing state:" );
       
   261     __GSLOGSTRING1( "   iIsActive: %d",     iIsActive );
       
   262     __GSLOGSTRING1( "   iGSAppRunning: %d", iGSAppRunning );
       
   263     __GSLOGSTRING1( "   iCrashCounter: %d",   iCrashCounter );
       
   264     __GSLOGSTRING1( "   iWatchdogActivationLimit: %d", iWatchdogActivationLimit );
       
   265     __GSLOGSTRING1( "   iMaxPluginBlackListedRuns: %d", iMaxPluginBlackListedRuns );
       
   266 
       
   267     __GSLOGSTRING( "[CGSWatchDog] Stored plugins from quarantine:" );
       
   268     for( TInt i = 0; i < iQuarantine.Count(); i++ )
       
   269         {
       
   270             __GSLOGSTRING1( "    0x%X", iQuarantine[i].iUid );
       
   271         }
       
   272     __GSLOGSTRING( "-" );
       
   273 
       
   274     __GSLOGSTRING( "[CGSWatchDog] Stored plugins from blacklist:" );
       
   275     for( TInt i = 0; i < iBlackList.Count(); i++ )
       
   276         {
       
   277             __GSLOGSTRING2( "    0x%X %d runs", iBlackList[i].iUid.iUid, iBlackList[i].iRunsAfterCrash );
       
   278         }
       
   279     __GSLOGSTRING( "-" );
       
   280 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
   281     }
       
   282 
       
   283 
       
   284 // ---------------------------------------------------------------------------
       
   285 // CGSWatchDog::ReadStateL
       
   286 //
       
   287 //
       
   288 // ---------------------------------------------------------------------------
       
   289 void CGSWatchDog::ReadStateL()
       
   290     {
       
   291     /*TInt isActive = EFalse; // Needed for mapping to TBool value
       
   292     TInt err = iStore->Get( KWatchDogIsActive, isActive );
       
   293     if( isActive == 1 )
       
   294         {
       
   295         iIsActive = ETrue;
       
   296         }
       
   297     else
       
   298         {
       
   299         iIsActive = EFalse;
       
   300         }*/
       
   301 
       
   302     TInt appRunning; // Needed for mapping to TBool value
       
   303     TInt err = iStore->Get( KWatchDogGSRunning, appRunning );
       
   304 
       
   305     if( err )
       
   306         {
       
   307         // CenRep values are uninitialized: first runtime of watchdog
       
   308         // -> init values
       
   309         InitStateL();
       
   310         }
       
   311 
       
   312     if( appRunning )
       
   313         {
       
   314         iGSAppRunning = ETrue;
       
   315         }
       
   316     else
       
   317         {
       
   318         iGSAppRunning = EFalse;
       
   319         }
       
   320 
       
   321     iStore->Get( KWatchDogCrashCounter, iCrashCounter );
       
   322     iStore->Get( KWatchdogActivationLimit, iWatchdogActivationLimit );
       
   323     iStore->Get( KWatchdogMaxPluginBlackListedRuns, iMaxPluginBlackListedRuns );
       
   324 
       
   325     ReadQuarantineL();
       
   326     ReadBlackListL();
       
   327 
       
   328 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
   329     // The following is just for debug trace:
       
   330     __GSLOGSTRING( "[CGSWatchDog] Read state:" );
       
   331     __GSLOGSTRING1( "   iIsActive: %d",     iIsActive );
       
   332     __GSLOGSTRING1( "   iGSAppRunning: %d", iGSAppRunning );
       
   333     __GSLOGSTRING1( "   iCrashCounter: %d", iCrashCounter );
       
   334     __GSLOGSTRING1( "   iWatchdogActivationLimit: %d", iWatchdogActivationLimit );
       
   335     __GSLOGSTRING1( "   iMaxPluginBlackListedRuns: %d", iMaxPluginBlackListedRuns );
       
   336 
       
   337     __GSLOGSTRING( "[CGSWatchDog] Read plugins from quarantine:" );
       
   338     for( TInt i = 0; i < iQuarantine.Count(); i++ )
       
   339         {
       
   340             __GSLOGSTRING1( "    0x%X", iQuarantine[i].iUid );
       
   341         }
       
   342     __GSLOGSTRING( "-" );
       
   343 
       
   344     __GSLOGSTRING( "[CGSWatchDog] Read plugins from blacklist:" );
       
   345     for( TInt i = 0; i < iBlackList.Count(); i++ )
       
   346         {
       
   347             __GSLOGSTRING2( "    0x%X %d runs", iBlackList[i].iUid.iUid, iBlackList[i].iRunsAfterCrash );
       
   348         }
       
   349     __GSLOGSTRING( "-" );
       
   350 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
   351     }
       
   352 
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // CGSWatchDog::InitStateL
       
   356 //
       
   357 //
       
   358 // ---------------------------------------------------------------------------
       
   359 void CGSWatchDog::InitStateL()
       
   360     {
       
   361     __GSLOGSTRING( "[CGSWatchDog] initializing state..." );
       
   362     iIsActive = EFalse;
       
   363     iGSAppRunning = EFalse;
       
   364     iCrashCounter = 0;
       
   365 
       
   366     // Check CenRep, if values do not exist, use default values:
       
   367     TInt err;
       
   368     err = iStore->Get( KWatchDogCrashCounter, iWatchdogActivationLimit );
       
   369     if( err )
       
   370         {
       
   371         iWatchdogActivationLimit = KGSDefaultWatchdogActivationLimit;
       
   372         }
       
   373 
       
   374     err = iStore->Get( KWatchdogMaxPluginBlackListedRuns, iMaxPluginBlackListedRuns);
       
   375     if( err )
       
   376         {
       
   377         iMaxPluginBlackListedRuns = KGSDefaultMaxPluginBlackListedRuns;
       
   378         }
       
   379 
       
   380     StoreStateL();
       
   381     }
       
   382 
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 // CGSWatchDog::ReadQuarantineL
       
   386 //
       
   387 //
       
   388 // ---------------------------------------------------------------------------
       
   389 void CGSWatchDog::ReadQuarantineL()
       
   390     {
       
   391     HBufC8* buf = HBufC8::NewLC( KMaxBinaryLength );
       
   392     TPtr8 serializedArr = buf->Des();
       
   393     iStore->Get( KWatchDogQuarantine, serializedArr );
       
   394     RDesReadStream stream;
       
   395     stream.Open( serializedArr );
       
   396     CleanupClosePushL( stream );
       
   397 
       
   398     // In case CenRep value is uninitialized (less than 16 bits), don't try
       
   399     //reading it
       
   400     TInt count = 0;
       
   401     if( buf->Size() > 0 )
       
   402         {
       
   403         count = stream.ReadUint16L();
       
   404         }
       
   405     for( TInt i = 0; i < count; i++  )
       
   406         {
       
   407         TUid uid;
       
   408         uid.iUid = stream.ReadInt32L();
       
   409         iQuarantine.AppendL( uid );
       
   410         }
       
   411     //stream.Close();
       
   412     CleanupStack::PopAndDestroy( &stream );
       
   413     CleanupStack::PopAndDestroy( buf );
       
   414     }
       
   415 
       
   416 
       
   417 // ---------------------------------------------------------------------------
       
   418 // CGSWatchDog::StoreQuarantineL
       
   419 //
       
   420 //
       
   421 // ---------------------------------------------------------------------------
       
   422 void CGSWatchDog::StoreQuarantineL()
       
   423     {
       
   424     // Hmmm. KMaxBinaryLength = 1024*2 unicode characters (16bit)
       
   425     // = 1024*2*16 bits = 32768.
       
   426     // 32768 - 16(count) bits reserved for 32 bit TUids = 1023.5 TUids
       
   427     // -> We can store 1023 UIds in quarantine. Should be enought as we have
       
   428     // about ~50 plugins at the moment and each plugin ought to be listed in
       
   429     // quarantine only once at a specific point of time.
       
   430     HBufC8* buf = HBufC8::NewLC( KMaxBinaryLength );
       
   431     TPtr8 serializedArr = buf->Des();
       
   432     RDesWriteStream stream;
       
   433     stream.Open( serializedArr );
       
   434     CleanupClosePushL( stream );
       
   435 
       
   436     stream.WriteUint16L( iQuarantine.Count() );
       
   437 
       
   438     for( TInt i = 0; i < iQuarantine.Count(); i++ )
       
   439         {
       
   440         stream.WriteInt32L( iQuarantine[i].iUid );
       
   441         }
       
   442     // This also flushes the stream:
       
   443     CleanupStack::PopAndDestroy( &stream );
       
   444 
       
   445     iStore->Set( KWatchDogQuarantine, serializedArr );
       
   446 
       
   447     CleanupStack::PopAndDestroy( buf );
       
   448     }
       
   449 
       
   450 
       
   451 // ---------------------------------------------------------------------------
       
   452 // CGSWatchDog::ReadBlackListL
       
   453 //
       
   454 //
       
   455 // ---------------------------------------------------------------------------
       
   456 void CGSWatchDog::ReadBlackListL()
       
   457     {
       
   458     HBufC8* buf = HBufC8::NewLC( KMaxBinaryLength );
       
   459     TPtr8 serializedArr = buf->Des();
       
   460     iStore->Get( KWatchDogBlackList, serializedArr );
       
   461     RDesReadStream stream;
       
   462     stream.Open( serializedArr );
       
   463     CleanupClosePushL( stream );
       
   464 
       
   465     // In case CenRep value is uninitialized (less than 16 bits), don't try
       
   466     //reading it
       
   467     TInt count = 0;
       
   468     if( buf->Size() > 0 )
       
   469         {
       
   470         count = stream.ReadUint16L();
       
   471         }
       
   472     for( TInt i = 0; i < count; i++  )
       
   473         {
       
   474         TGSPluginQuarantine plugin;
       
   475         plugin.InternalizeL( stream );
       
   476         iBlackList.AppendL( plugin );
       
   477         }
       
   478 
       
   479     //stream.Close();
       
   480     CleanupStack::PopAndDestroy( &stream );
       
   481     CleanupStack::PopAndDestroy( buf );
       
   482     }
       
   483 
       
   484 
       
   485 // ---------------------------------------------------------------------------
       
   486 // CGSWatchDog::StoreBlackListL
       
   487 //
       
   488 //
       
   489 // ---------------------------------------------------------------------------
       
   490 void CGSWatchDog::StoreBlackListL()
       
   491     {
       
   492     HBufC8* buf = HBufC8::NewLC( KMaxBinaryLength );
       
   493     TPtr8 serializedArr = buf->Des();
       
   494     RDesWriteStream stream;
       
   495     stream.Open( serializedArr );
       
   496     CleanupClosePushL( stream );
       
   497 
       
   498     stream.WriteUint16L( iBlackList.Count() );
       
   499 
       
   500     for( TInt i = 0; i < iBlackList.Count(); i++ )
       
   501         {
       
   502         iBlackList[i].ExternalizeL( stream );
       
   503 
       
   504 #ifdef _GS_WATCHDOG_VERBOSE_TRACES
       
   505     __GSLOGSTRING1( "[CGSWatchDog] Written to blacklist 0x%X",
       
   506                     iBlackList[i].iUid.iUid );
       
   507 #endif //_GS_WATCHDOG_VERBOSE_TRACES
       
   508 
       
   509         }
       
   510     // This also flushes the stream:
       
   511     CleanupStack::PopAndDestroy( &stream );
       
   512 
       
   513     iStore->Set( KWatchDogBlackList, serializedArr );
       
   514 
       
   515     CleanupStack::PopAndDestroy( buf );
       
   516     }
       
   517 
       
   518 
       
   519 // ---------------------------------------------------------------------------
       
   520 // CGSWatchDog::UpdateBlackListedPluginRunCounters
       
   521 //
       
   522 //
       
   523 // ---------------------------------------------------------------------------
       
   524 void CGSWatchDog::UpdateBlackListedPluginRunCounters()
       
   525     {
       
   526     TInt count = iBlackList.Count();
       
   527     for( TInt i = 0; i < count; i++ )
       
   528         {
       
   529         iBlackList[i].iRunsAfterCrash++;
       
   530         if( iBlackList[i].iRunsAfterCrash > iMaxPluginBlackListedRuns )
       
   531             {
       
   532 //__GSLOGSTRING2( "[CGSWatchDog] 0x%X removed from blacklist (%d runs)", iBlackList[i].iUid.iUid, iBlackList[i].iRunsAfterCrash );
       
   533             iBlackList.Remove( i );
       
   534             i--;    // Item in index i has been removed
       
   535             count--;// One item has been removed from the array
       
   536             }
       
   537         }
       
   538     }
       
   539 
       
   540 
       
   541 // ---------------------------------------------------------------------------
       
   542 // TGSPluginQuarantine::InternalizeL
       
   543 //
       
   544 //
       
   545 // ---------------------------------------------------------------------------
       
   546 void TGSPluginQuarantine::InternalizeL( RReadStream& aStream )
       
   547     {
       
   548     iUid.iUid = aStream.ReadInt32L();
       
   549     iRunsAfterCrash = aStream.ReadInt16L();
       
   550     }
       
   551 
       
   552 
       
   553 // ---------------------------------------------------------------------------
       
   554 // TGSPluginQuarantine::ExternalizeL
       
   555 //
       
   556 //
       
   557 // ---------------------------------------------------------------------------
       
   558 void TGSPluginQuarantine::ExternalizeL( RWriteStream& aStream ) const
       
   559     {
       
   560     aStream.WriteInt32L( iUid.iUid );
       
   561     aStream.WriteInt16L( iRunsAfterCrash );
       
   562     }
       
   563 
       
   564 
       
   565 //End of File