|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 // Internal Includes |
|
42 #include "sensorbackendsym.h" |
|
43 |
|
44 // Constants |
|
45 const TInt KDesiredReadingCount = 1; |
|
46 const TInt KMaximumReadingCount = 1; |
|
47 const TInt KDefaultBufferingPeriod = 0; |
|
48 |
|
49 ///// Internal Functions |
|
50 |
|
51 /* |
|
52 * FindSensorL is used to find if a specific sensor is available on the |
|
53 * device, if FindSensorL leaves then the sensor is not supported |
|
54 */ |
|
55 void CSensorBackendSym::FindSensorL() |
|
56 { |
|
57 // This method scans the device for the availability |
|
58 // of specified sensor using Sensor APIs |
|
59 CSensrvChannelFinder* finder = CSensrvChannelFinder::NewLC(); |
|
60 RSensrvChannelInfoList channelList; |
|
61 TSensrvChannelInfo channelInfo; |
|
62 // Retrieve the list of channels available |
|
63 finder->FindChannelsL( channelList, channelInfo ); |
|
64 CleanupStack::PopAndDestroy(finder); |
|
65 // Iterate the channel list and look for required sensor |
|
66 for (TInt i = 0; i<channelList.Count(); i++) |
|
67 { |
|
68 // Iterate the available channels |
|
69 if (channelList[i].iChannelType == iBackendData.iSensorType) |
|
70 { |
|
71 // Required sensor found |
|
72 iBackendData.iChannelInfo = channelList[i]; |
|
73 channelList.Close(); |
|
74 return; |
|
75 } |
|
76 } |
|
77 // Required sensor not found, leave with error |
|
78 channelList.Close(); |
|
79 iBackendData.iSensorAvailable = EFalse; |
|
80 User::Leave(KErrNotFound); |
|
81 } |
|
82 |
|
83 /* |
|
84 * OpenSensorChannelL is used to open the channel for sensor as indicated by |
|
85 * iPrivateData.iChannelInfo |
|
86 */ |
|
87 void CSensorBackendSym::OpenSensorChannelL() |
|
88 { |
|
89 // Search if sensor is available on the phone |
|
90 FindSensorL(); |
|
91 // Required sensor found |
|
92 if( !(iBackendData.iSensorChannel) ) |
|
93 { |
|
94 // Create and Open the Sensor channel |
|
95 iBackendData.iSensorChannel = CSensrvChannel::NewL( iBackendData.iChannelInfo ); |
|
96 // Open the channel for sensor |
|
97 iBackendData.iSensorChannel->OpenChannelL(); |
|
98 iBackendData.iReadingLock.CreateLocal(); |
|
99 iBackendData.iSensorAvailable = ETrue; |
|
100 } |
|
101 else |
|
102 { |
|
103 User::Leave(KErrAlreadyExists); |
|
104 } |
|
105 } |
|
106 |
|
107 /* |
|
108 * CloseSensorChannel is used to close the sensor channel and release the |
|
109 * resources |
|
110 */ |
|
111 void CSensorBackendSym::CloseSensorChannelL() |
|
112 { |
|
113 // If the sensor channel is not created nothing to delete |
|
114 if( iBackendData.iSensorChannel ) |
|
115 { |
|
116 // Stop listening before closing the channel |
|
117 iBackendData.iSensorAvailable = EFalse; |
|
118 StopListeningL(); |
|
119 // Close the channel |
|
120 User::LeaveIfError(iBackendData.iSensorChannel->CloseChannel()); |
|
121 iBackendData.iReadingLock.Close(); |
|
122 // If close is successful, destroy iSensorChannel |
|
123 delete iBackendData.iSensorChannel; |
|
124 iBackendData.iSensorChannel = NULL; |
|
125 } |
|
126 User::Leave( KErrNotFound ); |
|
127 } |
|
128 |
|
129 /* |
|
130 * Used to start listening to the sensor |
|
131 */ |
|
132 void CSensorBackendSym::StartListeningL() |
|
133 { |
|
134 // Check if data listening is enabled |
|
135 if(iBackendData.iDataListening) |
|
136 { |
|
137 // Start timer if required i.e. if update interval is more than zero |
|
138 TInt interval = sensor()->updateInterval(); |
|
139 if( interval > 0 ) |
|
140 { |
|
141 iBackendData.iTimerId = startTimer(interval); |
|
142 } |
|
143 // Start listening to the sensor |
|
144 // Before calling this api the channel should be found and opened |
|
145 iBackendData.iSensorChannel->StartDataListeningL( this, |
|
146 KDesiredReadingCount, |
|
147 KMaximumReadingCount, |
|
148 KDefaultBufferingPeriod ); |
|
149 } |
|
150 // start property listening if required |
|
151 if ( iBackendData.iPropertyListening ) |
|
152 { |
|
153 iBackendData.iSensorChannel->SetPropertyListenerL(this); |
|
154 } |
|
155 } |
|
156 |
|
157 /* |
|
158 * timerEvent is called when timer expires, this is used for supporting time based |
|
159 * sensor update policies |
|
160 */ |
|
161 void CSensorBackendSym::timerEvent(QTimerEvent* /*aTimerEvent*/) |
|
162 { |
|
163 // Called upon timer expiry |
|
164 //Use synchronization mechanism and emit the reading value |
|
165 iBackendData.iReadingLock.Wait(); |
|
166 newReadingAvailable(); |
|
167 iBackendData.iReadingLock.Signal(); |
|
168 } |
|
169 |
|
170 /* |
|
171 * Used to stop listening to the sensor |
|
172 */ |
|
173 void CSensorBackendSym::StopListeningL() |
|
174 { |
|
175 if(iBackendData.iPropertyListening) |
|
176 { |
|
177 //Stop Property listening |
|
178 iBackendData.iSensorChannel->SetPropertyListenerL(NULL); |
|
179 } |
|
180 if(iBackendData.iDataListening) |
|
181 { |
|
182 // If timer is being used, stop the timer |
|
183 if (iBackendData.iTimerId) |
|
184 { |
|
185 killTimer(iBackendData.iTimerId); |
|
186 iBackendData.iTimerId = 0; |
|
187 } |
|
188 // Stop listening to the sensor channel |
|
189 User::LeaveIfError(iBackendData.iSensorChannel->StopDataListening()); |
|
190 } |
|
191 } |
|
192 |
|
193 /* |
|
194 * Default C++ constructor |
|
195 */ |
|
196 CSensorBackendSym::CSensorBackendSym(QSensor *sensor):QSensorBackend(sensor) |
|
197 { |
|
198 // By default enabling Data listening |
|
199 iBackendData.iDataListening = ETrue; |
|
200 // By default disabling Property listening |
|
201 iBackendData.iPropertyListening = EFalse; |
|
202 } |
|
203 |
|
204 /* |
|
205 * Backend Destructor |
|
206 */ |
|
207 CSensorBackendSym::~CSensorBackendSym() |
|
208 { |
|
209 // No Implementation |
|
210 } |
|
211 |
|
212 /* |
|
213 * InitializeL is used to create and init the sensor server objects |
|
214 */ |
|
215 void CSensorBackendSym::InitializeL() |
|
216 { |
|
217 // Initialize Symbian Sensor Framework Objects |
|
218 OpenSensorChannelL(); |
|
219 } |
|
220 |
|
221 /* |
|
222 * Close is used to release all the sensor server objects |
|
223 * May change when error handling is supported by mobility apis |
|
224 */ |
|
225 TInt CSensorBackendSym::Close() |
|
226 { |
|
227 // Close Symbian Sensor Framework objects |
|
228 TRAPD(err,CloseSensorChannelL()); |
|
229 return err; |
|
230 } |
|
231 |
|
232 |
|
233 ///// Derived From QSensorBackend |
|
234 |
|
235 /** |
|
236 * start is used to start listening to the sensor |
|
237 */ |
|
238 void CSensorBackendSym::start() |
|
239 { |
|
240 // Start listening to sensor, after this call DataRecieved will be called |
|
241 // when data is available |
|
242 TRAPD(err,StartListeningL()) |
|
243 if( err != KErrNone ) |
|
244 { |
|
245 sensorStopped(); |
|
246 sensorError(err); |
|
247 } |
|
248 } |
|
249 |
|
250 /* |
|
251 * stop is used to stop listening to the sensor |
|
252 */ |
|
253 void CSensorBackendSym::stop() |
|
254 { |
|
255 // Stop listening to sensor, after this call DataRecieved wont be called |
|
256 TRAPD(err,StopListeningL()) |
|
257 if ( err != KErrNone ) |
|
258 { |
|
259 sensorError(err); |
|
260 } |
|
261 } |
|
262 |
|
263 //Derived From MSensrvDataListener |
|
264 |
|
265 /* |
|
266 * DataReceived is called by the Sensor Server when ever data is available in the |
|
267 * sensor buffer |
|
268 */ |
|
269 void CSensorBackendSym::DataReceived(CSensrvChannel &aChannel, TInt /*aCount*/, TInt /*aDataLost*/) |
|
270 { |
|
271 // Retrieve the data from sensor buffer |
|
272 RecvData(aChannel); |
|
273 // Notify only if no timer present |
|
274 if( !iBackendData.iTimerId ) |
|
275 { |
|
276 newReadingAvailable(); |
|
277 } |
|
278 } |
|
279 |
|
280 /** |
|
281 * DataError is called to indicate an error, fatal errors are inrecoverable |
|
282 */ |
|
283 void CSensorBackendSym::DataError(CSensrvChannel& /*aChannel*/, TSensrvErrorSeverity aError) |
|
284 { |
|
285 // If error is fatal stop the sensor |
|
286 if( aError == ESensrvErrorSeverityFatal ) |
|
287 { |
|
288 sensorStopped(); |
|
289 } |
|
290 sensorError(KErrGeneral); |
|
291 } |
|
292 |
|
293 /* |
|
294 * GetDataListenerInterfaceL is used to get a pointer to the sensor server backend |
|
295 * It is not required for QT Mobility Sensors API |
|
296 */ |
|
297 void CSensorBackendSym::CSensorBackendSym::GetDataListenerInterfaceL (TUid /*aInterfaceUid*/, TAny*&/*aInterface*/) |
|
298 { |
|
299 // No implementation required |
|
300 } |
|
301 |
|
302 // From MSensrvProeprtyListener |
|
303 |
|
304 /** |
|
305 * Notification about the changed value of a property. |
|
306 */ |
|
307 void CSensorBackendSym::PropertyChanged(CSensrvChannel &aChannel, const TSensrvProperty &aChangedProperty) |
|
308 { |
|
309 TRAP_IGNORE(HandlePropertyChange(aChannel,aChangedProperty)) |
|
310 } |
|
311 |
|
312 /** |
|
313 * Property listening failed. |
|
314 */ |
|
315 void CSensorBackendSym::PropertyError(CSensrvChannel &/*aChannel*/, TSensrvErrorSeverity aError) |
|
316 { |
|
317 if( aError == ESensrvErrorSeverityFatal ) |
|
318 { |
|
319 sensorStopped(); |
|
320 } |
|
321 sensorError(KErrGeneral); |
|
322 } |
|
323 |
|
324 /** |
|
325 * Set a listener for the indication, if the setting of the property succeeded. |
|
326 */ |
|
327 void CSensorBackendSym::SetPropertySuccessIndicationChanged(TSetPropertySuccessIndicator /*aIndication*/) |
|
328 { |
|
329 // No implementation required |
|
330 } |
|
331 |
|
332 /* |
|
333 * Returns a pointer to a specified interface extension - to allow future extension of this class without breaking binary compatibility. |
|
334 */ |
|
335 void CSensorBackendSym::GetPropertyListenerInterfaceL (TUid /*aInterfaceUid*/, TAny *&/*aInterface*/) |
|
336 { |
|
337 // No implementation required |
|
338 } |
|
339 |
|
340 void CSensorBackendSym::SetListening(TBool aDataListening, TBool aPropertyListening) |
|
341 { |
|
342 iBackendData.iDataListening = aDataListening; |
|
343 iBackendData.iPropertyListening = aPropertyListening; |
|
344 } |
|
345 |
|
346 /** |
|
347 * Deriving class implements this if it requires property change notification |
|
348 */ |
|
349 void CSensorBackendSym::HandlePropertyChange(CSensrvChannel &/*aChannel*/, const TSensrvProperty &/*aChangedProperty*/) |
|
350 { |
|
351 // No implementation required in this class |
|
352 } |
|
353 |