--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/sensor/src.s60/csensorbase.cpp Tue Apr 27 16:30:29 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 <bautils.h>
+#include <barsc.h>
+
+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;
+}
+
+