|
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 |
|
42 #include "qgeopositioninfosource_s60_p.h" |
|
43 #include "qgeosatelliteinfosource_s60_p.h" |
|
44 #include "qmlbackendao_s60_p.h" |
|
45 |
|
46 QTM_BEGIN_NAMESPACE |
|
47 |
|
48 //The name of the requestor //Added by PM |
|
49 //_LIT(KRequestor,"QTMobility Location"); |
|
50 |
|
51 // constructor |
|
52 CQMLBackendAO::CQMLBackendAO() : |
|
53 CActive(EPriorityStandard), // Standard priority |
|
54 mPosInfo(NULL), |
|
55 mRequester(NULL), |
|
56 mRequesterSatellite(NULL), |
|
57 mRequestType(RequestType(0)) |
|
58 { |
|
59 } |
|
60 |
|
61 // |
|
62 // |
|
63 // |
|
64 CQMLBackendAO* CQMLBackendAO::NewLC(QObject *aRequester, |
|
65 RequestType aRequestType, TPositionModuleId aModId) |
|
66 { |
|
67 CQMLBackendAO* self = new(ELeave) CQMLBackendAO(); |
|
68 CleanupStack::PushL(self); |
|
69 self->ConstructL(aRequester, aRequestType, aModId); |
|
70 return self; |
|
71 } |
|
72 |
|
73 // |
|
74 // |
|
75 // |
|
76 CQMLBackendAO* CQMLBackendAO::NewL(QObject *aRequester, |
|
77 RequestType aRequestType, TPositionModuleId aModId) |
|
78 { |
|
79 CQMLBackendAO* self = CQMLBackendAO::NewLC(aRequester, aRequestType, aModId); |
|
80 CleanupStack::Pop(); // self; |
|
81 return self; |
|
82 } |
|
83 |
|
84 // |
|
85 // |
|
86 // |
|
87 TInt CQMLBackendAO::ConstructL(QObject *aRequester, RequestType aRequestType, |
|
88 TPositionModuleId aModId) |
|
89 { |
|
90 TInt error = KErrNone; |
|
91 RPositionServer PosServer; |
|
92 |
|
93 if (aRequester->inherits("QGeoSatelliteInfoSource")) |
|
94 mRequesterSatellite = static_cast<CQGeoSatelliteInfoSourceS60*>(aRequester); |
|
95 else |
|
96 mRequester = static_cast<CQGeoPositionInfoSourceS60*>(aRequester); |
|
97 |
|
98 mRequestType = aRequestType; |
|
99 |
|
100 if ((mRequestType == RegularUpdate) || (mRequestType == OnceUpdate)) { |
|
101 if (aRequester->inherits("QGeoSatelliteInfoSource")) |
|
102 PosServer = mRequesterSatellite->getPositionServer(); |
|
103 else |
|
104 PosServer = mRequester->getPositionServer(); |
|
105 |
|
106 error = mPositioner.Open(PosServer, aModId); |
|
107 |
|
108 if (error != KErrNone) |
|
109 return error; |
|
110 |
|
111 CleanupClosePushL(mPositioner); |
|
112 |
|
113 error = mPositioner.SetRequestor(CRequestor::ERequestorService , |
|
114 CRequestor::EFormatApplication, _L("QTmobility_Location")); |
|
115 |
|
116 CleanupStack::Pop(1); |
|
117 |
|
118 if (error != KErrNone) |
|
119 return error; |
|
120 |
|
121 } |
|
122 |
|
123 CActiveScheduler::Add(this); // Add to scheduler |
|
124 |
|
125 return error; |
|
126 } |
|
127 |
|
128 // |
|
129 CQMLBackendAO::~CQMLBackendAO() |
|
130 { |
|
131 Cancel(); |
|
132 |
|
133 if ((mRequestType == OnceUpdate) || (mRequestType == RegularUpdate)) { |
|
134 //close the subsession |
|
135 mPositioner.Close(); |
|
136 |
|
137 if (mPosInfo) { |
|
138 mPosInfo->ClearRequestedFields(); |
|
139 |
|
140 mPosInfo->ClearPositionData(); |
|
141 //delete the HPositionGenericInfo |
|
142 delete mPosInfo; |
|
143 } |
|
144 } else if (mRequestType == DeviceStatus) { |
|
145 RPositionServer posServer; |
|
146 |
|
147 //done only by the position server Active Object |
|
148 if (mRequester) |
|
149 posServer = mRequester->getPositionServer(); |
|
150 else |
|
151 posServer = mRequesterSatellite->getPositionServer(); |
|
152 |
|
153 posServer.Close(); |
|
154 } |
|
155 } |
|
156 |
|
157 // |
|
158 void CQMLBackendAO::DoCancel() |
|
159 { |
|
160 CancelAll(); |
|
161 } |
|
162 |
|
163 |
|
164 // |
|
165 void CQMLBackendAO::RunL() |
|
166 { |
|
167 switch (mRequestType) { |
|
168 case DeviceStatus : |
|
169 handleDeviceNotification(iStatus.Int()); |
|
170 break; |
|
171 case RegularUpdate : |
|
172 case OnceUpdate: |
|
173 handlePosUpdateNotification(iStatus.Int()); |
|
174 break; |
|
175 default : |
|
176 break; |
|
177 } |
|
178 } |
|
179 |
|
180 // |
|
181 TInt CQMLBackendAO::RunError(TInt aError) |
|
182 { |
|
183 return aError; |
|
184 } |
|
185 |
|
186 |
|
187 // checks any pending request in activeobject |
|
188 bool CQMLBackendAO::isRequestPending() |
|
189 { |
|
190 if (IsActive()) |
|
191 return true; |
|
192 else |
|
193 return false; |
|
194 } |
|
195 |
|
196 |
|
197 |
|
198 // Async call to get notifications about device status. |
|
199 void CQMLBackendAO::notifyDeviceStatus(TPositionModuleStatusEventBase &aStatusEvent) |
|
200 { |
|
201 RPositionServer PosServ; |
|
202 |
|
203 if (mRequester) |
|
204 PosServ = mRequester->getPositionServer(); |
|
205 else |
|
206 PosServ = mRequesterSatellite->getPositionServer(); |
|
207 |
|
208 //register for device status events |
|
209 TPositionModuleStatusEventBase::TModuleEvent RequestedEvents( |
|
210 TPositionModuleStatusEventBase::EEventDeviceStatus); |
|
211 |
|
212 aStatusEvent.SetRequestedEvents(RequestedEvents); |
|
213 |
|
214 PosServ.NotifyModuleStatusEvent(aStatusEvent, iStatus); |
|
215 |
|
216 SetActive(); |
|
217 |
|
218 } |
|
219 |
|
220 void CQMLBackendAO::CancelAll() |
|
221 { |
|
222 |
|
223 RPositionServer PosServer; |
|
224 if (mRequestType == DeviceStatus) { |
|
225 if (mRequester) |
|
226 PosServer = mRequester->getPositionServer(); |
|
227 else |
|
228 PosServer = mRequesterSatellite->getPositionServer(); |
|
229 |
|
230 PosServer.CancelRequest(EPositionServerNotifyModuleStatusEvent); |
|
231 } else if ((mRequestType == OnceUpdate) || (mRequestType == RegularUpdate)) { |
|
232 mPositioner.CancelRequest(EPositionerNotifyPositionUpdate); |
|
233 } |
|
234 |
|
235 } |
|
236 |
|
237 //Initialize the posInfo with appropriate fields |
|
238 bool CQMLBackendAO::initializePosInfo() |
|
239 { |
|
240 if (!mPosInfo) { |
|
241 mPosInfo = HPositionGenericInfo::New(); |
|
242 |
|
243 if (mPosInfo == NULL) |
|
244 return FALSE; |
|
245 } else { |
|
246 mPosInfo->ClearRequestedFields(); |
|
247 |
|
248 mPosInfo->ClearPositionData(); |
|
249 } |
|
250 RPositionServer posServer; |
|
251 TPositionModuleInfo moduleInfo; |
|
252 TInt error = KErrNone; |
|
253 |
|
254 //get the posiiton server |
|
255 posServer = mRequester->getPositionServer(); |
|
256 |
|
257 //retrieve the module id used by the posiitoner |
|
258 if (mRequestType == RegularUpdate) |
|
259 error = posServer.GetModuleInfoById(mRequester->getCurrentPositonModuleID(), moduleInfo); |
|
260 else |
|
261 error = posServer.GetModuleInfoById(mRequester->getRequestUpdateModuleID(), moduleInfo); |
|
262 |
|
263 if (error == KErrNone) { |
|
264 |
|
265 //get capabilities of the module |
|
266 TPositionModuleInfo::TCapabilities caps = moduleInfo.Capabilities(); |
|
267 |
|
268 if (caps & TPositionModuleInfo::ECapabilitySatellite) { |
|
269 mPosInfo->SetRequestedField(EPositionFieldSatelliteNumInView); |
|
270 mPosInfo->SetRequestedField(EPositionFieldSatelliteNumUsed); |
|
271 } |
|
272 |
|
273 if (caps & TPositionModuleInfo::ECapabilitySpeed) { |
|
274 mPosInfo->SetRequestedField(EPositionFieldHorizontalSpeed); |
|
275 mPosInfo->SetRequestedField(EPositionFieldVerticalSpeed); |
|
276 } |
|
277 if (caps & TPositionModuleInfo::ECapabilityCompass) { |
|
278 mPosInfo->SetRequestedField(EPositionFieldMagneticCourseError); |
|
279 mPosInfo->SetRequestedField(EPositionFieldHeading); |
|
280 } |
|
281 return TRUE; |
|
282 } |
|
283 return FALSE; |
|
284 } |
|
285 |
|
286 //requestUpdate : request for position update once |
|
287 void CQMLBackendAO::requestUpdate(int aTimeout) |
|
288 { |
|
289 TPositionUpdateOptions aPosOption; |
|
290 |
|
291 mPositioner.GetUpdateOptions(aPosOption); |
|
292 |
|
293 aPosOption.SetUpdateInterval(TTimeIntervalMicroSeconds(0)); |
|
294 |
|
295 aPosOption.SetUpdateTimeOut(TTimeIntervalMicroSeconds(aTimeout * 1000)); |
|
296 |
|
297 mPositioner.SetUpdateOptions(aPosOption); |
|
298 |
|
299 startUpdates(); |
|
300 } |
|
301 |
|
302 |
|
303 // |
|
304 void CQMLBackendAO::cancelUpdate() |
|
305 { |
|
306 Cancel(); |
|
307 |
|
308 } |
|
309 |
|
310 |
|
311 // |
|
312 void CQMLBackendAO::handleDeviceNotification(int aError) |
|
313 { |
|
314 switch (aError) { |
|
315 //NotifyPositionModulestatusEvent successfully completed |
|
316 case KErrNone : |
|
317 |
|
318 //module not found |
|
319 case KErrNotFound : |
|
320 if (mRequester) |
|
321 mRequester->updateDeviceStatus(); |
|
322 else |
|
323 mRequesterSatellite->updateDeviceStatus(); |
|
324 break; |
|
325 |
|
326 //request has been successfully cancelled |
|
327 case KErrCancel : |
|
328 break; |
|
329 |
|
330 //unrecoverabe errors |
|
331 default : |
|
332 break; |
|
333 } |
|
334 } |
|
335 |
|
336 |
|
337 // |
|
338 void CQMLBackendAO::handlePosUpdateNotification(int aError) |
|
339 { |
|
340 |
|
341 HPositionGenericInfo *positionInfo = NULL; |
|
342 |
|
343 TPositionSatelliteInfo satInfo; |
|
344 switch (aError) { |
|
345 //NotifyPositionUpdate successfully completed |
|
346 case KErrNone : |
|
347 |
|
348 //Posiiton Module is unable to return any position information |
|
349 case KPositionQualityLoss : |
|
350 |
|
351 //requested information could not be retrieved within the maximum peroid |
|
352 case KErrTimedOut: |
|
353 |
|
354 |
|
355 |
|
356 if (mRequester) { |
|
357 positionInfo = HPositionGenericInfo::New(); |
|
358 |
|
359 if (positionInfo == NULL) |
|
360 return; |
|
361 |
|
362 //copy the buffer contents into a new HPositionGenericInfo buffer,to be used |
|
363 //for creating QGeoPositionInfo object later |
|
364 memcpy(positionInfo , mPosInfo , mPosInfo->BufferSize()); |
|
365 } else { |
|
366 satInfo = mPosSatInfo; |
|
367 } |
|
368 |
|
369 //if regUpdateAO, request for the next update |
|
370 if (mRequestType == RegularUpdate) { |
|
371 if (mRequester) { |
|
372 initializePosInfo(); |
|
373 mPositioner.NotifyPositionUpdate(*mPosInfo, iStatus); |
|
374 } else |
|
375 mPositioner.NotifyPositionUpdate(mPosSatInfo, iStatus); |
|
376 |
|
377 SetActive(); |
|
378 } |
|
379 |
|
380 if (mRequester) { |
|
381 mRequester->updatePosition(positionInfo, aError); |
|
382 delete positionInfo; |
|
383 } else { |
|
384 if ((aError != KErrTimedOut) || (mRequestType != RegularUpdate)) { |
|
385 mRequesterSatellite->updatePosition(satInfo, aError, (mRequestType == RegularUpdate)); |
|
386 } |
|
387 } |
|
388 |
|
389 break; |
|
390 |
|
391 //request was successfully cancelled |
|
392 case KErrCancel : |
|
393 break; |
|
394 |
|
395 default : |
|
396 break; |
|
397 |
|
398 } |
|
399 } |
|
400 |
|
401 ////////////////////////////////////////////////////////////// |
|
402 // Sets the interval for getting the regular notification // |
|
403 // the time interval set is in milli seconds // |
|
404 ////////////////////////////////////////////////////////////// |
|
405 int CQMLBackendAO::setUpdateInterval(int aMilliSec) |
|
406 { |
|
407 int minimumUpdateInterval = 0; |
|
408 TInt64 mUpdateInterval = 0 ; |
|
409 |
|
410 if (mRequester) |
|
411 minimumUpdateInterval = mRequester->minimumUpdateInterval(); |
|
412 else |
|
413 minimumUpdateInterval = mRequesterSatellite->minimumUpdateInterval(); |
|
414 |
|
415 if (minimumUpdateInterval < 0) |
|
416 minimumUpdateInterval = 100; |
|
417 // if the current requesttype is regular updates |
|
418 // then set the updateinterval otherwise ignore |
|
419 //if(mRequestType != REQ_REG_UPDATE) |
|
420 // return; |
|
421 |
|
422 TPositionUpdateOptions aPosOption; |
|
423 |
|
424 TInt error = mPositioner.GetUpdateOptions(aPosOption); |
|
425 |
|
426 // TTimeIntervalMicroSeconds is converted seconds |
|
427 TInt currentUpdateInterval = aPosOption.UpdateInterval().Int64() / 1000; |
|
428 |
|
429 // If msec is not 0 and is less than the value returned by minimumUpdateInterval(), |
|
430 // the interval will be set to the minimum interval. |
|
431 if (aMilliSec != 0 && aMilliSec <= minimumUpdateInterval) { |
|
432 mUpdateInterval = minimumUpdateInterval; |
|
433 } else { |
|
434 mUpdateInterval = aMilliSec; |
|
435 } |
|
436 |
|
437 // if the same value is being set then just ignore it. |
|
438 if (currentUpdateInterval == mUpdateInterval) { |
|
439 return mUpdateInterval; |
|
440 } |
|
441 |
|
442 // will set Either zero, minimum or +ve value |
|
443 // seconds converted to TTimeIntervalMicroSeconds |
|
444 aPosOption.SetUpdateInterval(TTimeIntervalMicroSeconds(mUpdateInterval * 1000)); |
|
445 |
|
446 // set the timeout to the smaller of 150% of interval or update interval + 10 seconds |
|
447 TInt64 mUpdateTimeout = (mUpdateInterval * 3) / 2; |
|
448 if (mUpdateTimeout > mUpdateInterval + 10000) |
|
449 mUpdateTimeout = mUpdateInterval + 10000; |
|
450 |
|
451 if (aMilliSec > 0) |
|
452 aPosOption.SetUpdateTimeOut(TTimeIntervalMicroSeconds(mUpdateTimeout * 1000)); |
|
453 |
|
454 error = mPositioner.SetUpdateOptions(aPosOption); |
|
455 |
|
456 return mUpdateInterval; |
|
457 } |
|
458 |
|
459 void CQMLBackendAO::startUpdates() |
|
460 { |
|
461 if (!IsActive()) { |
|
462 if (mRequester) { |
|
463 initializePosInfo(); |
|
464 mPositioner.NotifyPositionUpdate(*mPosInfo , iStatus); |
|
465 } else |
|
466 mPositioner.NotifyPositionUpdate(mPosSatInfo , iStatus); |
|
467 |
|
468 SetActive(); |
|
469 |
|
470 } |
|
471 } |
|
472 |
|
473 QTM_END_NAMESPACE |