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

Side by Side Diff: content/browser/geolocation/libgps_wrapper_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
« no previous file with comments | « content/browser/geolocation/libgps_wrapper_linux.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/geolocation/libgps_wrapper_linux.h"
6
7 #include <math.h>
8 #include <dlfcn.h>
9 #include <errno.h>
10
11 #include "base/logging.h"
12 #include "base/stringprintf.h"
13 #include "content/public/common/geoposition.h"
14 #include "third_party/gpsd/release-3.1/gps.h"
15
16 COMPILE_ASSERT(GPSD_API_MAJOR_VERSION == 5, GPSD_API_version_is_not_5);
17
18 namespace content {
19 namespace {
20 const char kLibGpsName[] = "libgps.so.20";
21 } // namespace
22
23 LibGps::LibGps(void* dl_handle,
24 gps_open_fn gps_open,
25 gps_close_fn gps_close,
26 gps_read_fn gps_read)
27 : dl_handle_(dl_handle),
28 gps_open_(gps_open),
29 gps_close_(gps_close),
30 gps_read_(gps_read),
31 gps_data_(new gps_data_t),
32 is_open_(false) {
33 DCHECK(gps_open_);
34 DCHECK(gps_close_);
35 DCHECK(gps_read_);
36 }
37
38 LibGps::~LibGps() {
39 Stop();
40 if (dl_handle_) {
41 const int err = dlclose(dl_handle_);
42 DCHECK_EQ(0, err) << "Error closing dl handle: " << err;
43 }
44 }
45
46 LibGps* LibGps::New() {
47 void* dl_handle = dlopen(kLibGpsName, RTLD_LAZY);
48 if (!dl_handle) {
49 DLOG(WARNING) << "Could not open " << kLibGpsName << ": " << dlerror();
50 return NULL;
51 }
52
53 DLOG(INFO) << "Loaded " << kLibGpsName;
54
55 #define DECLARE_FN_POINTER(function) \
56 function##_fn function = reinterpret_cast<function##_fn>( \
57 dlsym(dl_handle, #function)); \
58 if (!function) { \
59 DLOG(WARNING) << "libgps " << #function << " error: " << dlerror(); \
60 dlclose(dl_handle); \
61 return NULL; \
62 }
63 DECLARE_FN_POINTER(gps_open);
64 DECLARE_FN_POINTER(gps_close);
65 DECLARE_FN_POINTER(gps_read);
66 // We don't use gps_shm_read() directly, just to make sure that libgps has
67 // the shared memory support.
68 typedef int (*gps_shm_read_fn)(struct gps_data_t*);
69 DECLARE_FN_POINTER(gps_shm_read);
70 #undef DECLARE_FN_POINTER
71
72 return new LibGps(dl_handle, gps_open, gps_close, gps_read);
73 }
74
75 bool LibGps::Start() {
76 if (is_open_)
77 return true;
78
79 #if defined(OS_CHROMEOS)
80 errno = 0;
81 if (gps_open_(GPSD_SHARED_MEMORY, 0, gps_data_.get()) != 0) {
82 // See gps.h NL_NOxxx for definition of gps_open() error numbers.
83 DLOG(WARNING) << "gps_open() failed " << errno;
84 return false;
85 } else {
86 is_open_ = true;
87 return true;
88 }
89 #else // drop the support for desktop linux for now
90 DLOG(WARNING) << "LibGps is only supported on ChromeOS";
91 return false;
92 #endif
93 }
94 void LibGps::Stop() {
95 if (is_open_)
96 gps_close_(gps_data_.get());
97 is_open_ = false;
98 }
99
100 bool LibGps::Read(Geoposition* position) {
101 DCHECK(position);
102 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
103 if (!is_open_) {
104 DLOG(WARNING) << "No gpsd connection";
105 position->error_message = "No gpsd connection";
106 return false;
107 }
108
109 if (gps_read_(gps_data_.get()) < 0) {
110 DLOG(WARNING) << "gps_read() fails";
111 position->error_message = "gps_read() fails";
112 return false;
113 }
114
115 if (!GetPositionIfFixed(position)) {
116 DLOG(WARNING) << "No fixed position";
117 position->error_message = "No fixed position";
118 return false;
119 }
120
121 position->error_code = Geoposition::ERROR_CODE_NONE;
122 position->timestamp = base::Time::Now();
123 if (!position->Validate()) {
124 // GetPositionIfFixed returned true, yet we've not got a valid fix.
125 // This shouldn't happen; something went wrong in the conversion.
126 NOTREACHED() << "Invalid position from GetPositionIfFixed: lat,long "
127 << position->latitude << "," << position->longitude
128 << " accuracy " << position->accuracy << " time "
129 << position->timestamp.ToDoubleT();
130 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
131 position->error_message = "Bad fix from gps";
132 return false;
133 }
134 return true;
135 }
136
137 bool LibGps::GetPositionIfFixed(Geoposition* position) {
138 DCHECK(position);
139 if (gps_data_->status == STATUS_NO_FIX) {
140 DVLOG(2) << "Status_NO_FIX";
141 return false;
142 }
143
144 if (isnan(gps_data_->fix.latitude) || isnan(gps_data_->fix.longitude)) {
145 DVLOG(2) << "No valid lat/lon value";
146 return false;
147 }
148
149 position->latitude = gps_data_->fix.latitude;
150 position->longitude = gps_data_->fix.longitude;
151
152 if (!isnan(gps_data_->fix.epx) && !isnan(gps_data_->fix.epy)) {
153 position->accuracy = std::max(gps_data_->fix.epx, gps_data_->fix.epy);
154 } else if (isnan(gps_data_->fix.epx) && !isnan(gps_data_->fix.epy)) {
155 position->accuracy = gps_data_->fix.epy;
156 } else if (!isnan(gps_data_->fix.epx) && isnan(gps_data_->fix.epy)) {
157 position->accuracy = gps_data_->fix.epx;
158 } else {
159 // TODO(joth): Fixme. This is a workaround for http://crbug.com/99326
160 DVLOG(2) << "libgps reported accuracy NaN, forcing to zero";
161 position->accuracy = 0;
162 }
163
164 if (gps_data_->fix.mode == MODE_3D && !isnan(gps_data_->fix.altitude)) {
165 position->altitude = gps_data_->fix.altitude;
166 if (!isnan(gps_data_->fix.epv))
167 position->altitude_accuracy = gps_data_->fix.epv;
168 }
169
170 if (!isnan(gps_data_->fix.track))
171 position->heading = gps_data_->fix.track;
172 if (!isnan(gps_data_->fix.speed))
173 position->speed = gps_data_->fix.speed;
174 return true;
175 }
176
177 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/geolocation/libgps_wrapper_linux.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698