javaextensions/sensor/src.s60/cpssensorbase.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Base class for Publish & Subscripe -type Sensors
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "sensorlistener.h"
       
    20 #include "cpssensorbase.h"
       
    21 #include "logger.h"
       
    22 
       
    23 const TInt KPSSensorChannel = 0;
       
    24 const TInt KPSSensorInvalidValue = 0;
       
    25 
       
    26 CPSSensorBase::CPSSensorBase(TTimeIntervalMicroSeconds32 aPollInterval)
       
    27         : iPollInterval(aPollInterval)
       
    28 {
       
    29     JELOG2(ESensor);
       
    30 }
       
    31 
       
    32 CPSSensorBase::~CPSSensorBase()
       
    33 {
       
    34     JELOG2(ESensor);
       
    35     iProperty.Close();
       
    36     if (iAsyncQuery)
       
    37     {
       
    38         iAsyncQuery->Cancel();
       
    39         delete iAsyncQuery;
       
    40     }
       
    41     if (iPollTimer)
       
    42     {
       
    43         iPollTimer->Cancel();
       
    44         delete iPollTimer;
       
    45     }
       
    46 }
       
    47 
       
    48 void CPSSensorBase::ConstructL(TUid aPropertyCategory, TInt aPropertyKey)
       
    49 {
       
    50     JELOG2(ESensor);
       
    51     iPropertyCategory = aPropertyCategory;
       
    52     iPropertyKey = aPropertyKey;
       
    53     CSensorBase::ConstructL();
       
    54 }
       
    55 
       
    56 int CPSSensorBase::OpenChannel(SensorListener* aListener)
       
    57 {
       
    58     JELOG2(ESensor);
       
    59     TRAPD(err, OpenChannelL(aListener));
       
    60     return err;
       
    61 }
       
    62 
       
    63 void CPSSensorBase::OpenChannelL(SensorListener* aListener)
       
    64 {
       
    65     JELOG2(ESensor);
       
    66     iSensorListener = aListener;
       
    67     iPollTimer = CPSSensorDataListenTimer::NewL(*this);
       
    68     CActiveScheduler::Add(iPollTimer);
       
    69 
       
    70     iAsyncQuery = CPSSensorBaseAsyncQuery::NewL(*this, iPropertyCategory, iPropertyKey);
       
    71     CActiveScheduler::Add(iAsyncQuery);
       
    72 
       
    73     User::LeaveIfError(iProperty.Attach(iPropertyCategory, iPropertyKey));
       
    74 }
       
    75 
       
    76 void CPSSensorBase::StartDataListeningL()
       
    77 {
       
    78     JELOG2(ESensor);
       
    79     if (iPollTimer->IsActive())
       
    80     {
       
    81         iPollTimer->Cancel();
       
    82     }
       
    83     ResetAccumulationData();
       
    84     AccumulateDataL();
       
    85 }
       
    86 
       
    87 void CPSSensorBase::CancelDataListeningL()
       
    88 {
       
    89     JELOG2(ESensor);
       
    90     iPollTimer->Cancel();
       
    91 }
       
    92 
       
    93 void CPSSensorBase::CloseChannelL()
       
    94 {
       
    95     JELOG2(ESensor);
       
    96     iSensorListener = NULL;
       
    97 }
       
    98 
       
    99 void CPSSensorBase::StartConditionListeningL()
       
   100 {
       
   101     JELOG2(ESensor);
       
   102     // Evaluate current value right away to check if the current
       
   103     // value already matches
       
   104     PropertyValueChanged();
       
   105 
       
   106     // Request notification of property value change
       
   107     iAsyncQuery->NotifyOnChange();
       
   108 }
       
   109 
       
   110 void CPSSensorBase::StopConditionListeningL()
       
   111 {
       
   112     JELOG2(ESensor);
       
   113     iAsyncQuery->Cancel();
       
   114 }
       
   115 
       
   116 TBool CPSSensorBase::EvaluateConditions(TInt aValue, TInt aChannelId)
       
   117 {
       
   118     JELOG2(ESensor);
       
   119     // Values below zero are error codes; no condition listening callbacks
       
   120     // for invalid values.
       
   121     if (aValue < 0)
       
   122     {
       
   123         return EFalse;
       
   124     }
       
   125     return CSensorBase::EvaluateConditions(aValue, aChannelId);
       
   126 }
       
   127 
       
   128 
       
   129 void CPSSensorBase::AddConditionL(void** aHandle, int aChannelId,
       
   130                                   double aLowerLimit, double aUpperLimit, int aLowerOp,
       
   131                                   int aUpperOp)
       
   132 {
       
   133     JELOG2(ESensor);
       
   134     CSensorBase::AddConditionL(aHandle, aChannelId, aLowerLimit,
       
   135                                aUpperLimit, aLowerOp, aUpperOp);
       
   136 
       
   137     // Check conditions right away for current value
       
   138     PropertyValueChanged();
       
   139 }
       
   140 
       
   141 void CPSSensorBase::ResetAccumulationData()
       
   142 {
       
   143     JELOG2(ESensor);
       
   144     iData[ KPSSensorChannel ]->iNumOfValues = 0;
       
   145     iStartTime = KErrNotFound;
       
   146 }
       
   147 
       
   148 void CPSSensorBase::AccumulateDataL()
       
   149 {
       
   150     JELOG2(ESensor);
       
   151     __ASSERT_DEBUG(iData != NULL, User::Invariant());
       
   152     SensorData* data = iData[ KPSSensorChannel ];
       
   153 
       
   154     // Request new data accumulation event
       
   155     iPollTimer->After(iPollInterval);
       
   156 
       
   157     TTime currentTime;
       
   158     if (data->iTimeStampsIncluded || (iBufferingPeriod > 0))
       
   159     {
       
   160         currentTime.UniversalTime();
       
   161         if (iStartTime == KErrNotFound)
       
   162         {
       
   163             iStartTime = currentTime;
       
   164         }
       
   165     }
       
   166 
       
   167     TInt currentValue = 0;
       
   168     TInt err = iProperty.Get(currentValue);
       
   169     __ASSERT_DEBUG(err == KErrNone, User::Invariant());
       
   170 
       
   171     // P&S sensors are assumed to have one channel only
       
   172     TInt interpretedValue = InterpretValue(currentValue);
       
   173 
       
   174     // Negative values are error codes and therefore marked
       
   175     // as invalid. Returned value for invalid values is zero.
       
   176     if (interpretedValue < 0)
       
   177     {
       
   178         data->iIntValues[ data->iNumOfValues ] = KPSSensorInvalidValue;
       
   179         if (data->iValiditiesIncluded)
       
   180         {
       
   181             data->iValidities[ data->iNumOfValues ] = EFalse;
       
   182         }
       
   183     }
       
   184     else
       
   185     {
       
   186         data->iIntValues[ data->iNumOfValues ] = interpretedValue;
       
   187         if (data->iValiditiesIncluded)
       
   188         {
       
   189             data->iValidities[ data->iNumOfValues ] = ETrue;
       
   190         }
       
   191     }
       
   192 
       
   193     if (data->iTimeStampsIncluded)
       
   194     {
       
   195         data->iTimeStamps[ data->iNumOfValues ] = TimeStamp(currentTime);
       
   196     }
       
   197     data->iNumOfValues++;
       
   198 
       
   199     TInt64 intervalFromStart = -1;
       
   200     if (iBufferingPeriod > 0)
       
   201     {
       
   202         intervalFromStart = currentTime.MicroSecondsFrom(iStartTime).Int64();
       
   203     }
       
   204 
       
   205     if ((data->iNumOfValues == iBufferSize) ||
       
   206             (iBufferingPeriod > 0 && intervalFromStart > iBufferingPeriod))
       
   207     {
       
   208         SendData();
       
   209     }
       
   210 }
       
   211 
       
   212 void CPSSensorBase::SendData()
       
   213 {
       
   214     JELOG2(ESensor);
       
   215     if (iIsOneShot)
       
   216     {
       
   217         iPollTimer->Cancel();
       
   218     }
       
   219     iSensorListener->DataReceived(iData, EFalse);
       
   220     ResetAccumulationData();
       
   221 }
       
   222 
       
   223 void CPSSensorBase::PropertyValueChanged()
       
   224 {
       
   225     JELOG2(ESensor);
       
   226     TInt value;
       
   227     TInt err = iProperty.Get(value);
       
   228     __ASSERT_DEBUG(err == KErrNone, User::Invariant());
       
   229 
       
   230     // Negative values are sensor value range
       
   231     if (err == KErrNone && value >= 0)
       
   232     {
       
   233         EvaluateConditions(value, KPSSensorChannel);
       
   234     }
       
   235 }
       
   236 
       
   237 // ***************************************************************************
       
   238 // CPSSensorBaseAsyncQuery
       
   239 // ***************************************************************************
       
   240 
       
   241 CPSSensorBase::CPSSensorBaseAsyncQuery*
       
   242 CPSSensorBase::CPSSensorBaseAsyncQuery::NewL(CPSSensorBase& aSensorBase,
       
   243         TUid aPropertyCategory, TInt aPropertyKey)
       
   244 {
       
   245     JELOG2(ESensor);
       
   246     CPSSensorBaseAsyncQuery* self =
       
   247         new(ELeave)CPSSensorBaseAsyncQuery(aSensorBase);
       
   248     CleanupStack::PushL(self);
       
   249     self->ConstructL(aPropertyCategory, aPropertyKey);
       
   250     CleanupStack::Pop(); // self
       
   251     return self;
       
   252 }
       
   253 
       
   254 CPSSensorBase::CPSSensorBaseAsyncQuery::CPSSensorBaseAsyncQuery(CPSSensorBase& aSensorBase)
       
   255         : CActive(EPriorityStandard), iSensorBase(aSensorBase)
       
   256 {
       
   257     JELOG2(ESensor);
       
   258 }
       
   259 
       
   260 void CPSSensorBase::CPSSensorBaseAsyncQuery::ConstructL(TUid aPropertyCategory, TInt aPropertyKey)
       
   261 {
       
   262     JELOG2(ESensor);
       
   263     User::LeaveIfError(iProperty.Attach(aPropertyCategory, aPropertyKey));
       
   264 }
       
   265 
       
   266 CPSSensorBase::CPSSensorBaseAsyncQuery::~CPSSensorBaseAsyncQuery()
       
   267 {
       
   268     JELOG2(ESensor);
       
   269     iProperty.Close();
       
   270 }
       
   271 
       
   272 void CPSSensorBase::CPSSensorBaseAsyncQuery::NotifyOnChange()
       
   273 {
       
   274     JELOG2(ESensor);
       
   275     if (!IsActive())
       
   276     {
       
   277         iProperty.Subscribe(iStatus);
       
   278         SetActive();
       
   279     }
       
   280 }
       
   281 
       
   282 void CPSSensorBase::CPSSensorBaseAsyncQuery::RunL()
       
   283 {
       
   284     JELOG2(ESensor);
       
   285     iProperty.Subscribe(iStatus);
       
   286     SetActive();
       
   287     iSensorBase.PropertyValueChanged();
       
   288 }
       
   289 
       
   290 void CPSSensorBase::CPSSensorBaseAsyncQuery::DoCancel()
       
   291 {
       
   292     JELOG2(ESensor);
       
   293     iProperty.Cancel();
       
   294 }
       
   295 
       
   296 // ***************************************************************************
       
   297 // CPSSensorDataListenTimer
       
   298 // ***************************************************************************
       
   299 
       
   300 CPSSensorBase::CPSSensorDataListenTimer*
       
   301 CPSSensorBase::CPSSensorDataListenTimer::NewL(CPSSensorBase& aSensorBase)
       
   302 {
       
   303     JELOG2(ESensor);
       
   304     CPSSensorDataListenTimer* self =
       
   305         new(ELeave)CPSSensorDataListenTimer(aSensorBase);
       
   306     CleanupStack::PushL(self);
       
   307     self->ConstructL();
       
   308     CleanupStack::Pop(); // self
       
   309     return self;
       
   310 }
       
   311 
       
   312 CPSSensorBase::CPSSensorDataListenTimer::CPSSensorDataListenTimer(
       
   313     CPSSensorBase& aSensorBase)
       
   314         : CTimer(EPriorityNormal), iSensorBase(aSensorBase)
       
   315 {
       
   316     JELOG2(ESensor);
       
   317 }
       
   318 
       
   319 CPSSensorBase::CPSSensorDataListenTimer::~CPSSensorDataListenTimer()
       
   320 {
       
   321     JELOG2(ESensor);
       
   322 }
       
   323 
       
   324 void CPSSensorBase::CPSSensorDataListenTimer::RunL()
       
   325 {
       
   326     JELOG2(ESensor);
       
   327     iSensorBase.AccumulateDataL();
       
   328 }
       
   329 
       
   330 void CPSSensorBase::CPSSensorDataListenTimer::DoCancel()
       
   331 {
       
   332     JELOG2(ESensor);
       
   333 }