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

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

Issue 11571036: Linux: use generated library loader for libgps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more fixlets Created 8 years 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/geolocation/gps_location_provider_linux.h" 5 #include "content/browser/geolocation/gps_location_provider_linux.h"
6 6
7 #include <dlfcn.h>
8 #include <errno.h> 7 #include <errno.h>
9 8
10 #include <algorithm> 9 #include <algorithm>
11 #include <cmath> 10 #include <cmath>
12 11
13 #include "base/bind.h" 12 #include "base/bind.h"
14 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
15 #include "base/logging.h" 14 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
17 #include "base/message_loop.h" 16 #include "base/message_loop.h"
18 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
19 #include "content/public/common/geoposition.h" 18 #include "content/public/common/geoposition.h"
20 19
21 #if defined(USE_LIBGPS)
22 #include "third_party/gpsd/release-3.1/gps.h"
23 #endif // defined(USE_LIBGPS)
24
25 namespace content { 20 namespace content {
26 namespace { 21 namespace {
27 22
28 const int kGpsdReconnectRetryIntervalMillis = 10 * 1000; 23 const int kGpsdReconnectRetryIntervalMillis = 10 * 1000;
29 24
30 // As per http://gpsd.berlios.de/performance.html#id374524, poll twice per sec. 25 // As per http://gpsd.berlios.de/performance.html#id374524, poll twice per sec.
31 const int kPollPeriodMovingMillis = 500; 26 const int kPollPeriodMovingMillis = 500;
32 27
33 // Poll less frequently whilst stationary. 28 // Poll less frequently whilst stationary.
34 const int kPollPeriodStationaryMillis = kPollPeriodMovingMillis * 3; 29 const int kPollPeriodStationaryMillis = kPollPeriodMovingMillis * 3;
(...skipping 29 matching lines...) Expand all
64 59
65 // See http://crbug.com/103751. 60 // See http://crbug.com/103751.
66 COMPILE_ASSERT(GPSD_API_MAJOR_VERSION == 5, GPSD_API_version_is_not_5); 61 COMPILE_ASSERT(GPSD_API_MAJOR_VERSION == 5, GPSD_API_version_is_not_5);
67 62
68 namespace { 63 namespace {
69 64
70 const char kLibGpsName[] = "libgps.so.20"; 65 const char kLibGpsName[] = "libgps.so.20";
71 66
72 } // namespace 67 } // namespace
73 68
74 LibGps::LibGps(void* dl_handle, 69 LibGps::LibGps()
75 gps_open_fn gps_open, 70 : gps_data_(new gps_data_t),
76 gps_close_fn gps_close,
77 gps_read_fn gps_read)
78 : dl_handle_(dl_handle),
79 gps_open_(gps_open),
80 gps_close_(gps_close),
81 gps_read_(gps_read),
82 gps_data_(new gps_data_t),
83 is_open_(false) { 71 is_open_(false) {
84 DCHECK(gps_open_);
85 DCHECK(gps_close_);
86 DCHECK(gps_read_);
87 } 72 }
88 73
89 LibGps::~LibGps() { 74 LibGps::~LibGps() {
90 Stop(); 75 Stop();
91 if (dl_handle_) {
92 const int err = dlclose(dl_handle_);
93 DCHECK_EQ(0, err) << "Error closing dl handle: " << err;
94 }
95 } 76 }
96 77
97 LibGps* LibGps::New() { 78 LibGps* LibGps::New() {
98 void* dl_handle = dlopen(kLibGpsName, RTLD_LAZY); 79 scoped_ptr<LibGps> libgps(new LibGps);
99 if (!dl_handle) { 80 if (!libgps->libgps_loader_.Load(kLibGpsName))
100 DLOG(WARNING) << "Could not open " << kLibGpsName << ": " << dlerror();
101 return NULL; 81 return NULL;
102 }
103 82
104 DLOG(INFO) << "Loaded " << kLibGpsName; 83 return libgps.release();
105
106 #define DECLARE_FN_POINTER(function) \
107 function##_fn function = reinterpret_cast<function##_fn>( \
108 dlsym(dl_handle, #function)); \
109 if (!function) { \
110 DLOG(WARNING) << "libgps " << #function << " error: " << dlerror(); \
111 dlclose(dl_handle); \
112 return NULL; \
113 }
114 DECLARE_FN_POINTER(gps_open);
115 DECLARE_FN_POINTER(gps_close);
116 DECLARE_FN_POINTER(gps_read);
117 // We don't use gps_shm_read() directly, just to make sure that libgps has
118 // the shared memory support.
119 typedef int (*gps_shm_read_fn)(struct gps_data_t*);
120 DECLARE_FN_POINTER(gps_shm_read);
121 #undef DECLARE_FN_POINTER
122
123 return new LibGps(dl_handle, gps_open, gps_close, gps_read);
124 } 84 }
125 85
126 bool LibGps::Start() { 86 bool LibGps::Start() {
127 if (is_open_) 87 if (is_open_)
128 return true; 88 return true;
129 89
130 errno = 0; 90 errno = 0;
131 if (gps_open_(GPSD_SHARED_MEMORY, 0, gps_data_.get()) != 0) { 91 if (libgps_loader_.gps_open(GPSD_SHARED_MEMORY, 0, gps_data_.get()) != 0) {
132 // See gps.h NL_NOxxx for definition of gps_open() error numbers. 92 // See gps.h NL_NOxxx for definition of gps_open() error numbers.
133 DLOG(WARNING) << "gps_open() failed " << errno; 93 DLOG(WARNING) << "gps_open() failed " << errno;
134 return false; 94 return false;
135 } 95 }
136 96
137 is_open_ = true; 97 is_open_ = true;
138 return true; 98 return true;
139 } 99 }
140 100
141 void LibGps::Stop() { 101 void LibGps::Stop() {
142 if (is_open_) 102 if (is_open_)
143 gps_close_(gps_data_.get()); 103 libgps_loader_.gps_close(gps_data_.get());
144 is_open_ = false; 104 is_open_ = false;
145 } 105 }
146 106
147 bool LibGps::Read(Geoposition* position) { 107 bool LibGps::Read(Geoposition* position) {
148 DCHECK(position); 108 DCHECK(position);
149 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; 109 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
150 if (!is_open_) { 110 if (!is_open_) {
151 DLOG(WARNING) << "No gpsd connection"; 111 DLOG(WARNING) << "No gpsd connection";
152 position->error_message = "No gpsd connection"; 112 position->error_message = "No gpsd connection";
153 return false; 113 return false;
154 } 114 }
155 115
156 if (gps_read_(gps_data_.get()) < 0) { 116 if (libgps_loader_.gps_read(gps_data_.get()) < 0) {
157 DLOG(WARNING) << "gps_read() fails"; 117 DLOG(WARNING) << "gps_read() fails";
158 position->error_message = "gps_read() fails"; 118 position->error_message = "gps_read() fails";
159 return false; 119 return false;
160 } 120 }
161 121
162 if (!GetPositionIfFixed(position)) { 122 if (!GetPositionIfFixed(position)) {
163 DLOG(WARNING) << "No fixed position"; 123 DLOG(WARNING) << "No fixed position";
164 position->error_message = "No fixed position"; 124 position->error_message = "No fixed position";
165 return false; 125 return false;
166 } 126 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 if (!isnan(gps_data_->fix.track)) 177 if (!isnan(gps_data_->fix.track))
218 position->heading = gps_data_->fix.track; 178 position->heading = gps_data_->fix.track;
219 if (!isnan(gps_data_->fix.speed)) 179 if (!isnan(gps_data_->fix.speed))
220 position->speed = gps_data_->fix.speed; 180 position->speed = gps_data_->fix.speed;
221 return true; 181 return true;
222 } 182 }
223 183
224 #else // !defined(USE_LIBGPS) 184 #else // !defined(USE_LIBGPS)
225 185
226 // Stub implementation of LibGps. 186 // Stub implementation of LibGps.
227 LibGps::LibGps(void* dl_handle, 187 LibGps::LibGps() {
228 gps_open_fn gps_open,
229 gps_close_fn gps_close,
230 gps_read_fn gps_read) {
231 } 188 }
232 189
233 LibGps::~LibGps() { 190 LibGps::~LibGps() {
234 } 191 }
235 192
236 LibGps* LibGps::New() { 193 LibGps* LibGps::New() {
237 return NULL; 194 return NULL;
238 } 195 }
239 196
240 bool LibGps::Start() { 197 bool LibGps::Start() {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 base::Bind(&GpsLocationProviderLinux::DoGpsPollTask, 290 base::Bind(&GpsLocationProviderLinux::DoGpsPollTask,
334 weak_factory_.GetWeakPtr()), 291 weak_factory_.GetWeakPtr()),
335 base::TimeDelta::FromMilliseconds(interval)); 292 base::TimeDelta::FromMilliseconds(interval));
336 } 293 }
337 294
338 LocationProviderBase* NewSystemLocationProvider() { 295 LocationProviderBase* NewSystemLocationProvider() {
339 return new GpsLocationProviderLinux(LibGps::New); 296 return new GpsLocationProviderLinux(LibGps::New);
340 } 297 }
341 298
342 } // namespace content 299 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698