diff -r 2e3d3ce01487 -r 0fdb7f6b0309 sysresmonitoring/oommonitor/src/oomconfigparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysresmonitoring/oommonitor/src/oomconfigparser.cpp Fri Feb 19 22:58:54 2010 +0200 @@ -0,0 +1,1077 @@ +/* +* Copyright (c) 2006 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: The parser for the OOM configuration file. +* +*/ +#include +#include + +#include "oomconfigparser.h" +#include "oompanic.h" +#include "oomtraces.h" +#include "oomidletimerule.h" +#include "oomforegroundrule.h" +#include "oomconstants.hrh" +#include "oomapplicationconfig.h" +#include "oomcloseappconfig.h" +#include "oomconfig.h" +#include "oomrunpluginconfig.h" + +enum TOomConfigParserPanic +{ +KOomErrMoreThanOneOomConfig = 0, +KOomErrGlobalSettingsMustComeAfterRoot, +KOomErrAppSettingsMustComeAfterGlobalSettings, +KOomErrCloseAppSettingsMustComeAfterAppSettings, +KOomErrAppIdleSettingsMustComeAfterAppCloseSettings, +KOomErrLowRamErrorInGlobalSettings, +KOomErrGoodRamErrorInGlobalSettings, +KOomErrMaxCloseErrorInGlobalSettings, +KOomErrDefaultPriorityErrorInGlobalSettings, +KOomErrMissingUidFromAppCloseConfig, +KOomErrMissingPriorityFromAppCloseConfig, +KOomErrMissingSyncModeFromAppCloseConfig, +KOomErrMissingEstimateFromAppCloseConfig, +KOomErrInvalidSyncMode, +KOomErrMissingSyncModeInAppCloseConfig, +KOomErrBadOrMissingPriorityInAppIdleRule, +KOomErrBadOrMissingIdleTimeInAppIdleRule, +KOomErrBadOrMissingUidInAppIdleRule, +KOomErrBadNeverCloseValue, +KOomErrBadOrMissingUidInAppConfig, +KOomErrBadOrMissingPriorityInAppCloseConfig, +KOomErrBadLowThresholdValueForAppConfig, +KOomErrBadGoodThresholdValueForAppConfig, +KOomErrSystemPluginSettingsMustComeAfterAppCloseSettings, +KOomErrAppPluginSettingsMustComeAfterSystemPluginSettings, +KOomErrAppPluginIdleTimeRulesMustComeAfterAppPluginSettings, +KOomErrBadOrMissingUidInAppCloseConfig, +KOomErrBadOrMissingUidInSystemPluginConfig, +KOomErrBadOrMissingPriorityInSystemPluginConfig, +KOomErrBadOrMissingTargetAppIdInAppPluginConfig, +KOomErrBadOrMissingUidInAppPluginConfig, +KOomErrBadOrMissingPriorityInAppPluginConfig, +KOomErrBadOrMissingPriorityInPluginIdleRule, +KOomErrBadOrMissingIdleTimeInPluginIdleRule, +KOomErrBadOrMissingUidInPluginIdleRule, +KOomErrBadOrMissingUidInForegroundAppRule, +KOomErrBadOrMissingPriorityInForegroundAppRule, +KOomErrBadOrMissingTargetAppIdInForegroundAppRule, +KOomErrDefaultWaitAfterPluginInGlobalSettings, +KOomErrBadOrMissingPriorityInForceCheck, +KOomErrOomRulesMustComeLast, +KOomErrBadPluginWaitTime, +KOomErrBadXml, +KOomErrAppCloseIdleRuleOutsideAppCloseElement, +KOomErrForegroundAppRuleOutsideAppCloseElement, +KOomErrPluginIdleRuleOutsideAppPluginElement, +KOomErrPluginForegroundRuleOutsidePluginElement, +KOomErrBadCallIfTargetAppNotRunning +}; + +const TInt KOomXmlFileBufferSize = 1024; +const TInt KOomMaxAppExitTime = 2000; +const TInt KBytesInMegabyte = 1024; +#ifdef __WINS__ +const TInt KEmulatorTickDivisor = 5; // The tick is 5 times slower on the emulator than on the phone +#endif +using namespace Xml; + +// Mime type of the parsed document +_LIT8(KXmlMimeType, "text/xml"); + +_LIT(KOomConfigFilePath, ":\\private\\10207218\\oomconfig.xml"); +_LIT(KRomDrive, "z"); + +// Element strings +// Root +_LIT8(KOomConfigOomConfig, "oom_config"); + +// Global settings +_LIT8(KOomConfigGlobalSettings, "global_settings"); +_LIT8(KOomConfigForceCheckAtPriority, "force_check"); + +// App settings +_LIT8(KOomConfigAppSettings, "app_specific_thresholds"); +_LIT8(KOomConfigApp, "app"); + +// App close settings +_LIT8(KOomConfigAppCloseSettings, "app_close_settings"); +_LIT8(KOomConfigCloseApp, "close_app"); + +// App close idle time +_LIT8(KOomConfigAppCloseIdlePriority, "app_close_idle_priority"); + +_LIT8(KOomConfigForegroundAppPriority, "foreground_app_priority"); + +// Global settings attribute names +_LIT8(KOomAttributeLowRamThreshold, "low_ram_threshold"); +_LIT8(KOomAttributeGoodRamThreshold, "good_ram_threshold"); +_LIT8(KOomAttributeMaxAppCloseBatch, "max_app_close_batch"); +_LIT8(KOomAttributeDefaultWaitAfterPlugin, "default_wait_after_plugin"); +_LIT8(KOomAttributeMaxAppExitTime , "max_app_exit_time"); + +// System plugins + +_LIT8(KOomAttributeSystemPluginSettings, "system_plugin_settings"); +_LIT8(KOomAttributeSystemPlugin, "system_plugin"); + +// Application plugins + +_LIT8(KOomAttributeAppPluginSettings, "app_plugin_settings"); +_LIT8(KOomAttributeAppPlugin, "app_plugin"); + +// Plugin idle time rules + +_LIT8(KOomAttributePluginIdlePriority, "plugin_idle_priority"); + +// Plugin foreground app rules +_LIT8(KOomAttributePluginForegroundAppPriority, "plugin_foreground_app_priority"); + +// Atribute names +_LIT8(KOomAttibuteUid, "uid"); +_LIT8(KOomAttibuteSyncMode, "sync_mode"); +_LIT8(KOomAttibutePriority, "priority"); +_LIT8(KOomAttibuteRamEstimate, "ram_estimate"); + +_LIT8(KOomConfigSyncModeContinue, "continue"); +_LIT8(KOomConfigSyncModeCheck, "check"); +_LIT8(KOomConfigSyncModeEstimate, "estimate"); + +_LIT8(KOomAttibuteIdleTime, "idle_time"); +_LIT8(KOomAttibuteIdlePriority, "priority"); + +_LIT8(KOomAttibuteNeverClose, "NEVER_CLOSE"); + +_LIT8(KOomAttributeTargetAppId, "target_app_id"); + +_LIT8(KOomAttributeWait, "wait"); + +_LIT8(KOomAttributeIfForegroundAppId, "if_foreground_app_id"); + +_LIT8(KOomAttributeCallIfTargetAppNotRunning, "call_if_target_app_not_running"); +_LIT8(KOomAttributeTrue, "true"); +_LIT8(KOomAttributeFalse, "false"); +_LIT8(KOomAttribute0, "0"); +_LIT8(KOomAttribute1, "1"); + + +_LIT8(KOomConfigDefaultAppUid, "DEFAULT_APP"); +_LIT8(KOomConfigDefaultPluginUid, "DEFAULT_PLUGIN"); +_LIT8(KOomConfigTargetAppValue, "TARGET_APP"); + +_LIT8(KOomConfigBusyAppUid, "BUSY_APP"); +_LIT8(KOomConfigHighPriorityAppUid, "HIGH_PRIORITY_APP"); + +COomConfigParser::COomConfigParser(COomConfig& aConfig, RFs& aFs) : iConfig(aConfig), iFs(aFs), iState(EOomParsingStateNone) + { + } + +void COomConfigParser::ParseL() + { + FUNC_LOG; + + TRACES("COomConfigParser::ParseL: Parsing Config File"); + + CParser* parser = CParser::NewLC(KXmlMimeType, *this); + + RFile configFile; + TFileName configFileName; + TChar driveChar = iFs.GetSystemDriveChar(); + configFileName.Append(driveChar); + configFileName.Append(KOomConfigFilePath); + if (configFile.Open(iFs, configFileName, EFileShareExclusive) != KErrNone) + { + configFileName.Replace(0,1,KRomDrive); //replace 'c' with 'z' + User::LeaveIfError(configFile.Open(iFs, configFileName, EFileShareExclusive)); + } + CleanupClosePushL(configFile); + + TBuf8 fileBuffer; + TInt bytesRead; + do + { + User::LeaveIfError(configFile.Read(fileBuffer)); + bytesRead = fileBuffer.Size(); + + parser->ParseL(fileBuffer); + + } while (bytesRead != 0); + + CleanupStack::PopAndDestroy(2, parser); // config file - automatically closes it + // parser + + TRACES("COomConfigParser::ParseL: Finished Parsing Config File"); + } + +void COomConfigParser::OnStartDocumentL(const RDocumentParameters&, TInt) + { + FUNC_LOG; + } + +void COomConfigParser::OnEndDocumentL(TInt) + { + FUNC_LOG; + } + + +void COomConfigParser::OnEndElementL(const RTagInfo&, TInt) + { + } + +void COomConfigParser::OnContentL(const TDesC8&, TInt) + { + } + +void COomConfigParser::OnStartPrefixMappingL(const RString&, const RString&, + TInt) + { + } + +void COomConfigParser::OnEndPrefixMappingL(const RString&, TInt) + { + } + +void COomConfigParser::OnIgnorableWhiteSpaceL(const TDesC8&, TInt) + { + } + +void COomConfigParser::OnSkippedEntityL(const RString&, TInt) + { + } + +void COomConfigParser::OnProcessingInstructionL(const TDesC8&, const TDesC8&, + TInt) + { + } + +void COomConfigParser::OnError(TInt) + { + } + +TAny* COomConfigParser::GetExtendedInterface(const TInt32) + { + return 0; + } + +void COomConfigParser::OnStartElementL(const RTagInfo& aElement, const RAttributeArray& aAttributes, + TInt aErrorCode) + { + if (aErrorCode != KErrNone) + ConfigError(KOomErrBadXml); + + StartElementL(aElement.LocalName().DesC(), aAttributes); + } + +void COomConfigParser::StartElementL(const TDesC8& aLocalName, + const RAttributeArray& aAttributes) + { + // Root + if (aLocalName == KOomConfigOomConfig) + { + if (iState != EOomParsingStateNone) + ConfigError(KOomErrMoreThanOneOomConfig); + + ChangeState(EOomParsingStateRoot); + } + // Parse main elements + else if (aLocalName == KOomConfigGlobalSettings) + { + if (iState != EOomParsingStateRoot) + ConfigError(KOomErrGlobalSettingsMustComeAfterRoot); + + SetGlobalSettings(aAttributes); + + ChangeState(EOomParsingStateGlobalSettings); + } + else if (aLocalName == KOomConfigAppSettings) + { + ChangeState(EOomParsingStateAppSettings); + } + else if (aLocalName == KOomConfigAppCloseSettings) + { + ChangeState(EOomParsingStateAppCloseSettings); + } + else if (aLocalName == KOomAttributeSystemPluginSettings) + { + ChangeState(EOomParsingStateSystemPluginSettings); + } + else if (aLocalName == KOomAttributeAppPluginSettings) + { + ChangeState(EOomParsingStateAppPluginSettings); + } + // Parse actual configuration elements + else if (aLocalName == KOomConfigForceCheckAtPriority) + { + SetForceCheckConfigL(aAttributes); + } + else if (aLocalName == KOomConfigApp) + { + SetAppConfigL(aAttributes); + } + else if (aLocalName == KOomConfigCloseApp) + { + SetCloseAppConfigL(aAttributes); + } + else if (aLocalName == KOomConfigAppCloseIdlePriority) + { + CheckState(EOomParsingStateAppCloseSettings, KOomErrAppCloseIdleRuleOutsideAppCloseElement); + SetAppCloseIdlePriorityConfigL(aAttributes); + } + else if (aLocalName == KOomConfigForegroundAppPriority) + { + CheckState(EOomParsingStateAppCloseSettings, KOomErrForegroundAppRuleOutsideAppCloseElement); + SetForegroundAppPriorityL(aAttributes); + } + else if (aLocalName == KOomAttributeSystemPlugin) + { + SetSystemPluginConfigL(aAttributes); + } + else if (aLocalName == KOomAttributeAppPlugin) + { + SetAppPluginConfigL(aAttributes); + } + else if (aLocalName == KOomAttributePluginIdlePriority) + { + CheckState(EOomParsingStateAppPluginSettings, KOomErrPluginIdleRuleOutsideAppPluginElement); + SetPluginIdlePriorityL(aAttributes); + } + else if (aLocalName == KOomAttributePluginForegroundAppPriority) + { + CheckState(EOomParsingStateAppPluginSettings, EOomParsingStateSystemPluginSettings, KOomErrPluginForegroundRuleOutsidePluginElement); + SetPluginForegroundAppPriorityL(aAttributes); + } + + } + +void COomConfigParser::ConfigError(TInt aError) + { + OomConfigParserPanic(aError); + } + +void COomConfigParser::SetGlobalSettings(const RAttributeArray& aAttributes) + { + TInt defaultLowMemoryThreshold; + TInt err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeLowRamThreshold, defaultLowMemoryThreshold); + + if (err == KErrNone) + iConfig.SetDefaultLowRamThreshold(defaultLowMemoryThreshold * KBytesInMegabyte); + else + ConfigError(KOomErrLowRamErrorInGlobalSettings); + + if (err == KErrNone) + { + TInt defaultGoodMemoryThreshold; + TInt err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeGoodRamThreshold, defaultGoodMemoryThreshold); + + if (err == KErrNone) + iConfig.SetDefaultGoodRamThreshold(defaultGoodMemoryThreshold * KBytesInMegabyte); + else + ConfigError(KOomErrGoodRamErrorInGlobalSettings); + } + + if (err == KErrNone) + { + TInt defaultMaxCloseAppBatch; + TInt err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeMaxAppCloseBatch, defaultMaxCloseAppBatch); + + if (err == KErrNone) + iConfig.SetMaxCloseAppBatch(defaultMaxCloseAppBatch); + else + ConfigError(KOomErrMaxCloseErrorInGlobalSettings); + } + + if (err == KErrNone) + { + TInt defaultWaitAfterPlugin; + TInt err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeDefaultWaitAfterPlugin, defaultWaitAfterPlugin); + + if (err == KErrNone) + iConfig.SetDefaultWaitAfterPlugin(defaultWaitAfterPlugin); + else + ConfigError(KOomErrDefaultWaitAfterPluginInGlobalSettings); + } + + if (err == KErrNone) + { + TInt maxAppExitTime; + TInt err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeMaxAppExitTime, maxAppExitTime); + + if (err == KErrNone) + iConfig.SetMaxAppExitTime(maxAppExitTime); + else + iConfig.SetMaxAppExitTime(KOomMaxAppExitTime); + } + } + +void COomConfigParser::SetForceCheckConfigL(const RAttributeArray& aAttributes) + { + TUint priority; + TInt err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibutePriority, priority); + if (err == KErrNone) + { + iConfig.GlobalConfig().AddForceCheckPriorityL(priority); + } + else + { + ConfigError(KOomErrBadOrMissingPriorityInForceCheck); + } + } + +void COomConfigParser::SetAppConfigL(const RAttributeArray& aAttributes) + { + TUint uid; + COomApplicationConfig* appConfig = NULL; + + TInt err = GetValueFromHexAttributeList(aAttributes, KOomAttibuteUid, uid); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingUidInAppConfig); + } + else + iParentUid = uid; + + appConfig = COomApplicationConfig::NewL(uid); + CleanupStack::PushL(appConfig); + + // Set the app specific memory thresholds (if they exist) + // Get the app specific low threshold + if (err == KErrNone) + { + TUint lowThreshold; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeLowRamThreshold, lowThreshold); + if (err == KErrNone) + { + appConfig->iLowRamThreshold = lowThreshold * KBytesInMegabyte; + } + else if (err == KErrNotFound) + err = KErrNone; + + if (err != KErrNone) + ConfigError(KOomErrBadLowThresholdValueForAppConfig); + } + + // Get the app specific good threshold + if (err == KErrNone) + { + TUint goodThreshold; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeGoodRamThreshold, goodThreshold); + if (err == KErrNone) + { + appConfig->iGoodRamThreshold = goodThreshold * KBytesInMegabyte; + } + else if (err == KErrNotFound) + err = KErrNone; + + if (err != KErrNone) + ConfigError(KOomErrBadGoodThresholdValueForAppConfig); + } + + // Add the applciation config to the main config + if ((err == KErrNone) && (appConfig)) + { + iConfig.AddApplicationConfigL(appConfig); + } + + if (appConfig) + CleanupStack::Pop(appConfig); + } + +void COomConfigParser::SetCloseAppConfigL(const RAttributeArray& aAttributes) + { + // Get and convert uid attribute to TInt + TInt err = KErrNone; + + TUint uid; + err = GetValueFromHexAttributeList(aAttributes, KOomAttibuteUid, uid); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingUidInAppCloseConfig); + return; + } + else + iParentUid = uid; + + COomCloseAppConfig* closeAppConfig = COomCloseAppConfig::NewL(uid); // Radio UID + CleanupStack::PushL(closeAppConfig); + + if (err == KErrNone) + { + // Check that we have a priority for the added app_close event + // Specifying a priority is mandatory + TUint priority; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibutePriority, priority); + if (err == KErrNone) + { + closeAppConfig->SetDefaultPriority(priority); + } + else + { + ConfigError(KOomErrBadOrMissingPriorityInAppCloseConfig); + } + } + + if (err == KErrNone) + { + TPtrC8 syncModeString; + err = GetValueFromAttributeList(aAttributes, KOomAttibuteSyncMode, syncModeString); + + if (err == KErrNone) + { + TOomSyncMode syncMode = EContinue; + + if (syncModeString == KOomConfigSyncModeContinue) + syncMode = EContinue; + else if (syncModeString == KOomConfigSyncModeCheck) + syncMode = ECheckRam; + else if (syncModeString == KOomConfigSyncModeEstimate) + syncMode = EEstimate; + else + ConfigError(KOomErrInvalidSyncMode); + + if (err == KErrNone) + { + closeAppConfig->iSyncMode = syncMode; + } + } + else + { + ConfigError(KOomErrMissingSyncModeInAppCloseConfig); + } + } + + + if (err == KErrNone) + { + // If we have a default priority attribute then add it, otherwise use the global default priority + TInt ramEstimate; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteRamEstimate, ramEstimate); + if ((err == KErrNotFound) && (closeAppConfig->iSyncMode != EEstimate)) + { + err = KErrNone; + } + + if (err != KErrNone) + ConfigError(KOomErrMissingEstimateFromAppCloseConfig); + else + closeAppConfig->iRamEstimate = ramEstimate * KBytesInMegabyte; + } + + if (err == KErrNone) + iConfig.SetAppCloseConfigL(closeAppConfig); + + CleanupStack::Pop(closeAppConfig); + } + +void COomConfigParser::SetAppCloseIdlePriorityConfigL(const RAttributeArray& aAttributes) + { + TUint uid; + TInt idleTime; + TUint priority; + + // Use the UID from the parent scope + uid = iParentUid; + + TInt err = KErrNone; + + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteIdleTime, idleTime); + +#ifdef __WINS__ + // The tick is 5 times slower on the emulator than on the phone + idleTime = idleTime / KEmulatorTickDivisor; +#endif + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingIdleTimeInAppIdleRule); + } + + if (err == KErrNone) + { + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteIdlePriority, priority); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingPriorityInAppIdleRule); + } + } + + if (err == KErrNone) + { + COomIdleTimeRule* idleRule = COomIdleTimeRule::NewL(idleTime, priority); + CleanupStack::PushL(idleRule); + iConfig.AddApplicationRuleL(uid, idleRule); + CleanupStack::Pop(idleRule); + } + } + +void COomConfigParser::SetForegroundAppPriorityL(const RAttributeArray& aAttributes) + { + TUint appUid; + TUint targetAppId; + TUint priority; + + TInt err = KErrNone; + + // Use the UID from the parent scope + appUid = iParentUid; + + // Check that we have a priority for the added system plugin action + // Specifying a priority is mandatory + err = GetValueFromHexAttributeList(aAttributes, KOomAttributeIfForegroundAppId, targetAppId); + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingTargetAppIdInForegroundAppRule); + } + + if (err == KErrNone) + { + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteIdlePriority, priority); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingPriorityInForegroundAppRule); + } + } + + if (err == KErrNone) + { + COomForegroundRule* foregroundRule = new (ELeave) COomForegroundRule(targetAppId, priority); + CleanupStack::PushL(foregroundRule); + iConfig.AddApplicationRuleL(appUid, foregroundRule); + CleanupStack::Pop(foregroundRule); + } + + } + +void COomConfigParser::SetSystemPluginConfigL(const RAttributeArray& aAttributes) + { + // Get and convert uid attribute to TInt + TInt err = KErrNone; + + TUint uid; + err = GetValueFromHexAttributeList(aAttributes, KOomAttibuteUid, uid); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingUidInSystemPluginConfig); + return; + } + else + iParentUid = uid; + + COomRunPluginConfig* pluginConfig = COomRunPluginConfig::NewL(uid, EOomSystemPlugin); + CleanupStack::PushL(pluginConfig); + + if (err == KErrNone) + { + // Check that we have a priority for the added system plugin action + // Specifying a priority is mandatory + TUint priority; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibutePriority, priority); + if (err == KErrNone) + { + pluginConfig->SetDefaultPriority(priority); + } + else + { + ConfigError(KOomErrBadOrMissingPriorityInSystemPluginConfig); + } + } + + if (err == KErrNone) + { + TInt wait; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeWait, wait); + if (err == KErrNone) + { + pluginConfig->SetWaitAfterPlugin(wait); + } + else if (err == KErrNotFound) + { + // If this attribute isn't present then just don't set it, and clear the error + err = KErrNone; + } + else + ConfigError(KOomErrBadPluginWaitTime); + } + + if (err == KErrNone) + { + // Get the config for the sync mode for this plugin (if one is specified) and set it + SetPluginSyncMode(aAttributes, *pluginConfig); + } + + iConfig.AddPluginConfigL(pluginConfig); + + CleanupStack::Pop(pluginConfig); + } + +void COomConfigParser::SetAppPluginConfigL(const RAttributeArray& aAttributes) + { + // Get and convert uid attribute to TInt + TInt err = KErrNone; + + TUint uid; + err = GetValueFromHexAttributeList(aAttributes, KOomAttibuteUid, uid); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingUidInAppPluginConfig); + return; + } + else + iParentUid = uid; + + COomRunPluginConfig* pluginConfig = COomRunPluginConfig::NewL(uid, EOomAppPlugin); + CleanupStack::PushL(pluginConfig); + + if (err == KErrNone) + { + // Check that we have a priority for the added system plugin action + // Specifying a priority is mandatory + TUint priority; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibutePriority, priority); + if (err == KErrNone) + { + pluginConfig->SetDefaultPriority(priority); + } + else + { + ConfigError(KOomErrBadOrMissingPriorityInAppPluginConfig); + } + } + + if (err == KErrNone) + { + // Check that we have a priority for the added system plugin action + // Specifying a priority is mandatory + TUint targetAppId; + err = GetValueFromHexAttributeList(aAttributes, KOomAttributeTargetAppId, targetAppId); + if (err == KErrNone) + { + pluginConfig->SetTargetApp(targetAppId); + iParentTargetApp = targetAppId; + } + else + { + ConfigError(KOomErrBadOrMissingTargetAppIdInAppPluginConfig); + } + } + + if (err == KErrNone) + { + TInt wait; + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttributeWait, wait); + if (err == KErrNone) + { + pluginConfig->SetWaitAfterPlugin(wait); + } + else if (err == KErrNotFound) + { + // If this attribute isn't present then just don't set it, and clear the error + err = KErrNone; + } + else + ConfigError(KOomErrBadPluginWaitTime); + } + + if (err == KErrNone) + { + // Get the config for the sync mode for this plugin (if one is specified) and set it + SetPluginSyncMode(aAttributes, *pluginConfig); + + TBool targetAppNotRunning; + err = GetValueFromBooleanAttributeList(aAttributes, KOomAttributeCallIfTargetAppNotRunning, targetAppNotRunning); + if (err == KErrNone) + { + pluginConfig->SetCallIfTargetAppNotRunning(targetAppNotRunning); + } + else if (err == KErrNotFound) + { + // If this attribute isn't present then just don't set it, and clear the error + err = KErrNone; + } + else + { + ConfigError(KOomErrBadCallIfTargetAppNotRunning); + } + } + + iConfig.AddPluginConfigL(pluginConfig); + + CleanupStack::Pop(pluginConfig); + + } + +void COomConfigParser::SetPluginIdlePriorityL(const RAttributeArray& aAttributes) + { + TUint uid; + TInt idleTime; + TUint priority; + + TInt err = KErrNone; + + // Use the UID from the parent scope + uid = iParentUid; + + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteIdleTime, idleTime); + +#ifdef __WINS__ + // The tick is 5 times slower on the emulator than on the phone + idleTime = idleTime / KEmulatorTickDivisor; +#endif + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingIdleTimeInPluginIdleRule); + } + + if (err == KErrNone) + { + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteIdlePriority, priority); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingPriorityInPluginIdleRule); + } + } + + if (err == KErrNone) + { + COomIdleTimeRule* idleRule = COomIdleTimeRule::NewL(idleTime, priority); + CleanupStack::PushL(idleRule); + iConfig.AddPluginRuleL(uid, idleRule); + CleanupStack::Pop(idleRule); + } + } + +void COomConfigParser::SetPluginForegroundAppPriorityL(const RAttributeArray& aAttributes) + { + TUint uid; + TUint targetAppId; + TUint priority; + + TInt err = KErrNone; + + // Use the UID from the parent scope + uid = iParentUid; + + // Check that we have a priority for the added system plugin action + // Specifying a priority is mandatory + + TPtrC8 targetAppString; + err = GetValueFromAttributeList(aAttributes, KOomAttributeTargetAppId, targetAppString); + if ((err == KErrNone) + && (targetAppString == KOomConfigTargetAppValue) + && (iState == EOomParsingStateAppPluginSettings)) + // If the target app is specified as "TARGET_APP" then we use the target app from the parent entry + { + targetAppId = iParentTargetApp; + } + else + { + err = GetValueFromHexAttributeList(aAttributes, KOomAttributeTargetAppId, targetAppId); + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingTargetAppIdInForegroundAppRule); + } + } + + if (err == KErrNone) + { + err = GetValueFromDecimalAttributeList(aAttributes, KOomAttibuteIdlePriority, priority); + + if (err != KErrNone) + { + ConfigError(KOomErrBadOrMissingPriorityInForegroundAppRule); + } + } + + if (err == KErrNone) + { + COomForegroundRule* foregroundRule = new (ELeave) COomForegroundRule(targetAppId, priority); + CleanupStack::PushL(foregroundRule); + iConfig.AddPluginRuleL(uid, foregroundRule); + CleanupStack::Pop(foregroundRule); + } + } + +// Finds an attribute of the given name and gets its value +// A value is only valid as long as AAtrributes is valid (and unmodified) +// Returns KErrNone if the attribute is present in the list, KErrNotFound otherwise +TInt COomConfigParser::GetValueFromAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TPtrC8& aValue) + { + TInt index = aAttributes.Count(); + TBool attributeFound = EFalse; + while ((index--) && (!attributeFound)) + { + if (aAttributes[index].Attribute().LocalName().DesC() == aName) + { + attributeFound = ETrue; + aValue.Set(aAttributes[index].Value().DesC()); + } + } + + TInt err = KErrNone; + + if (!attributeFound) + err = KErrNotFound; + + return err; + } + +// Finds an attribute of the given name and gets its value (coverting the string hex value to a UInt) +// Returns KErrNone if the attribute is present in the list, KErrNotFound otherwise +// Returns KErrCorrupt if the string is not a valid hex number +TInt COomConfigParser::GetValueFromHexAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TUint& aValue) + { + TPtrC8 hexString; + TInt err = GetValueFromAttributeList(aAttributes, aName, hexString); + + if (hexString == KOomConfigDefaultAppUid) + { + // This is a special case + // When we hit this value in a hex field then we return the default app UID + aValue = KOomDefaultAppId; + } + else if (hexString == KOomConfigDefaultPluginUid) + { + // This is a special case + // When we hit this value in a hex field then we return the default app UID + aValue = KOomDefaultPluginId; + } + else if (hexString == KOomConfigBusyAppUid) + { + aValue = KOomBusyAppId; + } + else if (hexString == KOomConfigHighPriorityAppUid) + { + aValue = KOomHighPriorityAppId; + } + else if (err == KErrNone) + { + TLex8 hexLex(hexString); + err = hexLex.Val(aValue, EHex); + if (err != KErrNone) + err = KErrCorrupt; + } + + return err; + } + +// Finds an attribute of the given name and gets its value (coverting the string decimal value to a UInt) +// Returns KErrNone if the attribute is present in the list, KErrNotFound otherwise +// Returns KErrCorrupt if the string is not a valid decimal number +TInt COomConfigParser::GetValueFromDecimalAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TUint& aValue) + { + TPtrC8 decimalString; + TInt err = GetValueFromAttributeList(aAttributes, aName, decimalString); + + if (err == KErrNone) + { + if (decimalString == KOomAttibuteNeverClose) + aValue = KOomPriorityInfinate; + else + { + TLex8 decimalLex(decimalString); + err = decimalLex.Val(aValue, EDecimal); + if (err != KErrNone) + err = KErrCorrupt; + } + } + + return err; + } + +TInt COomConfigParser::GetValueFromDecimalAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TInt& aValue) + { + TUint uintValue; + TInt err = GetValueFromDecimalAttributeList(aAttributes, aName, uintValue); + aValue = uintValue; + return err; + } + +TInt COomConfigParser::GetValueFromBooleanAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TBool& aValue) + { + TPtrC8 ptrValue; + TInt err = GetValueFromAttributeList(aAttributes, aName, ptrValue); + if (err == KErrNone) + { + if (ptrValue == KOomAttributeTrue || ptrValue == KOomAttribute1) + { + aValue = ETrue; + } + else if (ptrValue == KOomAttributeFalse || ptrValue == KOomAttribute0) + { + aValue = EFalse; + } + else + { + err = KErrCorrupt; + } + } + return err; + } + +void COomConfigParser::SetPluginSyncMode(const RAttributeArray& aAttributes, COomRunPluginConfig& aRunPluginConfig) + { + TPtrC8 syncModeString; + TInt err = GetValueFromAttributeList(aAttributes, KOomAttibuteSyncMode, syncModeString); + + if (err == KErrNone) + // If there is no specified sync mode then leave it as the default + { + TOomSyncMode syncMode = EContinue; + + if (syncModeString == KOomConfigSyncModeContinue) + syncMode = EContinueIgnoreMaxBatchSize; + else if (syncModeString == KOomConfigSyncModeCheck) + syncMode = ECheckRam; + else if (syncModeString == KOomConfigSyncModeEstimate) + syncMode = EEstimate; + else + ConfigError(KOomErrInvalidSyncMode); + + if (err == KErrNone) + { + aRunPluginConfig.iSyncMode = syncMode; + } + } + } + +// Check that the current state is as expected +// If not then the specified config error is generated +void COomConfigParser::CheckState(TOomParsingState aExpectedState, TInt aError) + { + if (iState != aExpectedState) + ConfigError(aError); + } + +// Check that the current state is as expected +// If not then the specified config error is generated +// This version checks to ensure that the current state matches either of the passed in states +void COomConfigParser::CheckState(TOomParsingState aExpectedState1, TOomParsingState aExpectedState2, TInt aError) + { + if ((iState != aExpectedState1) + && (iState != aExpectedState2)) + ConfigError(aError); + } + +void COomConfigParser::ChangeState(TOomParsingState aState) + { + iState = aState; + }