Fixed seg fault on logout.
[situare] / src / gps / gpspositionprivateliblocation.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Jussi Laitinen - jussi.laitinen@ixonos.com
6
7    Situare is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License
9    version 2 as published by the Free Software Foundation.
10
11    Situare is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with Situare; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19    USA.
20 */
21
22 #include <QFile>
23 #include <QDir>
24 #include <QApplication>
25 #include <QDebug>
26 #include <QTimer>
27
28 #include "error.h"
29 #include "gpscommon.h"
30 #include "gpsposition.h"
31 #include "liblocationwrapper.h"
32
33 #include "gpspositionprivateliblocation.h"
34
35 const int POWER_SAVE_START_DELAY_MS = 1000 * 60; // 60 seconds
36
37 GPSPositionPrivate::GPSPositionPrivate(QObject *parent)
38     : QObject(parent),
39       m_liblocationWrapper(0),
40       m_initialized(false),
41       m_powerSave(false),
42       m_running(false),
43       m_updateInterval(DEFAULT_UPDATE_INTERVAL)
44 {
45     qDebug() << __PRETTY_FUNCTION__;
46
47     m_parent = static_cast<GPSPosition*>(parent);
48
49     m_delayedPowerSaveTimer = new QTimer(this);
50     m_delayedPowerSaveTimer->setInterval(POWER_SAVE_START_DELAY_MS);
51     connect(m_delayedPowerSaveTimer, SIGNAL(timeout()),
52             this, SLOT(delayedPowerSaveStart()));
53 }
54
55 void GPSPositionPrivate::delayedPowerSaveStart()
56 {
57     qDebug() << __PRETTY_FUNCTION__;
58
59     m_powerSave = true;
60     m_delayedPowerSaveTimer->stop();
61     m_liblocationWrapper->stopUpdates();
62 }
63
64 bool GPSPositionPrivate::isInitialized() const
65 {
66     qDebug() << __PRETTY_FUNCTION__;
67
68     return m_initialized;
69 }
70
71 void GPSPositionPrivate::setMode(GPSPosition::Mode mode, const QString &filePath)
72 {
73     qDebug() << __PRETTY_FUNCTION__;
74
75     Q_UNUSED(filePath);
76
77     if (m_liblocationWrapper) {
78         disconnect(m_liblocationWrapper, 0, 0, 0);
79         delete m_liblocationWrapper;
80     }
81
82     if (mode == GPSPosition::Default) {
83         m_liblocationWrapper = new LiblocationWrapper(this);
84
85         if (!m_liblocationWrapper) {
86             m_initialized = false;
87             emit m_parent->error(ErrorContext::SITUARE, SituareError::GPS_INITIALIZATION_FAILED);
88             return;
89         }
90     }
91
92     if (m_liblocationWrapper) {
93         m_initialized = true;
94         m_liblocationWrapper->init(m_updateInterval);
95
96         connect(m_liblocationWrapper, SIGNAL(locationChanged(const GeoPositionInfo &)),
97                 this, SLOT(positionUpdated(const GeoPositionInfo &)));
98         connect(m_liblocationWrapper, SIGNAL(errorMessage(const QString &)),
99                 this, SLOT(locationError(const QString &)));
100     }
101 }
102
103 void GPSPositionPrivate::setPowerSave(bool enabled)
104 {
105     qDebug() << __PRETTY_FUNCTION__;
106
107     if (isRunning()) {
108         if (enabled) {
109             m_delayedPowerSaveTimer->start();
110         } else {
111             m_powerSave = false;
112             m_delayedPowerSaveTimer->stop();
113             m_liblocationWrapper->startUpdates();
114         }
115     }
116     else {
117         m_powerSave = false;
118     }
119 }
120
121 void GPSPositionPrivate::start()
122 {
123     qDebug() << __PRETTY_FUNCTION__;
124
125     if (m_initialized && !isRunning()) {
126         m_liblocationWrapper->startUpdates();
127         m_running = true;
128     }
129
130     setPowerSave(false);
131 }
132
133 void GPSPositionPrivate::stop()
134 {
135     qDebug() << __PRETTY_FUNCTION__;
136
137     if (m_initialized && isRunning()) {
138         m_liblocationWrapper->stopUpdates();
139         m_running = false;
140     }
141 }
142
143 bool GPSPositionPrivate::isRunning() const
144 {
145     qDebug() << __PRETTY_FUNCTION__;
146
147     return m_running;
148 }
149
150 GeoCoordinate GPSPositionPrivate::lastPosition() const
151 {
152     qDebug() << __PRETTY_FUNCTION__;
153
154     GeoPositionInfo positionInfo =  m_liblocationWrapper->lastKnownPosition();
155
156     return positionInfo.coordinate();
157 }
158
159 void GPSPositionPrivate::requestLastPosition()
160 {
161     qDebug() << __PRETTY_FUNCTION__;
162
163     GeoPositionInfo positionInfo = m_liblocationWrapper->lastKnownPosition();
164
165     if (positionInfo.isValid())
166         emit m_parent->position(positionInfo.coordinate(), accuracy(positionInfo));
167 }
168
169 void GPSPositionPrivate::requestUpdate()
170 {
171     qDebug() << __PRETTY_FUNCTION__;
172
173     if (m_powerSave)
174         m_liblocationWrapper->startUpdates();
175     else
176         requestLastPosition();
177 }
178
179 void GPSPositionPrivate::positionUpdated(const GeoPositionInfo &positionInfo)
180 {
181     qDebug() << __PRETTY_FUNCTION__;
182
183     if (positionInfo.coordinate().isValid())
184         emit m_parent->position(positionInfo.coordinate(), accuracy(positionInfo));
185
186     if (m_powerSave)
187         m_liblocationWrapper->stopUpdates();
188 }
189
190 void GPSPositionPrivate::locationError(const QString &errorMessage)
191 {
192     qDebug() << __PRETTY_FUNCTION__;
193
194     Q_UNUSED(errorMessage);
195
196     emit m_parent->error(ErrorContext::SITUARE, SituareError::GPS_INITIALIZATION_FAILED);
197 }
198
199 void GPSPositionPrivate::setUpdateInterval(int interval)
200 {
201     qDebug() << __PRETTY_FUNCTION__;
202
203     if (m_updateInterval != interval) {
204         m_updateInterval = interval;
205         m_liblocationWrapper->init(m_updateInterval);
206     }
207 }
208
209 qreal GPSPositionPrivate::accuracy(const GeoPositionInfo &positionInfo)
210 {
211     qDebug() << __PRETTY_FUNCTION__;
212
213     return positionInfo.accuracy();
214 }