/*
* Copyright (c) 2008 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 Graphics OOM configuration file
*
*/
#include <e32base.h>
#include <xml/parser.h>
#include "goomconfigparser.h"
#include "goompanic.h"
#include "goomtraces.h"
#include "goomidletimerule.h"
#include "goomforegroundrule.h"
#include "goomconstants.hrh"
#include "goomapplicationconfig.h"
#include "goomcloseappconfig.h"
#include "goomconfig.h"
#include "goomrunpluginconfig.h"
enum
{
KGOomErrMoreThanOneGOomConfig = 0,
KGOomErrGlobalSettingsMustComeAfterRoot,
KGOomErrAppSettingsMustComeAfterGlobalSettings,
KGOomErrCloseAppSettingsMustComeAfterAppSettings,
KGOomErrAppIdleSettingsMustComeAfterAppCloseSettings,
KGOomErrLowRamErrorInGlobalSettings,
KGOomErrGoodRamErrorInGlobalSettings,
KGOomErrMaxCloseErrorInGlobalSettings,
KGOomErrDefaultPriorityErrorInGlobalSettings,
KGOomErrMissingUidFromAppCloseConfig,
KGOomErrMissingPriorityFromAppCloseConfig,
KGOomErrMissingSyncModeFromAppCloseConfig,
KGOomErrMissingEstimateFromAppCloseConfig,
KGOomErrInvalidSyncMode,
KGOomErrMissingSyncModeInAppCloseConfig,
KGOomErrBadOrMissingPriorityInAppIdleRule,
KGOomErrBadOrMissingIdleTimeInAppIdleRule,
KGOomErrBadOrMissingUidInAppIdleRule,
KGOomErrBadNeverCloseValue,
KGOomErrBadOrMissingUidInAppConfig,
KGOomErrBadOrMissingPriorityInAppCloseConfig,
KGOomErrBadLowThresholdValueForAppConfig,
KGOomErrBadGoodThresholdValueForAppConfig,
KGOomErrBadTargetFreeValueForAppConfig,
KGOomErrBadSkipPluginValueForAppConfig,
KGOomErrSystemPluginSettingsMustComeAfterAppCloseSettings,
KGOomErrAppPluginSettingsMustComeAfterSystemPluginSettings,
KGOomErrAppPluginIdleTimeRulesMustComeAfterAppPluginSettings,
KGOomErrBadOrMissingUidInAppCloseConfig,
KGOomErrBadOrMissingUidInSystemPluginConfig,
KGOomErrBadOrMissingPriorityInSystemPluginConfig,
KGOomErrBadOrMissingTargetAppIdInAppPluginConfig,
KGOomErrBadOrMissingUidInAppPluginConfig,
KGOomErrBadOrMissingPriorityInAppPluginConfig,
KGOomErrBadOrMissingPriorityInPluginIdleRule,
KGOomErrBadOrMissingIdleTimeInPluginIdleRule,
KGOomErrBadOrMissingUidInPluginIdleRule,
KGOomErrBadOrMissingUidInForegroundAppRule,
KGOomErrBadOrMissingPriorityInForegroundAppRule,
KGOomErrBadOrMissingTargetAppIdInForegroundAppRule,
KGOomErrDefaultWaitAfterPluginInGlobalSettings,
KGOomErrBadOrMissingPriorityInForceCheck,
KGOomErrGOomRulesMustComeLast,
KGOomErrBadPluginWaitTime,
KGOomErrBadXml,
KGOomErrAppCloseIdleRuleOutsideAppCloseElement,
KGOomErrForegroundAppRuleOutsideAppCloseElement,
KGOomErrPluginIdleRuleOutsideAppPluginElement,
KGOomErrPluginForegroundRuleOutsidePluginElement
};
const TInt KGOomXmlFileBufferSize = 1024;
using namespace Xml;
// Mime type of the parsed document
_LIT8(KXmlMimeType, "text/xml");
_LIT(KGOomConfigFilePath, ":\\private\\10207218\\goomconfig.xml");
_LIT(KRomDrive, "z");
// Element strings
// Root
_LIT8(KGOomConfigGOomConfig, "goom_config");
// Global settings
_LIT8(KGOomConfigGlobalSettings, "global_settings");
_LIT8(KGOomConfigForceCheckAtPriority, "force_check");
// App settings
_LIT8(KGOomConfigAppSettings, "app_specific_thresholds");
_LIT8(KGOomConfigApp, "app");
// App close settings
_LIT8(KGOomConfigAppCloseSettings, "app_close_settings");
_LIT8(KGOomConfigCloseApp, "close_app");
_LIT8(KGOomAttributeAppCloseTimeout, "close_timeout");
_LIT8(KGOomAttributeAppWaitAfterClose, "wait_after_close");
// App close idle time
_LIT8(KGOomConfigAppCloseIdlePriority, "app_close_idle_priority");
_LIT8(KGOomConfigForegroundAppPriority, "foreground_app_priority");
// Global settings attribute names
_LIT8(KGOomAttributeLowRamThreshold, "low_ram_threshold");
_LIT8(KGOomAttributeGoodRamThreshold, "good_ram_threshold");
_LIT8(KGOomAttributeMaxAppCloseBatch, "max_app_close_batch");
_LIT8(KGOomAttributeDefaultWaitAfterPlugin, "default_wait_after_plugin");
//App specific
_LIT8(KGOomAttributeTargetFreeOnStartup, "target_free_on_startup");
_LIT8(KGOomAttributeSkipPlugin, "skip_plugin");
// System plugins
_LIT8(KGOomAttributeSystemPluginSettings, "system_plugin_settings");
_LIT8(KGOomAttributeSystemPlugin, "system_plugin");
// Application plugins
_LIT8(KGOomAttributeAppPluginSettings, "app_plugin_settings");
_LIT8(KGOomAttributeAppPlugin, "app_plugin");
// Plugin idle time rules
_LIT8(KGOomAttributePluginIdlePriority, "plugin_idle_priority");
// Plugin foreground app rules
_LIT8(KGOomAttributePluginForegroundAppPriority, "plugin_foreground_app_priority");
// Atribute names
_LIT8(KGOomAttibuteUid, "uid");
_LIT8(KGOomAttibuteSyncMode, "sync_mode");
_LIT8(KGOomAttibutePriority, "priority");
_LIT8(KGOomAttibuteRamEstimate, "ram_estimate");
_LIT8(KGOomConfigSyncModeContinue, "continue");
_LIT8(KGOomConfigSyncModeCheck, "check");
_LIT8(KGOomConfigSyncModeEstimate, "estimate");
_LIT8(KGOomAttibuteIdleTime, "idle_time");
_LIT8(KGOomAttibuteIdlePriority, "priority");
_LIT8(KGOomAttibuteNeverClose, "NEVER_CLOSE");
_LIT8(KGOomAttributeTargetAppId, "target_app_id");
_LIT8(KGOomAttributeWait, "wait");
_LIT8(KGOomAttributeIfForegroundAppId, "if_foreground_app_id");
_LIT8(KGOomConfigDefaultAppUid, "DEFAULT_APP");
_LIT8(KGOomConfigDefaultPluginUid, "DEFAULT_PLUGIN");
_LIT8(KGOomConfigTargetAppValue, "TARGET_APP");
_LIT8(KGOomConfigBusyAppUid, "BUSY_APP");
_LIT8(KGOomConfigHighPriorityAppUid, "HIGH_PRIORITY_APP");
CGOomConfigParser::CGOomConfigParser(CGOomConfig& aConfig, RFs& aFs) : iConfig(aConfig), iFs(aFs), iState(EGOomParsingStateNone)
{
}
void CGOomConfigParser::ParseL()
{
FUNC_LOG;
TRACES("CGOomConfigParser::ParseL: Parsing Config File");
CParser* parser = CParser::NewLC(KXmlMimeType, *this);
RFile configFile;
TFileName configFileName;
TChar driveChar = iFs.GetSystemDriveChar();
configFileName.Append(driveChar);
configFileName.Append(KGOomConfigFilePath);
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<KGOomXmlFileBufferSize> 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("CGOomConfigParser::ParseL: Finished Parsing Config File");
}
void CGOomConfigParser::OnStartDocumentL(const RDocumentParameters&, TInt)
{
FUNC_LOG;
}
void CGOomConfigParser::OnEndDocumentL(TInt)
{
FUNC_LOG;
}
void CGOomConfigParser::OnEndElementL(const RTagInfo&, TInt)
{
}
void CGOomConfigParser::OnContentL(const TDesC8&, TInt)
{
}
void CGOomConfigParser::OnStartPrefixMappingL(const RString&, const RString&,
TInt)
{
}
void CGOomConfigParser::OnEndPrefixMappingL(const RString&, TInt)
{
}
void CGOomConfigParser::OnIgnorableWhiteSpaceL(const TDesC8&, TInt)
{
}
void CGOomConfigParser::OnSkippedEntityL(const RString&, TInt)
{
}
void CGOomConfigParser::OnProcessingInstructionL(const TDesC8&, const TDesC8&,
TInt)
{
}
void CGOomConfigParser::OnError(TInt)
{
}
TAny* CGOomConfigParser::GetExtendedInterface(const TInt32)
{
return 0;
}
void CGOomConfigParser::OnStartElementL(const RTagInfo& aElement, const RAttributeArray& aAttributes,
TInt aErrorCode)
{
if (aErrorCode != KErrNone)
ConfigError(KGOomErrBadXml);
StartElementL(aElement.LocalName().DesC(), aAttributes);
}
TInt CGOomConfigParser::StartElementL(const TDesC8& aLocalName,
const RAttributeArray& aAttributes)
{
// Root
if (aLocalName == KGOomConfigGOomConfig)
{
if (iState != EGOomParsingStateNone)
ConfigError(KGOomErrMoreThanOneGOomConfig);
ChangeState(EGOomParsingStateRoot);
}
// Parse main elements
else if (aLocalName == KGOomConfigGlobalSettings)
{
if (iState != EGOomParsingStateRoot)
ConfigError(KGOomErrGlobalSettingsMustComeAfterRoot);
SetGlobalSettings(aAttributes);
ChangeState(EGOomParsingStateGlobalSettings);
}
else if (aLocalName == KGOomConfigAppSettings)
{
ChangeState(EGOomParsingStateAppSettings);
}
else if (aLocalName == KGOomConfigAppCloseSettings)
{
ChangeState(EGOomParsingStateAppCloseSettings);
}
else if (aLocalName == KGOomAttributeSystemPluginSettings)
{
ChangeState(EGOomParsingStateSystemPluginSettings);
}
else if (aLocalName == KGOomAttributeAppPluginSettings)
{
ChangeState(EGOomParsingStateAppPluginSettings);
}
// Parse actual configuration elements
else if (aLocalName == KGOomConfigForceCheckAtPriority)
{
SetForceCheckConfigL(aAttributes);
}
else if (aLocalName == KGOomConfigApp)
{
SetAppConfigL(aAttributes);
}
else if (aLocalName == KGOomConfigCloseApp)
{
SetCloseAppConfigL(aAttributes);
}
else if (aLocalName == KGOomConfigAppCloseIdlePriority)
{
CheckState(EGOomParsingStateAppCloseSettings, KGOomErrAppCloseIdleRuleOutsideAppCloseElement);
SetAppCloseIdlePriorityConfigL(aAttributes);
}
else if (aLocalName == KGOomConfigForegroundAppPriority)
{
CheckState(EGOomParsingStateAppCloseSettings, KGOomErrForegroundAppRuleOutsideAppCloseElement);
SetForegroundAppPriorityL(aAttributes);
}
else if (aLocalName == KGOomAttributeSystemPlugin)
{
SetSystemPluginConfigL(aAttributes);
}
else if (aLocalName == KGOomAttributeAppPlugin)
{
SetAppPluginConfigL(aAttributes);
}
else if (aLocalName == KGOomAttributePluginIdlePriority)
{
CheckState(EGOomParsingStateAppPluginSettings, KGOomErrPluginIdleRuleOutsideAppPluginElement);
SetPluginIdlePriorityL(aAttributes);
}
else if (aLocalName == KGOomAttributePluginForegroundAppPriority)
{
CheckState(EGOomParsingStateAppPluginSettings, EGOomParsingStateSystemPluginSettings, KGOomErrPluginForegroundRuleOutsidePluginElement);
SetPluginForegroundAppPriorityL(aAttributes);
}
return KErrNone;
}
void CGOomConfigParser::ConfigError(TInt aError)
{
GOomConfigParserPanic(aError);
}
void CGOomConfigParser::SetGlobalSettings(const RAttributeArray& aAttributes)
{
TInt defaultLowMemoryThreshold;
TInt err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeLowRamThreshold, defaultLowMemoryThreshold);
if (err == KErrNone)
iConfig.SetDefaultLowRamThreshold(defaultLowMemoryThreshold * 1024);
else
ConfigError(KGOomErrLowRamErrorInGlobalSettings);
if (err == KErrNone)
{
TInt defaultGoodMemoryThreshold;
TInt err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeGoodRamThreshold, defaultGoodMemoryThreshold);
if (err == KErrNone)
iConfig.SetDefaultGoodRamThreshold(defaultGoodMemoryThreshold * 1024);
else
ConfigError(KGOomErrGoodRamErrorInGlobalSettings);
}
if (err == KErrNone)
{
TInt defaultMaxCloseAppBatch;
TInt err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeMaxAppCloseBatch, defaultMaxCloseAppBatch);
if (err == KErrNone)
iConfig.SetMaxCloseAppBatch(defaultMaxCloseAppBatch);
else
ConfigError(KGOomErrMaxCloseErrorInGlobalSettings);
}
if (err == KErrNone)
{
TInt defaultWaitAfterPlugin;
TInt err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeDefaultWaitAfterPlugin, defaultWaitAfterPlugin);
if (err == KErrNone)
iConfig.SetDefaultWaitAfterPlugin(defaultWaitAfterPlugin);
else
ConfigError(KGOomErrDefaultWaitAfterPluginInGlobalSettings);
}
}
void CGOomConfigParser::SetForceCheckConfigL(const RAttributeArray& aAttributes)
{
TUint priority;
TInt err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttibutePriority, priority);
if (err == KErrNone)
{
iConfig.GlobalConfig().AddForceCheckPriorityL(priority);
}
else
{
ConfigError(KGOomErrBadOrMissingPriorityInForceCheck);
}
}
void CGOomConfigParser::SetAppConfigL(const RAttributeArray& aAttributes)
{
TUint uid;
CGOomApplicationConfig* appConfig = NULL;
TInt err = GetValueFromHexAttributeList(aAttributes, KGOomAttibuteUid, uid);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingUidInAppConfig);
}
else
iParentUid = uid;
appConfig = CGOomApplicationConfig::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, KGOomAttributeLowRamThreshold, lowThreshold);
if (err == KErrNone)
{
appConfig->iLowRamThreshold = lowThreshold * 1024; // The config files work in K, so we need to multiply by 1024
}
else if (err == KErrNotFound)
err = KErrNone;
if (err != KErrNone)
ConfigError(KGOomErrBadLowThresholdValueForAppConfig);
}
// Get the app specific good threshold
if (err == KErrNone)
{
TUint goodThreshold;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeGoodRamThreshold, goodThreshold);
if (err == KErrNone)
{
appConfig->iGoodRamThreshold = goodThreshold * 1024; // The config files work in K, so we need to multiply by 1024
}
else if (err == KErrNotFound)
err = KErrNone;
if (err != KErrNone)
ConfigError(KGOomErrBadGoodThresholdValueForAppConfig);
}
// Get the app specific TargetFreeOnStartup
if (err == KErrNone)
{
TUint targetFree;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeTargetFreeOnStartup, targetFree);
if (err == KErrNone)
{
appConfig->iTargetFree = targetFree * 1024; // The config files work in K, so we need to multiply by 1024
}
else if (err == KErrNotFound)
err = KErrNone;
if (err != KErrNone)
ConfigError(KGOomErrBadTargetFreeValueForAppConfig);
}
// Get the app specific SkipPlugin
if (err == KErrNone)
{
TUint skipPlugin;
err = GetValueFromHexAttributeList(aAttributes, KGOomAttributeSkipPlugin, skipPlugin);
if (err == KErrNone)
{
TRACES2("SKIP PLUGIN %x configured for App %x", skipPlugin, uid);
appConfig->iSkipPluginId = skipPlugin;
}
else if (err == KErrNotFound)
err = KErrNone;
if (err != KErrNone)
ConfigError(KGOomErrBadSkipPluginValueForAppConfig);
}
// Add the applciation config to the main config
if ((err == KErrNone) && (appConfig))
{
iConfig.AddApplicationConfigL(appConfig);
}
if (appConfig)
CleanupStack::Pop(appConfig);
}
void CGOomConfigParser::SetCloseAppConfigL(const RAttributeArray& aAttributes)
{
// Get and convert uid attribute to TInt
TInt err = KErrNone;
TUint uid;
err = GetValueFromHexAttributeList(aAttributes, KGOomAttibuteUid, uid);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingUidInAppCloseConfig);
return;
}
else
iParentUid = uid;
CGOomCloseAppConfig* closeAppConfig = CGOomCloseAppConfig::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, KGOomAttibutePriority, priority);
if (err == KErrNone)
{
closeAppConfig->SetDefaultPriority(priority);
}
else
{
ConfigError(KGOomErrBadOrMissingPriorityInAppCloseConfig);
}
}
if (err == KErrNone)
{
TPtrC8 syncModeString;
err = GetValueFromAttributeList(aAttributes, KGOomAttibuteSyncMode, syncModeString);
if (err == KErrNone)
{
TGOomSyncMode syncMode = EContinue;
if (syncModeString == KGOomConfigSyncModeContinue)
syncMode = EContinue;
else if (syncModeString == KGOomConfigSyncModeCheck)
syncMode = ECheckRam;
else if (syncModeString == KGOomConfigSyncModeEstimate)
syncMode = EEstimate;
else
ConfigError(KGOomErrInvalidSyncMode);
if (err == KErrNone)
{
closeAppConfig->iSyncMode = syncMode;
}
}
else
{
ConfigError(KGOomErrMissingSyncModeInAppCloseConfig);
}
}
if (err == KErrNone)
{
// If we have a default priority attribute then add it, otherwise use the global default priority
TInt ramEstimate;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttibuteRamEstimate, ramEstimate);
if ((err == KErrNotFound) && (closeAppConfig->iSyncMode != EEstimate))
{
err = KErrNone;
}
if (err != KErrNone)
ConfigError(KGOomErrMissingEstimateFromAppCloseConfig);
else
closeAppConfig->iRamEstimate = ramEstimate * 1024;
}
if (err == KErrNone)
{
TInt closeTimeout;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeAppCloseTimeout, closeTimeout);
if (err == KErrNone)
{
closeAppConfig->iCloseTimeout = closeTimeout;
}
else if (err == KErrNotFound)
{
closeAppConfig->iCloseTimeout=0;
err = KErrNone;
}
}
if (err == KErrNone)
{
TInt waitAfterClose;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeAppWaitAfterClose, waitAfterClose);
if (err == KErrNone)
{
closeAppConfig->iWaitAfterClose = waitAfterClose;
}
else if (err == KErrNotFound)
{
err = KErrNone;
closeAppConfig->iWaitAfterClose = 0;
}
}
if (err == KErrNone)
{
iConfig.SetAppCloseConfigL(closeAppConfig);
}
else
{
TRACES2("ERROR Creating Appcloseconfig file for %x, err %d", uid,err);
}
CleanupStack::Pop(closeAppConfig);
}
void CGOomConfigParser::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, KGOomAttibuteIdleTime, idleTime);
#ifdef __WINS__
// The tick is 5 times slower on the emulator than on the phone
idleTime = idleTime / 5;
#endif
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingIdleTimeInAppIdleRule);
}
if (err == KErrNone)
{
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttibuteIdlePriority, priority);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingPriorityInAppIdleRule);
}
}
if (err == KErrNone)
{
CGOomIdleTimeRule* idleRule = CGOomIdleTimeRule::NewL(idleTime, priority);
CleanupStack::PushL(idleRule);
iConfig.AddApplicationRuleL(uid, idleRule);
CleanupStack::Pop(idleRule);
}
}
void CGOomConfigParser::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, KGOomAttributeIfForegroundAppId, targetAppId);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingTargetAppIdInForegroundAppRule);
}
if (err == KErrNone)
{
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttibuteIdlePriority, priority);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingPriorityInForegroundAppRule);
}
}
if (err == KErrNone)
{
CGOomForegroundRule* foregroundRule = new (ELeave) CGOomForegroundRule(targetAppId, priority);
CleanupStack::PushL(foregroundRule);
iConfig.AddApplicationRuleL(appUid, foregroundRule);
CleanupStack::Pop(foregroundRule);
}
}
void CGOomConfigParser::SetSystemPluginConfigL(const RAttributeArray& aAttributes)
{
// Get and convert uid attribute to TInt
TInt err = KErrNone;
TUint uid;
err = GetValueFromHexAttributeList(aAttributes, KGOomAttibuteUid, uid);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingUidInSystemPluginConfig);
return;
}
else
iParentUid = uid;
CGOomRunPluginConfig* pluginConfig = CGOomRunPluginConfig::NewL(uid, EGOomSystemPlugin);
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, KGOomAttibutePriority, priority);
if (err == KErrNone)
{
pluginConfig->SetDefaultPriority(priority);
}
else
{
ConfigError(KGOomErrBadOrMissingPriorityInSystemPluginConfig);
}
}
if (err == KErrNone)
{
TInt wait;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeWait, 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(KGOomErrBadPluginWaitTime);
}
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 CGOomConfigParser::SetAppPluginConfigL(const RAttributeArray& aAttributes)
{
// Get and convert uid attribute to TInt
TInt err = KErrNone;
TUint uid;
err = GetValueFromHexAttributeList(aAttributes, KGOomAttibuteUid, uid);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingUidInAppPluginConfig);
return;
}
else
iParentUid = uid;
CGOomRunPluginConfig* pluginConfig = CGOomRunPluginConfig::NewL(uid, EGOomAppPlugin);
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, KGOomAttibutePriority, priority);
if (err == KErrNone)
{
pluginConfig->SetDefaultPriority(priority);
}
else
{
ConfigError(KGOomErrBadOrMissingPriorityInAppPluginConfig);
}
}
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, KGOomAttributeTargetAppId, targetAppId);
if (err == KErrNone)
{
pluginConfig->SetTargetApp(targetAppId);
iParentTargetApp = targetAppId;
}
else
{
ConfigError(KGOomErrBadOrMissingTargetAppIdInAppPluginConfig);
}
}
if (err == KErrNone)
{
TInt wait;
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttributeWait, 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(KGOomErrBadPluginWaitTime);
}
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 CGOomConfigParser::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, KGOomAttibuteIdleTime, idleTime);
#ifdef __WINS__
// The tick is 5 times slower on the emulator than on the phone
idleTime = idleTime / 5;
#endif
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingIdleTimeInPluginIdleRule);
}
if (err == KErrNone)
{
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttibuteIdlePriority, priority);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingPriorityInPluginIdleRule);
}
}
if (err == KErrNone)
{
CGOomIdleTimeRule* idleRule = CGOomIdleTimeRule::NewL(idleTime, priority);
CleanupStack::PushL(idleRule);
iConfig.AddPluginRuleL(uid, idleRule);
CleanupStack::Pop(idleRule);
}
}
void CGOomConfigParser::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, KGOomAttributeTargetAppId, targetAppString);
if ((err == KErrNone)
&& (targetAppString == KGOomConfigTargetAppValue)
&& (iState == EGOomParsingStateAppPluginSettings))
// 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, KGOomAttributeTargetAppId, targetAppId);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingTargetAppIdInForegroundAppRule);
}
}
if (err == KErrNone)
{
err = GetValueFromDecimalAttributeList(aAttributes, KGOomAttibuteIdlePriority, priority);
if (err != KErrNone)
{
ConfigError(KGOomErrBadOrMissingPriorityInForegroundAppRule);
}
}
if (err == KErrNone)
{
CGOomForegroundRule* foregroundRule = new (ELeave) CGOomForegroundRule(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 CGOomConfigParser::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 CGOomConfigParser::GetValueFromHexAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TUint& aValue)
{
TPtrC8 hexString;
TInt err = GetValueFromAttributeList(aAttributes, aName, hexString);
if (hexString == KGOomConfigDefaultAppUid)
{
// This is a special case
// When we hit this value in a hex field then we return the default app UID
aValue = KGOomDefaultAppId;
}
else if (hexString == KGOomConfigDefaultPluginUid)
{
// This is a special case
// When we hit this value in a hex field then we return the default app UID
aValue = KGOomDefaultPluginId;
}
else if (hexString == KGOomConfigBusyAppUid)
{
aValue = KGOomBusyAppId;
}
else if (hexString == KGOomConfigHighPriorityAppUid)
{
aValue = KGOomHighPriorityAppId;
}
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 CGOomConfigParser::GetValueFromDecimalAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TUint& aValue)
{
TPtrC8 decimalString;
TInt err = GetValueFromAttributeList(aAttributes, aName, decimalString);
if (err == KErrNone)
{
if (decimalString == KGOomAttibuteNeverClose)
aValue = KGOomPriorityInfinate;
else
{
TLex8 decimalLex(decimalString);
err = decimalLex.Val(aValue, EDecimal);
if (err != KErrNone)
err = KErrCorrupt;
}
}
return err;
}
TInt CGOomConfigParser::GetValueFromDecimalAttributeList(const RAttributeArray& aAttributes, const TDesC8& aName, TInt& aValue)
{
TUint uintValue;
TInt err = GetValueFromDecimalAttributeList(aAttributes, aName, uintValue);
aValue = uintValue;
return err;
}
void CGOomConfigParser::SetPluginSyncMode(const RAttributeArray& aAttributes, CGOomRunPluginConfig& aRunPluginConfig)
{
TPtrC8 syncModeString;
TInt err = GetValueFromAttributeList(aAttributes, KGOomAttibuteSyncMode, syncModeString);
if (err == KErrNone)
// If there is no specified sync mode then leave it as the default
{
TGOomSyncMode syncMode = EContinue;
if (syncModeString == KGOomConfigSyncModeContinue)
syncMode = EContinueIgnoreMaxBatchSize;
else if (syncModeString == KGOomConfigSyncModeCheck)
syncMode = ECheckRam;
else if (syncModeString == KGOomConfigSyncModeEstimate)
syncMode = EEstimate;
else
ConfigError(KGOomErrInvalidSyncMode);
if (err == KErrNone)
{
aRunPluginConfig.iSyncMode = syncMode;
}
}
}
// Check that the current state is as expected
// If not then the specified config error is generated
void CGOomConfigParser::CheckState(TGOomParsingState 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 CGOomConfigParser::CheckState(TGOomParsingState aExpectedState1, TGOomParsingState aExpectedState2, TInt aError)
{
if ((iState != aExpectedState1)
&& (iState != aExpectedState2))
ConfigError(aError);
}
void CGOomConfigParser::ChangeState(TGOomParsingState aState)
{
iState = aState;
}