Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(650)

Side by Side Diff: content/browser/geolocation/libgps_wrapper_linux.cc

Issue 6597044: Revert 76228 - Move core pieces of geolocation from chrome to content.This is... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/geolocation/libgps_wrapper_linux.h"
6
7 #include <dlfcn.h>
8 #include <errno.h>
9
10 #include "chrome/common/geoposition.h"
11 #include "base/logging.h"
12 #include "base/string_util.h"
13
14 namespace {
15 // Pass to TryToOpen() to indicate which functions should be wired up.
16 // This could be turned into a bit mask if required, but for now the
17 // two options are mutually exclusive.
18 enum InitMode {
19 INITMODE_QUERY,
20 INITMODE_STREAM,
21 };
22
23 // Attempts to load dynamic library named |lib| and initialize the required
24 // function pointers according to |mode|. Returns ownership a new instance
25 // of the library loader class, or NULL on failure.
26 LibGpsLibraryWrapper* TryToOpen(const char* lib, InitMode mode) {
27 void* dl_handle = dlopen(lib, RTLD_LAZY);
28 if (!dl_handle) {
29 VLOG(1) << "Could not open " << lib << ": " << dlerror();
30 return NULL;
31 }
32 VLOG(1) << "Loaded " << lib;
33
34 #define DECLARE_FN_POINTER(function, required) \
35 LibGpsLibraryWrapper::function##_fn function; \
36 function = reinterpret_cast<LibGpsLibraryWrapper::function##_fn>( \
37 dlsym(dl_handle, #function)); \
38 if ((required) && !function) { \
39 LOG(WARNING) << "libgps " << #function << " error: " << dlerror(); \
40 dlclose(dl_handle); \
41 return NULL; \
42 }
43 DECLARE_FN_POINTER(gps_open, true);
44 DECLARE_FN_POINTER(gps_close, true);
45 DECLARE_FN_POINTER(gps_poll, true);
46 DECLARE_FN_POINTER(gps_query, mode == INITMODE_QUERY);
47 DECLARE_FN_POINTER(gps_stream, mode == INITMODE_STREAM);
48 DECLARE_FN_POINTER(gps_waiting, mode == INITMODE_STREAM);
49 #undef DECLARE_FN_POINTER
50
51 return new LibGpsLibraryWrapper(dl_handle,
52 gps_open,
53 gps_close,
54 gps_poll,
55 gps_query,
56 gps_stream,
57 gps_waiting);
58 }
59 } // namespace
60
61 LibGps::LibGps(LibGpsLibraryWrapper* dl_wrapper)
62 : library_(dl_wrapper) {
63 DCHECK(dl_wrapper != NULL);
64 }
65
66 LibGps::~LibGps() {
67 }
68
69 LibGps* LibGps::New() {
70 LibGpsLibraryWrapper* wrapper;
71 wrapper = TryToOpen("libgps.so.19", INITMODE_STREAM);
72 if (wrapper)
73 return NewV294(wrapper);
74 wrapper = TryToOpen("libgps.so.17", INITMODE_QUERY);
75 if (wrapper)
76 return NewV238(wrapper);
77 wrapper = TryToOpen("libgps.so", INITMODE_STREAM);
78 if (wrapper)
79 return NewV294(wrapper);
80 return NULL;
81 }
82
83 bool LibGps::Start() {
84 if (library().is_open())
85 return true;
86 errno = 0;
87 static int fail_count = 0;
88 if (!library().open(NULL, NULL)) {
89 // See gps.h NL_NOxxx for definition of gps_open() error numbers.
90 LOG_IF(WARNING, 0 == fail_count++) << "gps_open() failed: " << errno;
91 return false;
92 }
93 fail_count = 0;
94 if (!StartStreaming()) {
95 VLOG(1) << "StartStreaming failed";
96 library().close();
97 return false;
98 }
99 return true;
100 }
101
102 void LibGps::Stop() {
103 library().close();
104 }
105
106 bool LibGps::Poll() {
107 last_error_ = "no data received from gpsd";
108 while (DataWaiting()) {
109 int error = library().poll();
110 if (error) {
111 last_error_ = StringPrintf("poll() returned %d", error);
112 Stop();
113 return false;
114 }
115 last_error_.clear();
116 }
117 return last_error_.empty();
118 }
119
120 bool LibGps::GetPosition(Geoposition* position) {
121 DCHECK(position);
122 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
123 if (!library().is_open()) {
124 position->error_message = "No gpsd connection";
125 return false;
126 }
127 if (!GetPositionIfFixed(position)) {
128 position->error_message = last_error_;
129 return false;
130 }
131 position->error_code = Geoposition::ERROR_CODE_NONE;
132 position->timestamp = base::Time::Now();
133 if (!position->IsValidFix()) {
134 // GetPositionIfFixed returned true, yet we've not got a valid fix.
135 // This shouldn't happen; something went wrong in the conversion.
136 NOTREACHED() << "Invalid position from GetPositionIfFixed: lat,long "
137 << position->latitude << "," << position->longitude
138 << " accuracy " << position->accuracy << " time "
139 << position->timestamp.ToDoubleT();
140 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
141 position->error_message = "Bad fix from gps";
142 return false;
143 }
144 return true;
145 }
146
147 LibGpsLibraryWrapper::LibGpsLibraryWrapper(void* dl_handle,
148 gps_open_fn gps_open,
149 gps_close_fn gps_close,
150 gps_poll_fn gps_poll,
151 gps_query_fn gps_query,
152 gps_stream_fn gps_stream,
153 gps_waiting_fn gps_waiting)
154 : dl_handle_(dl_handle),
155 gps_open_(gps_open),
156 gps_close_(gps_close),
157 gps_poll_(gps_poll),
158 gps_query_(gps_query),
159 gps_stream_(gps_stream),
160 gps_waiting_(gps_waiting),
161 gps_data_(NULL) {
162 }
163
164 LibGpsLibraryWrapper::~LibGpsLibraryWrapper() {
165 close();
166 if (dl_handle_) {
167 const int err = dlclose(dl_handle_);
168 CHECK_EQ(0, err) << "Error closing dl handle: " << err;
169 }
170 }
171
172 bool LibGpsLibraryWrapper::open(const char* host, const char* port) {
173 DCHECK(!gps_data_) << "libgps already opened";
174 DCHECK(gps_open_);
175 gps_data_ = gps_open_(host, port);
176 return is_open();
177 }
178
179 void LibGpsLibraryWrapper::close() {
180 if (is_open()) {
181 DCHECK(gps_close_);
182 gps_close_(gps_data_);
183 gps_data_ = NULL;
184 }
185 }
186
187 int LibGpsLibraryWrapper::poll() {
188 DCHECK(is_open());
189 DCHECK(gps_poll_);
190 return gps_poll_(gps_data_);
191 }
192
193 // This is intentionally ignoring the va_arg extension to query(): the caller
194 // can use base::StringPrintf to achieve the same effect.
195 int LibGpsLibraryWrapper::query(const char* fmt) {
196 DCHECK(is_open());
197 DCHECK(gps_query_);
198 return gps_query_(gps_data_, fmt);
199 }
200
201 int LibGpsLibraryWrapper::stream(int flags) {
202 DCHECK(is_open());
203 DCHECK(gps_stream_);
204 return gps_stream_(gps_data_, flags, NULL);
205 }
206
207 bool LibGpsLibraryWrapper::waiting() {
208 DCHECK(is_open());
209 DCHECK(gps_waiting_);
210 return gps_waiting_(gps_data_);
211 }
212
213 const gps_data_t& LibGpsLibraryWrapper::data() const {
214 DCHECK(is_open());
215 return *gps_data_;
216 }
217
218 bool LibGpsLibraryWrapper::is_open() const {
219 return gps_data_ != NULL;
220 }
OLDNEW
« no previous file with comments | « content/browser/geolocation/libgps_wrapper_linux.h ('k') | content/browser/geolocation/location_arbitrator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698