--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/controlpanel/src/cpframework/src/cpwatchdog.cpp Thu Apr 01 03:17:51 2010 +0800
@@ -0,0 +1,286 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0""
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "CpWatchDog.h"
+#include <qcoreapplication>
+#include <qsettings>
+#include <qdebug>
+#include "cplogger.h"
+
+//const value definition
+const int DefaultMaxPluginBlackListedRuns = 5;
+const int DefaultWatchdogActivationLimit = 1;
+const int WatchdogActivationDisabled = -1;
+
+//Key definition for QSettings
+const QString KeyWatchDogStatus = "WatchDog";
+const QString KeyWatchDogCpRunning = "cprunning";
+const QString KeyWatchDogCrashCounter = "crashcounter";
+const QString KeyWatchDogMaxPluginBlackListedRuns = "maxpluginblacklistedruns";
+const QString KeyWatchDogActivationLimit = "activationlimit";
+const QString KeyWatchDogQuarantine = "Quarantine";
+const QString KeyWatchDogQuarantineUid = "uid";
+const QString KeyWatchDogBlackList = "BlackList";
+const QString KeyWatchDogBlackListUid = "uid";
+const QString KeyWatchDogBlackListRunsAfterCrash = "runsaftercrash";
+
+CpWatchDog *CpWatchDog::self = 0;
+
+CpWatchDog::PluginQuarantine::PluginQuarantine()
+: mUid(0), mRunsAfterCrash(0)
+{
+}
+
+void CpWatchDog::PluginQuarantine::read(QSettings &settings)
+{
+ mUid = settings.value(KeyWatchDogBlackListUid,0).toInt();
+ mRunsAfterCrash = settings.value(KeyWatchDogBlackListRunsAfterCrash,0).toInt();
+}
+
+void CpWatchDog::PluginQuarantine::store(QSettings &settings)
+{
+ settings.setValue(KeyWatchDogBlackListUid,mUid);
+ settings.setValue(KeyWatchDogBlackListRunsAfterCrash,mRunsAfterCrash);
+}
+
+CpWatchDog *CpWatchDog::instance()
+{
+ if (!self) {
+ self = new CpWatchDog;
+ }
+ return self;
+}
+
+CpWatchDog::CpWatchDog()
+ : mActive(true),
+ mCrashCounter(0),
+ mAppRunning(true),
+ mMaxPluginBlackListedRuns(DefaultMaxPluginBlackListedRuns),
+ mWatchdogActivationLimit(DefaultWatchdogActivationLimit)
+{
+ //delete watch dog when application is about to quit.
+ connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(destroy()));
+ init();
+}
+
+CpWatchDog::~CpWatchDog()
+{
+ reportCleanExit();
+ updateBlackListedPluginRunCounters();
+ storeState();
+}
+
+void CpWatchDog::destroy()
+{
+ delete this;
+ self = 0;
+}
+
+void CpWatchDog::quarantine(int uid)
+{
+ if (isActive()) {
+ mQuarantine.append(uid);
+ storeQuarantine();
+ }
+}
+void CpWatchDog::removeFromQuarantine(int uid)
+{
+ if (isActive()) {
+ int index = mQuarantine.indexOf(uid);
+ if (index >= 0) {
+ mQuarantine.remove(index);
+ storeQuarantine();
+ }
+ }
+}
+
+bool CpWatchDog::isActive() const
+{
+ return mActive;
+}
+
+bool CpWatchDog::wasCleanExit() const
+{
+ return !mAppRunning;
+}
+
+void CpWatchDog::reportCleanExit()
+{
+ mAppRunning = false;
+
+ QSettings settings;
+ settings.beginGroup(KeyWatchDogStatus);
+ settings.setValue(KeyWatchDogCpRunning,mAppRunning);
+ settings.endGroup();
+}
+
+bool CpWatchDog::isInBlackList(int uid)
+{
+ bool found = false;
+ if (isActive()) {
+ foreach(const PluginQuarantine &quarantine,mBlackList) {
+ if (quarantine.mUid == uid) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ CpLogger() << "Plugin " << QString("0x%1").arg(uid,0,16) << "is in black list." << "\r\n";
+ }
+
+ return found;
+}
+
+void CpWatchDog::init()
+{
+ readState();
+
+ if (!wasCleanExit()
+ && mWatchdogActivationLimit != WatchdogActivationDisabled) {
+ mCrashCounter++;
+ mActive = true;
+
+ for (int i(0); i < mQuarantine.size(); i++) {
+ if (!isInBlackList(mQuarantine[i])) {
+ PluginQuarantine quarantine;
+ quarantine.mUid = mQuarantine[i];
+ quarantine.mRunsAfterCrash = 0;
+ mBlackList.append(quarantine);
+ mQuarantine.remove(i);
+ i--;
+ }
+ }
+ }
+ else {
+ mActive = false;
+ mCrashCounter = 0;
+ mQuarantine.clear();
+ }
+
+ mAppRunning = true;
+ storeState();
+}
+
+void CpWatchDog::readState()
+{
+ QSettings settings;
+ settings.beginGroup(KeyWatchDogStatus);
+ int appRunning = settings.value(KeyWatchDogCpRunning,0).toInt();
+ mAppRunning = (appRunning != 0);
+ mCrashCounter = settings.value(KeyWatchDogCrashCounter,0).toInt();
+ mMaxPluginBlackListedRuns = settings.value(
+ KeyWatchDogMaxPluginBlackListedRuns,DefaultMaxPluginBlackListedRuns).toInt();
+ mWatchdogActivationLimit = settings.value(
+ KeyWatchDogActivationLimit,DefaultWatchdogActivationLimit).toInt();
+ settings.endGroup();
+
+ readQuarantine();
+ readBlackList();
+}
+
+void CpWatchDog::storeState()
+{
+ {
+ QSettings settings;
+ settings.beginGroup(KeyWatchDogStatus);
+ settings.setValue(KeyWatchDogCpRunning, mAppRunning ? 1 : 0);
+ settings.setValue(KeyWatchDogCrashCounter,mCrashCounter);
+ settings.setValue(KeyWatchDogMaxPluginBlackListedRuns,mMaxPluginBlackListedRuns);
+ settings.setValue(KeyWatchDogActivationLimit,mWatchdogActivationLimit);
+ settings.endGroup();
+ } //Destructor of QSettings: writes any unsaved changes to permanent storage
+
+ storeQuarantine();
+ storeBlackList();
+}
+
+void CpWatchDog::readQuarantine()
+{
+ QSettings settings;
+ int size = settings.beginReadArray(KeyWatchDogQuarantine);
+ for (int i(0); i < size; i++) {
+ settings.setArrayIndex(i);
+ int uid = settings.value(KeyWatchDogQuarantineUid,0).toInt();
+ if (uid != 0) {
+ mQuarantine.append(uid);
+ }
+ }
+ settings.endArray();
+}
+
+void CpWatchDog::storeQuarantine()
+{
+ QSettings settings;
+
+ //remove old array data before updating
+ settings.beginGroup(KeyWatchDogQuarantine);
+ settings.remove(QString());
+ settings.endGroup();
+
+ settings.beginWriteArray(KeyWatchDogQuarantine);
+ int size = mQuarantine.size();
+ for (int i(0); i < size; i++) {
+ settings.setArrayIndex(i);
+ settings.setValue(KeyWatchDogQuarantineUid,mQuarantine[i]);
+ }
+ settings.endArray();
+}
+
+void CpWatchDog::readBlackList()
+{
+ QSettings settings;
+ int size = settings.beginReadArray(KeyWatchDogBlackList);
+ for (int i(0); i < size; i++) {
+ settings.setArrayIndex(i);
+ PluginQuarantine quarantine;
+ quarantine.read(settings);
+ if (quarantine.mUid != 0) {
+ mBlackList.append(quarantine);
+ }
+ }
+ settings.endArray();
+}
+
+void CpWatchDog::storeBlackList()
+{
+ QSettings settings;
+
+ //remove old array data before updating
+ settings.beginGroup(KeyWatchDogBlackList);
+ settings.remove(QString());
+ settings.endGroup();
+
+ settings.beginWriteArray(KeyWatchDogBlackList);
+ int size = mBlackList.size();
+ for (int i(0); i < size; i++) {
+ settings.setArrayIndex(i);
+ mBlackList[i].store(settings);
+ }
+ settings.endArray();
+}
+
+void CpWatchDog::updateBlackListedPluginRunCounters()
+{
+ for (int i(0); i < mBlackList.size(); i++) {
+ mBlackList[i].mRunsAfterCrash++;
+ if (mBlackList[i].mRunsAfterCrash > mMaxPluginBlackListedRuns) {
+ mBlackList.remove(i);
+ i--;
+ }
+ }
+}