| 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 |