diff -r e8e63152f320 -r 2a9601315dfc javaextensions/sensor/src.s60/csensorbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/sensor/src.s60/csensorbase.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,324 @@ +/* +* 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: Base class for sensors +* +*/ + + +#include "csensorbase.h" +#include "csensorlimitcondition.h" +#include "csensorrangecondition.h" +#include "sensorlistener.h" +#include "logger.h" +#include +#include + +const TUint JavaUpperTimeFor1970 = 14474675; +const TUint JavaLowerTimeFor1970 = 254771200; + +CSensorBase::~CSensorBase() +{ + JELOG2(ESensor); + iConditions.ResetAndDestroy(); + iConditions.Close(); + Cancel(); + delete iActiveScheduler; + iRunnerThread.Close(); + iMethodArray.Close(); +} +CSensorBase::CSensorBase() : CActive(EPriorityHigh), + iListeningType(0) +{ + JELOG2(ESensor); +} + +void CSensorBase::ConstructL() +{ + JELOG2(ESensor); + User::LeaveIfError(iRunnerThread.Open(RThread().Id())); + if (!CActiveScheduler::Current()) + { + iActiveScheduler = new(ELeave) CActiveScheduler(); + CActiveScheduler::Install(iActiveScheduler); + } + CActiveScheduler::Add(this); +} + +TInt64 CSensorBase::TimeStamp(const TTime& aTime) +{ + JELOG2(ESensor); + // Create a TTime object that represents the Java Date + // 'epoch' time of 00:00, 1 Jan 1970 + TInt64 javaEpocTimeNum = + MAKE_TINT64(JavaUpperTimeFor1970, JavaLowerTimeFor1970); + TTime javaEpochTime(javaEpocTimeNum); + // Find difference in microseconds between 'epoch' and EPOC + // date and adjust to milliseconds + TTimeIntervalMicroSeconds microInterval = + aTime.MicroSecondsFrom(javaEpochTime); + TInt64 intervalNum = microInterval.Int64(); + intervalNum /= 1000; + return intervalNum; +} + +void CSensorBase::StartServer() +{ + JELOG2(ESensor); + CActiveScheduler::Start(); +} + +void CSensorBase::StopServer() +{ + JELOG2(ESensor); + TMethod method(TMethod::EStopServer); + AsyncCallback(method); +} + +int CSensorBase::StartDataListening(SensorData** aData, + int aBufferSize, + long aBufferingPeriod, + bool aTimestampsIncluded, + bool aValiditiesIncluded, + bool aIsOneShot) +{ + JELOG2(ESensor); + TMethod method(TMethod::EStartDataListening); + method.SetSensorData(aData); + method.SetBufferSize(aBufferSize); + method.SetBufferingPeriod(aBufferingPeriod); + method.SetTimestampsIncluded(aTimestampsIncluded); + method.SetValiditiesIncluded(aValiditiesIncluded); + method.SetIsOneShot(aIsOneShot); + AsyncCallback(method); + return KErrNone; +} + +int CSensorBase::StartConditionListening(int aJavaConditionEval) +{ + JELOG2(ESensor); + TMethod method(TMethod::EStartConditionListening); + method.SetJavaConditionEval(aJavaConditionEval); + AsyncCallback(method); + return KErrNone; +} + +int CSensorBase::CancelDataListening() +{ + JELOG2(ESensor); + TMethod method(TMethod::ECancelDataListening); + AsyncCallback(method); + return KErrNone; +} + +int CSensorBase::StopConditionListening() +{ + JELOG2(ESensor); + TMethod method(TMethod::EStopConditionListening); + AsyncCallback(method); + return KErrNone; +} + +void CSensorBase::CloseChannel() +{ + JELOG2(ESensor); + TMethod method(TMethod::ECloseChannel); + AsyncCallback(method); +} + +void CSensorBase::AsyncCallback(TMethod aMethod) +{ + JELOG2(ESensor); + iMethodArray.Append(aMethod); + + // If there is old request ongoing, wait it for completion + if (iMethodArray.Count() > 1) + { + return; + } + iStatus = KRequestPending; + TRequestStatus* status = &iStatus; + SetActive(); + iRunnerThread.RequestComplete(status, KErrNone); +} + +void CSensorBase::RunL() +{ + JELOG2(ESensor); + // RunL should never be running if there is no method in array + __ASSERT_DEBUG(iMethodArray.Count() > 0, User::Invariant()); + TMethod method = iMethodArray[0]; + + switch (method.GetMethodType()) + { + case TMethod::EStartDataListening: + { + iData = method.GetSensorData(); + iBufferSize = method.GetBufferSize(); + iBufferingPeriod = 1000 * method.GetBufferingPeriod(); + iIsOneShot = method.GetIsOneShot(); + iTimestampsIncluded = method.GetTimestampsIncluded(); + iValiditiesIncluded = method.GetValiditiesIncluded(); + + StartDataListeningL(); + break; + } + case TMethod::EStartConditionListening: + { + iJavaConditionEval = method.GetJavaConditionEval(); + StartConditionListeningL(); + break; + } + case TMethod::EStopConditionListening: + { + StopConditionListeningL(); + break; + } + case TMethod::ECancelDataListening: + { + CancelDataListeningL(); + break; + } + case TMethod::ECloseChannel: + { + CloseChannelL(); + break; + } + case TMethod::EStopServer: + { + CActiveScheduler::Stop(); + break; + } + case TMethod::ERemoveCondition: + { + RemoveConditionL(method.GetConditionToRemove()); + break; + } + default: + { + break; + } + } + // If there is still methods left in array, then request new run + if (iMethodArray.Count() > 1) + { + iStatus = KRequestPending; + TRequestStatus* status = &iStatus; + SetActive(); + iRunnerThread.RequestComplete(status, KErrNone); + } + iMethodArray.Remove(0); +} + +void CSensorBase::DoCancel() +{ + JELOG2(ESensor); +} + +TBool CSensorBase::EvaluateConditions(TReal aValue, TInt aChannelId) +{ + JELOG2(ESensor); + TReal currentValue = InterpretValue(aValue); + TBool matched = EFalse; + TTime time; + time.UniversalTime(); + TInt64 javaTime = TimeStamp(time); + // Condition array is iterated backwards so we can + // remove matched elements at the same time + for (TInt i = iConditions.Count() - 1; i >= 0; i--) + { + if (iConditions[ i ]->Evaluate(currentValue, aChannelId)) + { + matched = ETrue; + CSensorConditionBase *condition = iConditions[i]; + iConditions.Remove(i); + if (iSensorListener) + { + iSensorListener->ConditionMet( + condition, + condition->GetChannelId(), + currentValue, + javaTime); + } + delete condition; + } + } + + // Also send all values separately if we have java side custom conditions + if (iJavaConditionEval) + { + iSensorListener->ConditionMet(0, aChannelId, currentValue, javaTime); + } + return matched; +} + +int CSensorBase::AddCondition( + void** aHandle, + int aChannelId, + double aLowerLimit, + double aUpperLimit, + int aLowerOp, + int aUpperOp) +{ + JELOG2(ESensor); + TRAPD(err, AddConditionL(aHandle, aChannelId, + aLowerLimit, aUpperLimit, aLowerOp, aUpperOp)); + return err; +} + +void CSensorBase::AddConditionL(void** aHandle, int aChannelId, + double aLowerLimit, double aUpperLimit, int aLowerOp, + int aUpperOp) +{ + JELOG2(ESensor); + CSensorConditionBase* condition; + if (aUpperOp < 0) + { + condition = new(ELeave)CSensorLimitCondition(aChannelId, + aLowerLimit, aLowerOp); + } + else + { + condition = new(ELeave)CSensorRangeCondition(aChannelId, + aLowerLimit, aUpperLimit, aLowerOp, aUpperOp); + } + CleanupStack::PushL(condition); + iConditions.AppendL(condition); + CleanupStack::Pop(); + *aHandle = condition; +} + +int CSensorBase::RemoveCondition(void* aHandle) +{ + JELOG2(ESensor); + TMethod method(TMethod::ERemoveCondition); + method.SetConditionToRemove(aHandle); + AsyncCallback(method); + return KErrNone; +} + +void CSensorBase::RemoveConditionL( + void* aHandle) +{ + JELOG2(ESensor); + CSensorConditionBase* condition = (CSensorConditionBase*) aHandle; + TInt index = iConditions.Find(condition); + if (index < KErrNone) + { + return; + } + iConditions.Remove(index); + delete condition; +} + +