controlpanel/src/cpframework/src/cpwatchdog.cpp
branchRCL_3
changeset 24 8ee96d21d9bf
equal deleted inserted replaced
23:8bda91a87a00 24:8ee96d21d9bf
       
     1 /*
       
     2 * Copyright (c) 2009 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 #include "cpwatchdog.h"
       
    18 #include <QCoreApplication>
       
    19 #include <QSettings>
       
    20 #include <QDebug>
       
    21 #include "cplogger.h"
       
    22 
       
    23 //const value definition
       
    24 const int DefaultMaxPluginBlackListedRuns = 5;
       
    25 const int DefaultWatchdogActivationLimit  = 1;
       
    26 const int WatchdogActivationDisabled      = -1;
       
    27 
       
    28 //Key definition for QSettings
       
    29 const QString KeyWatchDogStatus                   = "WatchDog";
       
    30 const QString KeyWatchDogCpRunning                = "cprunning";
       
    31 const QString KeyWatchDogCrashCounter             = "crashcounter";
       
    32 const QString KeyWatchDogMaxPluginBlackListedRuns = "maxpluginblacklistedruns";
       
    33 const QString KeyWatchDogActivationLimit          = "activationlimit";
       
    34 const QString KeyWatchDogQuarantine               = "Quarantine";
       
    35 const QString KeyWatchDogQuarantineUid            = "uid";
       
    36 const QString KeyWatchDogBlackList                = "BlackList";
       
    37 const QString KeyWatchDogBlackListUid             = "uid";
       
    38 const QString KeyWatchDogBlackListRunsAfterCrash  = "runsaftercrash";
       
    39 
       
    40 CpWatchDog *CpWatchDog::self = 0;
       
    41 
       
    42 CpWatchDog::PluginQuarantine::PluginQuarantine()
       
    43 : mUid(0), mRunsAfterCrash(0)
       
    44 {
       
    45 }
       
    46 
       
    47 void CpWatchDog::PluginQuarantine::read(QSettings &settings)
       
    48 {
       
    49     mUid = settings.value(KeyWatchDogBlackListUid,0).toInt();
       
    50     mRunsAfterCrash = settings.value(KeyWatchDogBlackListRunsAfterCrash,0).toInt();
       
    51 }
       
    52 
       
    53 void CpWatchDog::PluginQuarantine::store(QSettings &settings)
       
    54 {
       
    55     settings.setValue(KeyWatchDogBlackListUid,mUid);
       
    56     settings.setValue(KeyWatchDogBlackListRunsAfterCrash,mRunsAfterCrash);
       
    57 }
       
    58 
       
    59 CpWatchDog *CpWatchDog::instance()
       
    60 {
       
    61     if (!self) {
       
    62         self = new CpWatchDog;
       
    63     }
       
    64     return self;
       
    65 }
       
    66 
       
    67 CpWatchDog::CpWatchDog()
       
    68     : mActive(true),
       
    69       mCrashCounter(0),
       
    70       mAppRunning(true),
       
    71       mMaxPluginBlackListedRuns(DefaultMaxPluginBlackListedRuns),
       
    72       mWatchdogActivationLimit(DefaultWatchdogActivationLimit)
       
    73 {
       
    74     //delete watch dog when application is about to quit.
       
    75     connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(destroy()));
       
    76     init();
       
    77 }
       
    78 
       
    79 CpWatchDog::~CpWatchDog()
       
    80 {
       
    81     reportCleanExit();
       
    82     updateBlackListedPluginRunCounters();
       
    83     storeState();
       
    84 }
       
    85 
       
    86 void CpWatchDog::destroy()
       
    87 {
       
    88     delete this;
       
    89     self = 0;
       
    90 }
       
    91 
       
    92 void CpWatchDog::quarantine(int uid)
       
    93 {
       
    94     if (isActive()) {
       
    95         mQuarantine.append(uid);
       
    96         storeQuarantine();
       
    97     }
       
    98 }
       
    99 void CpWatchDog::removeFromQuarantine(int uid)
       
   100 {
       
   101     if (isActive()) {
       
   102         int index = mQuarantine.indexOf(uid);
       
   103         if (index >= 0) {
       
   104             mQuarantine.remove(index);
       
   105             storeQuarantine();
       
   106         }
       
   107     }
       
   108 }
       
   109 
       
   110 bool CpWatchDog::isActive() const
       
   111 {
       
   112     return mActive;
       
   113 }
       
   114 
       
   115 bool CpWatchDog::wasCleanExit() const
       
   116 {
       
   117     return !mAppRunning;
       
   118 }
       
   119 
       
   120 void CpWatchDog::reportCleanExit()
       
   121 {
       
   122     mAppRunning = false;
       
   123     
       
   124     QSettings settings;
       
   125     settings.beginGroup(KeyWatchDogStatus);
       
   126     settings.setValue(KeyWatchDogCpRunning,mAppRunning);
       
   127     settings.endGroup();
       
   128 }
       
   129 
       
   130 bool CpWatchDog::isInBlackList(int uid)
       
   131 {
       
   132     bool found = false;
       
   133     if (isActive()) {
       
   134         foreach(const PluginQuarantine &quarantine,mBlackList) {
       
   135             if (quarantine.mUid == uid) {
       
   136                 found = true;
       
   137                 break;
       
   138             }
       
   139         }
       
   140     }
       
   141     
       
   142     if (found) {
       
   143         CPFW_LOG( QLatin1String("Plugin ") + QString("0x%1").arg(uid,0,16) + QLatin1String(" is in black list."));
       
   144     }
       
   145     
       
   146     return found;
       
   147 }
       
   148 
       
   149 void CpWatchDog::init()
       
   150 {
       
   151     readState();
       
   152     
       
   153     if (!wasCleanExit() 
       
   154         && mWatchdogActivationLimit != WatchdogActivationDisabled) {
       
   155         mCrashCounter++;
       
   156         mActive = true;
       
   157         
       
   158         for (int i(0); i < mQuarantine.size(); i++) {
       
   159             if (!isInBlackList(mQuarantine[i])) {
       
   160                 PluginQuarantine quarantine;
       
   161                 quarantine.mUid = mQuarantine[i];
       
   162                 quarantine.mRunsAfterCrash = 0;
       
   163                 mBlackList.append(quarantine);
       
   164                 mQuarantine.remove(i);
       
   165                 i--;
       
   166             }
       
   167         }
       
   168     }
       
   169     else {
       
   170         mActive = false;
       
   171         mCrashCounter = 0;
       
   172         mQuarantine.clear();
       
   173     }
       
   174     
       
   175     mAppRunning = true;
       
   176     storeState();
       
   177 }
       
   178 
       
   179 void CpWatchDog::readState()
       
   180 {
       
   181     QSettings settings;
       
   182     settings.beginGroup(KeyWatchDogStatus);
       
   183     int appRunning = settings.value(KeyWatchDogCpRunning,0).toInt();
       
   184     mAppRunning = (appRunning != 0);
       
   185     mCrashCounter = settings.value(KeyWatchDogCrashCounter,0).toInt();
       
   186     mMaxPluginBlackListedRuns = settings.value(
       
   187             KeyWatchDogMaxPluginBlackListedRuns,DefaultMaxPluginBlackListedRuns).toInt();
       
   188     mWatchdogActivationLimit = settings.value(
       
   189             KeyWatchDogActivationLimit,DefaultWatchdogActivationLimit).toInt();
       
   190     settings.endGroup();
       
   191     
       
   192     readQuarantine();
       
   193     readBlackList();
       
   194 }
       
   195 
       
   196 void CpWatchDog::storeState()
       
   197 {
       
   198     {
       
   199         QSettings settings;
       
   200         settings.beginGroup(KeyWatchDogStatus);
       
   201         settings.setValue(KeyWatchDogCpRunning, mAppRunning ? 1 : 0);  
       
   202         settings.setValue(KeyWatchDogCrashCounter,mCrashCounter);   
       
   203         settings.setValue(KeyWatchDogMaxPluginBlackListedRuns,mMaxPluginBlackListedRuns);
       
   204         settings.setValue(KeyWatchDogActivationLimit,mWatchdogActivationLimit);
       
   205         settings.endGroup();
       
   206     } //Destructor of QSettings: writes any unsaved changes to permanent storage
       
   207     
       
   208     storeQuarantine();
       
   209     storeBlackList();
       
   210 }
       
   211 
       
   212 void CpWatchDog::readQuarantine()
       
   213 {
       
   214     QSettings settings;
       
   215     int size = settings.beginReadArray(KeyWatchDogQuarantine);
       
   216     for (int i(0); i < size; i++) {
       
   217         settings.setArrayIndex(i);
       
   218         int uid = settings.value(KeyWatchDogQuarantineUid,0).toInt();
       
   219         if (uid != 0) {
       
   220             mQuarantine.append(uid);
       
   221         }
       
   222     }
       
   223     settings.endArray();
       
   224 }
       
   225 
       
   226 void CpWatchDog::storeQuarantine()
       
   227 {
       
   228     QSettings settings;
       
   229     
       
   230     //remove old array data before updating
       
   231     settings.beginGroup(KeyWatchDogQuarantine);
       
   232     settings.remove(QString());
       
   233     settings.endGroup();
       
   234     
       
   235     settings.beginWriteArray(KeyWatchDogQuarantine);
       
   236     int size = mQuarantine.size();
       
   237     for (int i(0); i < size; i++) {
       
   238         settings.setArrayIndex(i);
       
   239         settings.setValue(KeyWatchDogQuarantineUid,mQuarantine[i]);
       
   240     }
       
   241     settings.endArray();
       
   242 }
       
   243 
       
   244 void CpWatchDog::readBlackList()
       
   245 {
       
   246     QSettings settings;
       
   247     int size = settings.beginReadArray(KeyWatchDogBlackList);
       
   248     for (int i(0); i < size; i++) {
       
   249         settings.setArrayIndex(i);
       
   250         PluginQuarantine quarantine;
       
   251         quarantine.read(settings);
       
   252         if (quarantine.mUid != 0) {
       
   253             mBlackList.append(quarantine);
       
   254         }
       
   255     }
       
   256     settings.endArray();
       
   257 }
       
   258 
       
   259 void CpWatchDog::storeBlackList()
       
   260 {
       
   261     QSettings settings;
       
   262 
       
   263     //remove old array data before updating
       
   264     settings.beginGroup(KeyWatchDogBlackList);
       
   265     settings.remove(QString());
       
   266     settings.endGroup();
       
   267     
       
   268     settings.beginWriteArray(KeyWatchDogBlackList);    
       
   269     int size = mBlackList.size();
       
   270     for (int i(0); i < size; i++) {
       
   271         settings.setArrayIndex(i);
       
   272         mBlackList[i].store(settings);
       
   273     }
       
   274     settings.endArray();
       
   275 }
       
   276 
       
   277 void CpWatchDog::updateBlackListedPluginRunCounters()
       
   278 {
       
   279     for (int i(0); i < mBlackList.size(); i++) {
       
   280         mBlackList[i].mRunsAfterCrash++;
       
   281         if (mBlackList[i].mRunsAfterCrash > mMaxPluginBlackListedRuns) {
       
   282             mBlackList.remove(i);
       
   283             i--;
       
   284         }
       
   285     }
       
   286 }