OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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/libgps_wrapper_linux.h" | 5 #include "content/browser/geolocation/libgps_wrapper_linux.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
12 #include "content/common/geoposition.h" | 12 #include "content/common/geoposition.h" |
13 | 13 |
14 namespace { | 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 | 15 // Attempts to load dynamic library named |lib| and initialize the required |
24 // function pointers according to |mode|. Returns ownership a new instance | 16 // function pointers according to |mode|. Returns ownership a new instance |
25 // of the library loader class, or NULL on failure. | 17 // of the library loader class, or NULL on failure. |
26 LibGpsLibraryWrapper* TryToOpen(const char* lib, InitMode mode) { | 18 // TODO(joth): This is a hang-over from when we dynamically two different |
| 19 // versions of libgps and chose between them. Now we could remove at least one |
| 20 // layer of wrapper class and directly #include gps.h in this cc file. |
| 21 // See http://crbug.com/98132 and http://crbug.com/99177 |
| 22 LibGpsLibraryWrapper* TryToOpen(const char* lib) { |
27 void* dl_handle = dlopen(lib, RTLD_LAZY); | 23 void* dl_handle = dlopen(lib, RTLD_LAZY); |
28 if (!dl_handle) { | 24 if (!dl_handle) { |
29 VLOG(1) << "Could not open " << lib << ": " << dlerror(); | 25 VLOG(1) << "Could not open " << lib << ": " << dlerror(); |
30 return NULL; | 26 return NULL; |
31 } | 27 } |
32 VLOG(1) << "Loaded " << lib; | 28 VLOG(1) << "Loaded " << lib; |
33 | 29 |
34 #define DECLARE_FN_POINTER(function, required) \ | 30 #define DECLARE_FN_POINTER(function) \ |
35 LibGpsLibraryWrapper::function##_fn function; \ | 31 LibGpsLibraryWrapper::function##_fn function; \ |
36 function = reinterpret_cast<LibGpsLibraryWrapper::function##_fn>( \ | 32 function = reinterpret_cast<LibGpsLibraryWrapper::function##_fn>( \ |
37 dlsym(dl_handle, #function)); \ | 33 dlsym(dl_handle, #function)); \ |
38 if ((required) && !function) { \ | 34 if (!function) { \ |
39 LOG(WARNING) << "libgps " << #function << " error: " << dlerror(); \ | 35 LOG(WARNING) << "libgps " << #function << " error: " << dlerror(); \ |
40 dlclose(dl_handle); \ | 36 dlclose(dl_handle); \ |
41 return NULL; \ | 37 return NULL; \ |
42 } | 38 } |
43 DECLARE_FN_POINTER(gps_open, true); | 39 DECLARE_FN_POINTER(gps_open); |
44 DECLARE_FN_POINTER(gps_close, true); | 40 DECLARE_FN_POINTER(gps_close); |
45 DECLARE_FN_POINTER(gps_poll, true); | 41 DECLARE_FN_POINTER(gps_poll); |
46 DECLARE_FN_POINTER(gps_query, mode == INITMODE_QUERY); | 42 DECLARE_FN_POINTER(gps_stream); |
47 DECLARE_FN_POINTER(gps_stream, mode == INITMODE_STREAM); | 43 DECLARE_FN_POINTER(gps_waiting); |
48 DECLARE_FN_POINTER(gps_waiting, mode == INITMODE_STREAM); | |
49 #undef DECLARE_FN_POINTER | 44 #undef DECLARE_FN_POINTER |
50 | 45 |
51 return new LibGpsLibraryWrapper(dl_handle, | 46 return new LibGpsLibraryWrapper(dl_handle, |
52 gps_open, | 47 gps_open, |
53 gps_close, | 48 gps_close, |
54 gps_poll, | 49 gps_poll, |
55 gps_query, | |
56 gps_stream, | 50 gps_stream, |
57 gps_waiting); | 51 gps_waiting); |
58 } | 52 } |
59 } // namespace | 53 } // namespace |
60 | 54 |
61 LibGps::LibGps(LibGpsLibraryWrapper* dl_wrapper) | 55 LibGps::LibGps(LibGpsLibraryWrapper* dl_wrapper) |
62 : library_(dl_wrapper) { | 56 : library_(dl_wrapper) { |
63 DCHECK(dl_wrapper != NULL); | 57 DCHECK(dl_wrapper != NULL); |
64 } | 58 } |
65 | 59 |
66 LibGps::~LibGps() { | 60 LibGps::~LibGps() { |
67 } | 61 } |
68 | 62 |
69 LibGps* LibGps::New() { | 63 LibGps* LibGps::New() { |
70 LibGpsLibraryWrapper* wrapper; | 64 LibGpsLibraryWrapper* wrapper; |
71 wrapper = TryToOpen("libgps.so.19", INITMODE_STREAM); | 65 wrapper = TryToOpen("libgps.so.19"); |
72 if (wrapper) | 66 if (wrapper) |
73 return NewV294(wrapper); | 67 return NewV294(wrapper); |
74 wrapper = TryToOpen("libgps.so.17", INITMODE_QUERY); | 68 wrapper = TryToOpen("libgps.so"); |
75 if (wrapper) | |
76 return NewV238(wrapper); | |
77 wrapper = TryToOpen("libgps.so", INITMODE_STREAM); | |
78 if (wrapper) | 69 if (wrapper) |
79 return NewV294(wrapper); | 70 return NewV294(wrapper); |
80 return NULL; | 71 return NULL; |
81 } | 72 } |
82 | 73 |
83 bool LibGps::Start() { | 74 bool LibGps::Start() { |
84 if (library().is_open()) | 75 if (library().is_open()) |
85 return true; | 76 return true; |
86 errno = 0; | 77 errno = 0; |
87 static int fail_count = 0; | 78 static int fail_count = 0; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 position->error_message = "Bad fix from gps"; | 132 position->error_message = "Bad fix from gps"; |
142 return false; | 133 return false; |
143 } | 134 } |
144 return true; | 135 return true; |
145 } | 136 } |
146 | 137 |
147 LibGpsLibraryWrapper::LibGpsLibraryWrapper(void* dl_handle, | 138 LibGpsLibraryWrapper::LibGpsLibraryWrapper(void* dl_handle, |
148 gps_open_fn gps_open, | 139 gps_open_fn gps_open, |
149 gps_close_fn gps_close, | 140 gps_close_fn gps_close, |
150 gps_poll_fn gps_poll, | 141 gps_poll_fn gps_poll, |
151 gps_query_fn gps_query, | |
152 gps_stream_fn gps_stream, | 142 gps_stream_fn gps_stream, |
153 gps_waiting_fn gps_waiting) | 143 gps_waiting_fn gps_waiting) |
154 : dl_handle_(dl_handle), | 144 : dl_handle_(dl_handle), |
155 gps_open_(gps_open), | 145 gps_open_(gps_open), |
156 gps_close_(gps_close), | 146 gps_close_(gps_close), |
157 gps_poll_(gps_poll), | 147 gps_poll_(gps_poll), |
158 gps_query_(gps_query), | |
159 gps_stream_(gps_stream), | 148 gps_stream_(gps_stream), |
160 gps_waiting_(gps_waiting), | 149 gps_waiting_(gps_waiting), |
161 gps_data_(NULL) { | 150 gps_data_(NULL) { |
162 } | 151 } |
163 | 152 |
164 LibGpsLibraryWrapper::~LibGpsLibraryWrapper() { | 153 LibGpsLibraryWrapper::~LibGpsLibraryWrapper() { |
165 close(); | 154 close(); |
166 if (dl_handle_) { | 155 if (dl_handle_) { |
167 const int err = dlclose(dl_handle_); | 156 const int err = dlclose(dl_handle_); |
168 CHECK_EQ(0, err) << "Error closing dl handle: " << err; | 157 CHECK_EQ(0, err) << "Error closing dl handle: " << err; |
(...skipping 14 matching lines...) Expand all Loading... |
183 gps_data_ = NULL; | 172 gps_data_ = NULL; |
184 } | 173 } |
185 } | 174 } |
186 | 175 |
187 int LibGpsLibraryWrapper::poll() { | 176 int LibGpsLibraryWrapper::poll() { |
188 DCHECK(is_open()); | 177 DCHECK(is_open()); |
189 DCHECK(gps_poll_); | 178 DCHECK(gps_poll_); |
190 return gps_poll_(gps_data_); | 179 return gps_poll_(gps_data_); |
191 } | 180 } |
192 | 181 |
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) { | 182 int LibGpsLibraryWrapper::stream(int flags) { |
202 DCHECK(is_open()); | 183 DCHECK(is_open()); |
203 DCHECK(gps_stream_); | 184 DCHECK(gps_stream_); |
204 return gps_stream_(gps_data_, flags, NULL); | 185 return gps_stream_(gps_data_, flags, NULL); |
205 } | 186 } |
206 | 187 |
207 bool LibGpsLibraryWrapper::waiting() { | 188 bool LibGpsLibraryWrapper::waiting() { |
208 DCHECK(is_open()); | 189 DCHECK(is_open()); |
209 DCHECK(gps_waiting_); | 190 DCHECK(gps_waiting_); |
210 return gps_waiting_(gps_data_); | 191 return gps_waiting_(gps_data_); |
211 } | 192 } |
212 | 193 |
213 const gps_data_t& LibGpsLibraryWrapper::data() const { | 194 const gps_data_t& LibGpsLibraryWrapper::data() const { |
214 DCHECK(is_open()); | 195 DCHECK(is_open()); |
215 return *gps_data_; | 196 return *gps_data_; |
216 } | 197 } |
217 | 198 |
218 bool LibGpsLibraryWrapper::is_open() const { | 199 bool LibGpsLibraryWrapper::is_open() const { |
219 return gps_data_ != NULL; | 200 return gps_data_ != NULL; |
220 } | 201 } |
OLD | NEW |