diff -r 52e343bb8f80 -r e26895079d7c piprofiler/plugins/PWRplugin/src/PwrPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piprofiler/plugins/PWRplugin/src/PwrPlugin.cpp Wed Sep 15 00:19:18 2010 +0300 @@ -0,0 +1,623 @@ +/* +* 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 "PwrPlugin.h" +#include + +#include +#include +#include +#include + + +// texts for notes +_LIT(KPowerTextLine1, "Power sampler:"); +_LIT(KPowerTextLine2, "Failed to start power measurement"); +_LIT(KPowerTextErrorSampling, "Error receiving measurement data"); +_LIT(KButtonOk, "Ok"); + +// LITERALS + +_LIT8(KSamplingPeriodMs, "sampling_period_ms"); + +// CONSTANTS +// Use this UID if plugin is PwrPlugin: +const TUid KSamplerPwrPluginUid = { 0x2001E5B9 }; + +/* + * + * class CPwrPlugin implementation + * + */ + +CPwrPlugin* CPwrPlugin::NewL(const TUid /*aImplementationUid*/, TAny* aInitParams) + { + LOGTEXT(_L("CPwrPlugin::NewL() - entry")); + CPwrPlugin* self = new (ELeave) CPwrPlugin(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + LOGTEXT(_L("CPwrPlugin::NewL() - exit")); + return self; + } + +CPwrPlugin::CPwrPlugin() : + iVersionDescriptor(&(this->iVersion[1]),0,19), + iSamplerType(PROFILER_USER_MODE_SAMPLER) + { + iPeriod = 250; + iSamplerId = PROFILER_PWR_SAMPLER_ID; + iEnabled = EFalse; + iPowerListener = NULL; + LOGTEXT(_L("CPwrPlugin::CPwrPlugin() - konstruktori")); + + } + +void CPwrPlugin::ConstructL() + { + LOGTEXT(_L("CPwrPlugin::ConstructL() - entry")); + // initiate sampler attributes array + iSamplerAttributes = new(ELeave) CArrayFixFlat(1); // only one sampler + + // insert default attributes to array + InitiateSamplerAttributesL(); + + LOGTEXT(_L("CPwrPlugin::ConstructL() - exit")); + } + +CPwrPlugin::~CPwrPlugin() + { + LOGTEXT(_L("CPwrPlugin::~CPwrPlugin() - entry")); + if(iPowerListener) + { + if(Enabled()) + { + iPowerListener->Stop(); + } + delete iPowerListener; + iPowerListener = NULL; + } + + if(iSamplerAttributes) + { + iSamplerAttributes->Reset(); + delete iSamplerAttributes; + iSamplerAttributes = NULL; + } + + LOGTEXT(_L("CPwrPlugin::~CPwrPlugin() - exit")); + } + +TUid CPwrPlugin::Id(TInt /*aSubId*/) const + { + LOGSTRING2( "CPwrPlugin::Id():0x%X", KSamplerPwrPluginUid.iUid ); + return KSamplerPwrPluginUid; + } + +void CPwrPlugin::InitiateSamplerAttributesL() + { + // create TSamplerAttributes + TSamplerAttributes attr(KSamplerPwrPluginUid.iUid, + KPWRShortName(), + KPWRLongName(), + KPWRDescription(), + 250, + EFalse, + EFalse, + 0); + this->iSamplerAttributes->AppendL(attr); + } + +void CPwrPlugin::SetEnabled(TBool aEnabled) + { + iEnabled = aEnabled; + } + +// returns setting array +void CPwrPlugin::GetAttributesL(CArrayFixFlat* aAttributes) + { + aAttributes->AppendL(iSamplerAttributes->At(0)); + } + +TInt CPwrPlugin::SetAttributesL(TSamplerAttributes aAttributes) + { + TSamplerAttributes attr; + + attr = iSamplerAttributes->At(0); + // replace the old attribute container + iSamplerAttributes->Delete(0); + iSamplerAttributes->InsertL(0, aAttributes); + return KErrNone; + } + +/* + * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler), + * called by CSamplerController class + * + * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n + */ +TInt CPwrPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray) + { + // local literals + _LIT8(KPWRShort, "pwr"); + + TInt err(KErrNone); + TBuf8<16> samplerSearchName; + samplerSearchName.Copy(KPWRShort); + + // get sampler specific settings + err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, 0); + + // returns KErrNone if settings found, otherwise KErrNotFound + return err; + } + +TInt CPwrPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex) + { + // + TBuf8<16> samplerSearch; + samplerSearch.Copy(KBracketOpen); + samplerSearch.Append(aSamplerName); + samplerSearch.Append(KBracketClose); + + // read a line + for (TInt i(0); iMdcaCount(); i++) + { + // check if this line has a setting block start, i.e. contains [xxx] in it + if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0) + { + // right settings block found, now loop until the next block is found + for(TInt j(i+1);jMdcaCount();j++) + { + // check if the next settings block was found + if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0) + { + // save found setting value directly to its owners attributes + SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex); + } + else + { + // next block found, return KErrNone + return KErrNone; + } + } + } + } + + return KErrNotFound; + } + +/** + * Method for setting a specific descriptor (from settings file) to attribute structure + * + * @param aSetting + * @param aName + */ +void CPwrPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex) + { + // find the equal mark from the setting line + TInt sepPos = aSetting.Find(KSettingItemSeparator); + // check that '=' is found + if (sepPos > 0) + { + // check that the element matches + if (aSetting.Left(sepPos).CompareF(KEnabled) == 0) + { + TBool en; + CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en); + if(en != iSamplerAttributes->At(aIndex).iEnabled) + { + iSamplerAttributes->At(aIndex).iEnabled = en; + } + } + else if (aSetting.Left(sepPos).CompareF(KSamplingPeriodMs) == 0) + { + TInt sr; + CSamplerPluginInterface::Str2Int(aSetting.Right(aSetting.Length()-sepPos-1), sr); + if(sr != iSamplerAttributes->At(aIndex).iSampleRate) + { + iSamplerAttributes->At(aIndex).iSampleRate = sr; + } + } + } + } + +TInt CPwrPlugin::GetSamplerType() + { + return iSamplerType; + } + +TInt CPwrPlugin::ResetAndActivateL(CProfilerSampleStream& aStream) + { + LOGTEXT(_L("CPwrPlugin::ResetAndActivate() - entry")); + // check if sampler enabled + if(iSamplerAttributes->At(0).iEnabled) + { + // create a new listener instance for every trace, destroy it on stop + iPowerListener = CProfilerPowerListener::NewL(this); + + iStream = &aStream; + TInt length = this->CreateFirstSample(); + iVersion[0] = (TUint8)length; + LOGSTRING2("CPwrPlugin::ResetAndActivate() - AddSample, length %d", length); + TInt ret = this->AddSample(iVersion, length+1, 0); + + LOGSTRING2("CPwrPlugin::ConstructL() - sampling period %d", this->iPeriod); + + HBufC8* iBufRes = HBufC8::NewMaxLC(10); + TPtr8 iPtrRes = iBufRes->Des(); + + // check if sampling rate set to something reasonable, relevant only in SYNC case + if(iSamplerAttributes->At(0).iSampleRate != -1) + { + iPtrRes.Num(iSamplerAttributes->At(0).iSampleRate); + } + else + { + iPtrRes.Append(KNullDesC8); + } + + // set disabled + SetEnabled(ETrue); + + // activate power listener + ret = iPowerListener->StartL(iPtrRes); + LOGTEXT(_L("CPwrPlugin::ResetAndActivate() - exit")); + + CleanupStack::PopAndDestroy(); + + if(ret != KErrNone) + return ret; + } + return KErrNone; + } + +TInt CPwrPlugin::CreateFirstSample() + { + LOGTEXT(_L("CPwrPlugin::CreateFirstSample - entry")); + this->iVersionDescriptor.Zero(); + this->iVersionDescriptor.Append(_L8("Bappea_PWR_V")); + this->iVersionDescriptor.Append(PROFILER_PWR_SAMPLER_VERSION); + LOGTEXT(_L("CPwrPlugin::CreateFirstSample - exit")); + return (TInt)(this->iVersionDescriptor.Length()); + } + +TInt CPwrPlugin::StopSampling() + { + if(iPowerListener) + { + iPowerListener->Stop(); + delete iPowerListener; + iPowerListener = NULL; + } + + // set disabled + SetEnabled(EFalse); + + return KErrNone; + } + + +/* + * + * class CProfilerPowerListener implementation + * + */ + +CProfilerPowerListener::CProfilerPowerListener(CPwrPlugin* aSampler) : + iPwrSamplingPeriod(0), + iOriginalReportingPeriod(0), + iNominalCapa(0), + iVoltage(0), + iCurrent(0), + iPowerAPI(0) +#ifdef PWR_SAMPLER_BACKLIGHT + ,iLightAPI(0), + iBackLightStatus(CHWRMLight::ELightStatusUnknown) +#endif + + { + LOGTEXT(_L("CProfilerPowerListener::CProfilerPowerListener() - konstuktori")); + this->iSampler = aSampler; + LOGTEXT(_L("CProfilerPowerListener::CProfilerPowerListener() - konstuktori exit")); + } + +CProfilerPowerListener* CProfilerPowerListener::NewL(CPwrPlugin* aSampler) + { + LOGTEXT(_L("CProfilerPowerListener::NewL() - entry")); + CProfilerPowerListener* self = new (ELeave) CProfilerPowerListener(aSampler); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + LOGTEXT(_L("CProfilerPowerListener::NewL() - exit")); + return self; + } + +void CProfilerPowerListener::ConstructL() + { + LOGTEXT(_L("CProfilerPowerListener::ConstructL() - entry")); + iSampleStartTime = 0; + LOGTEXT(_L("CProfilerPowerListener::ConstructL() - exit")); + } + +CProfilerPowerListener::~CProfilerPowerListener() + { + LOGTEXT(_L("CProfilerPowerListener::~CProfilerPowerListener() - entry")); + + if (iPowerAPI) + { + delete iPowerAPI; + iPowerAPI = 0; + } +#ifdef PWR_SAMPLER_BACKLIGHT + if (iLightAPI) + { + delete iLightAPI; + iLightAPI = 0; + } +#endif + + LOGTEXT(_L("CProfilerPowerListener::~CProfilerPowerListener() - exit")); + } + +TInt CProfilerPowerListener::DisplayNotifierL(const TDesC& aLine1, const TDesC& aLine2, const TDesC& aButton1, const TDesC& aButton2) + { + RNotifier notifier; + TRequestStatus stat; + + TInt buttonValue(0); + + User::LeaveIfError(notifier.Connect()); + + notifier.Notify(aLine1, aLine2, aButton1, aButton2, buttonValue, stat); + User::WaitForRequest(stat); + + notifier.Close(); + return buttonValue; + } + + +TInt CProfilerPowerListener::StartL(const TDesC8& aBuf) + { + LOGTEXT(_L("CProfilerPowerListener::StartL() - entry")); + + // get the property value + TInt r = RProperty::Get(KGppPropertyCat, EGppPropertySyncSampleNumber, iSampleStartTime); + if(r != KErrNone) + { + LOGSTRING2("CProfilerPowerListener::StartL() - getting iSyncOffset failed, error %d", r); + } + + // check if given sampling period is valid + if(aBuf.CompareF(KNullDesC8)!= 0) + { + TLex8* lex = new TLex8(aBuf); + lex->Val(iPwrSamplingPeriod); + delete lex; + } + else + { + // set default period + iPwrSamplingPeriod = 250; + } + + // Check that sampling period is in allowed range + if (KMinSampleInterval > 0 && iPwrSamplingPeriod < KMinSampleInterval) + { + iPwrSamplingPeriod = KMinSampleInterval; + } + + LOGSTRING2("CProfilerPowerListener::StartL() - Sampling period %d", iPwrSamplingPeriod); + + // Start monitoring voltage and current + iPowerAPI = CHWRMPower::NewL(); + iPowerAPI->SetPowerReportObserver(this); + + // Read HWRM reporting settings from central repository + CRepository* centRep = CRepository::NewL(KCRUidPowerSettings); + TInt baseInterval(0); + User::LeaveIfError(centRep->Get(KPowerBaseTimeInterval, baseInterval)); + User::LeaveIfError(centRep->Get(KPowerMaxReportingPeriod, iOriginalReportingPeriod)); + + LOGSTRING2("CProfilerPowerListener::StartL() - HWRM base power report interval: %d", baseInterval); + LOGSTRING2("CProfilerPowerListener::StartL() - Original HWRM max power reporting period: %d", iOriginalReportingPeriod); + + User::LeaveIfError(centRep->Set(KPowerMaxReportingPeriod, KReportingPeriodInfinite)); + + // Power reporting interval reading may return too low value sometimes. Minimum value expected to be 250ms. + if ( baseInterval < KMinSampleInterval ) + { + baseInterval = KMinSampleInterval; + LOGSTRING2("CProfilerPowerListener::StartL() - Power report interval too low. Changed to: %d", baseInterval); + } + + // Power reporting period is multiplier of HWRM base period + TInt intervalMultiplier = iPwrSamplingPeriod / baseInterval; + + if (intervalMultiplier < 1) + { + intervalMultiplier = 1; + } + + LOGSTRING2("CProfilerPowerListener::StartL() - Reporting period multiplier: %d", intervalMultiplier); + + TRequestStatus status(KRequestPending); + iPowerAPI->StartAveragePowerReporting(status, intervalMultiplier); + User::WaitForRequest(status); + + if (status.Int() != KErrNone) + { + LOGTEXT(_L("CProfilerPowerListener::StartL() - Failed to initialize power reporting")); + + DisplayNotifierL(KPowerTextLine1, KPowerTextLine2, KButtonOk, KNullDesC); + + return status.Int(); + } + +#ifdef PWR_SAMPLER_BACKLIGHT + // Start monitoring backlight status + iLightAPI = CHWRMLight::NewL(this); +#endif + + LOGTEXT(_L("CProfilerPowerListener::StartL() - exit")); + return KErrNone; + } + +void CProfilerPowerListener::Sample() + { + LOGTEXT(_L("CProfilerPowerListener::Sample() - entry")); + + TRequestStatus status; + CHWRMPower::TBatteryConsumptionData consumptionData; + + iPowerAPI->GetBatteryInfo(status, consumptionData); + User::WaitForRequest(status); + + // Data is valid only if status == KErrNone + if (status.Int() != KErrNone) + { + LOGSTRING2("CProfilerPowerListener::Sample() - Getting battery info failed with code: ", status.Int()); + iNominalCapa = 0; + } + else + { + iNominalCapa = consumptionData.iNominalCapacity; + } + + // Space for GPP sample time + //TUint32 sampleTime = iSampler->iStream->iSampler->GetSampleTime(); + TUint32 sampleTime = User::NTickCount() - iSampleStartTime; + LOGSTRING2("CProfilerPowerListener::Sample() - Sample time: %d", sampleTime); + LOGSTRING2("CProfilerPowerListener::Sample() - Nominal capacitance: %d", iNominalCapa); + LOGSTRING2("CProfilerPowerListener::Sample() - Voltage: %d", iVoltage); + LOGSTRING2("CProfilerPowerListener::Sample() - Current: %d", iCurrent); +#ifdef PWR_SAMPLER_BACKLIGHT + LOGSTRING2("CProfilerPowerListener::Sample() - Backlight status: %d", (TUint8)iBackLightStatus); +#endif + + iSample[0] = iNominalCapa; + iSample[1] = iNominalCapa >> 8; + iSample[2] = iVoltage; + iSample[3] = iVoltage >> 8; + iSample[4] = iCurrent; + iSample[5] = iCurrent >> 8; + iSample[6] = iCurrent >> 16; + iSample[7] = iCurrent >> 24; +#ifdef PWR_SAMPLER_BACKLIGHT + iSample[8] = (TUint8)iBackLightStatus; + iSample[9] = sampleTime; + iSample[10] = sampleTime >> 8; + iSample[11] = sampleTime >> 16; + iSample[12] = sampleTime >> 24; + + iSampler->AddSample(iSample, 13, 0); +#else + iSample[8] = sampleTime; + iSample[9] = sampleTime >> 8; + iSample[10] = sampleTime >> 16; + iSample[11] = sampleTime >> 24; + + iSampler->AddSample(iSample, 12, 0); +#endif + + LOGTEXT(_L("CProfilerPowerListener::Sample() - exit")); + } + +TInt CProfilerPowerListener::Stop() + { + LOGTEXT(_L("CProfilerPowerListener::Stop() - entry")); + + if (iPowerAPI) + { + TRAPD(err, iPowerAPI->StopAveragePowerReportingL()); + if(err != KErrNone) + { + LOGSTRING2("CProfilerPowerListener::Stop() - Failed to stop power reporting: %d", err); + } + else + { + LOGTEXT(_L("CProfilerPowerListener::Stop() - Stopped power monitoring")); + } + delete iPowerAPI; + iPowerAPI = 0; + + // Restore original value to max sampling period + CRepository* centRep = 0; + TRAP(err, centRep = CRepository::NewL(KCRUidPowerSettings)); + if (err != KErrNone) + { + LOGSTRING2("CProfilerPowerListener::Stop() - Failed to open Central Repository: %d", err); + } + else + { + err = centRep->Set(KPowerMaxReportingPeriod, iOriginalReportingPeriod); + if(err != KErrNone) + { + LOGSTRING2("CProfilerPowerListener::Stop() - Failed to restore max sampling period: %d", err); + } + } + } +#ifdef PWR_SAMPLER_BACKLIGHT + if (iLightAPI) + { + delete iLightAPI; + iLightAPI = 0; + } +#endif + + LOGTEXT(_L("CProfilerPowerListener::Stop() - exit")); + return KErrNone; + } + +void CProfilerPowerListener::PowerMeasurement(TInt aErr, CHWRMPower::TBatteryPowerMeasurementData& aMeasurement) + { + LOGTEXT(_L("CProfilerPowerListener::PowerMeasurement - entry")); + + if (aErr == KErrNone) + { + LOGSTRING3("CProfilerPowerListener::PowerMeasurement - Previous values - Voltage: %d Current: %d", iVoltage, iCurrent); + iVoltage = aMeasurement.iAverageVoltage; + iCurrent = aMeasurement.iAverageCurrent; + LOGSTRING3("CProfilerPowerListener::PowerMeasurement - New values - Voltage: %d Current: %d", iVoltage, iCurrent); + + this->Sample(); + } + else + { + LOGSTRING2("CProfilerPowerListener::PowerMeasurement - Failed with error code: %d", aErr); + DisplayNotifierL(KPowerTextLine1, KPowerTextErrorSampling, KButtonOk, KNullDesC); + } + LOGTEXT(_L("CProfilerPowerListener::PowerMeasurement - exit")); + } + +#ifdef PWR_SAMPLER_BACKLIGHT +void CProfilerPowerListener::LightStatusChanged(TInt aTarget, CHWRMLight::TLightStatus aStatus) + { + LOGTEXT(_L("CProfilerPowerListener::LightStatusChanged - entry")); + LOGSTRING3("CProfilerPowerListener::LightStatusChanged - Target: %d Status: %d", aTarget, aStatus); + + if (aTarget == CHWRMLight::EPrimaryDisplay) + { + LOGSTRING2("CProfilerPowerListener::LightStatusChanged - Previous light status: %d", iBackLightStatus); + iBackLightStatus = aStatus; + LOGSTRING2("CProfilerPowerListener::LightStatusChanged - New light status: %d", iBackLightStatus); + + this->Sample(); + } + LOGTEXT(_L("CProfilerPowerListener::LightStatusChanged - exit")); + } +#endif