OLD | NEW |
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/network_location_request.h" | 5 #include "content/browser/geolocation/network_location_request.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "content/common/geoposition.h" | |
16 #include "content/common/net/url_fetcher_impl.h" | 15 #include "content/common/net/url_fetcher_impl.h" |
| 16 #include "content/public/common/geoposition.h" |
17 #include "net/base/escape.h" | 17 #include "net/base/escape.h" |
18 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
19 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
20 #include "net/url_request/url_request_status.h" | 20 #include "net/url_request/url_request_status.h" |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 const size_t kMaxRequestLength = 2048; | 24 const size_t kMaxRequestLength = 2048; |
25 | 25 |
26 const char kAccessTokenString[] = "access_token"; | 26 const char kAccessTokenString[] = "access_token"; |
(...skipping 10 matching lines...) Expand all Loading... |
37 const string16& access_token, | 37 const string16& access_token, |
38 const WifiData& wifi_data, | 38 const WifiData& wifi_data, |
39 const base::Time& timestamp); | 39 const base::Time& timestamp); |
40 | 40 |
41 // Parsers the server response. | 41 // Parsers the server response. |
42 void GetLocationFromResponse(bool http_post_result, | 42 void GetLocationFromResponse(bool http_post_result, |
43 int status_code, | 43 int status_code, |
44 const std::string& response_body, | 44 const std::string& response_body, |
45 const base::Time& timestamp, | 45 const base::Time& timestamp, |
46 const GURL& server_url, | 46 const GURL& server_url, |
47 Geoposition* position, | 47 content::Geoposition* position, |
48 string16* access_token); | 48 string16* access_token); |
49 | 49 |
50 // Parses the server response body. Returns true if parsing was successful. | 50 // Parses the server response body. Returns true if parsing was successful. |
51 // Sets |*position| to the parsed location if a valid fix was received, | 51 // Sets |*position| to the parsed location if a valid fix was received, |
52 // otherwise leaves it unchanged (i.e. IsInitialized() == false). | 52 // otherwise leaves it unchanged. |
53 bool ParseServerResponse(const std::string& response_body, | 53 bool ParseServerResponse(const std::string& response_body, |
54 const base::Time& timestamp, | 54 const base::Time& timestamp, |
55 Geoposition* position, | 55 content::Geoposition* position, |
56 string16* access_token); | 56 string16* access_token); |
57 void AddWifiData(const WifiData& wifi_data, | 57 void AddWifiData(const WifiData& wifi_data, |
58 int age_milliseconds, | 58 int age_milliseconds, |
59 std::vector<std::string>* params); | 59 std::vector<std::string>* params); |
60 } // namespace | 60 } // namespace |
61 | 61 |
62 int NetworkLocationRequest::url_fetcher_id_for_tests = 0; | 62 int NetworkLocationRequest::url_fetcher_id_for_tests = 0; |
63 | 63 |
64 NetworkLocationRequest::NetworkLocationRequest( | 64 NetworkLocationRequest::NetworkLocationRequest( |
65 net::URLRequestContextGetter* context, | 65 net::URLRequestContextGetter* context, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 return true; | 99 return true; |
100 } | 100 } |
101 | 101 |
102 void NetworkLocationRequest::OnURLFetchComplete( | 102 void NetworkLocationRequest::OnURLFetchComplete( |
103 const content::URLFetcher* source) { | 103 const content::URLFetcher* source) { |
104 DCHECK_EQ(url_fetcher_.get(), source); | 104 DCHECK_EQ(url_fetcher_.get(), source); |
105 | 105 |
106 net::URLRequestStatus status = source->GetStatus(); | 106 net::URLRequestStatus status = source->GetStatus(); |
107 int response_code = source->GetResponseCode(); | 107 int response_code = source->GetResponseCode(); |
108 | 108 |
109 Geoposition position; | 109 content::Geoposition position; |
110 string16 access_token; | 110 string16 access_token; |
111 std::string data; | 111 std::string data; |
112 source->GetResponseAsString(&data); | 112 source->GetResponseAsString(&data); |
113 GetLocationFromResponse(status.is_success(), | 113 GetLocationFromResponse(status.is_success(), |
114 response_code, | 114 response_code, |
115 data, | 115 data, |
116 timestamp_, | 116 timestamp_, |
117 source->GetURL(), | 117 source->GetURL(), |
118 &position, | 118 &position, |
119 &access_token); | 119 &access_token); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 // interpreted as the wifi parameter separator. | 230 // interpreted as the wifi parameter separator. |
231 ReplaceSubstringsAfterOffset(&ssid, 0, "|", "\\|"); | 231 ReplaceSubstringsAfterOffset(&ssid, 0, "|", "\\|"); |
232 AddString("ssid:", ssid, &wifi_params); | 232 AddString("ssid:", ssid, &wifi_params); |
233 params->push_back( | 233 params->push_back( |
234 "wifi=" + net::EscapeQueryParamValue(wifi_params, false)); | 234 "wifi=" + net::EscapeQueryParamValue(wifi_params, false)); |
235 } | 235 } |
236 } | 236 } |
237 | 237 |
238 void FormatPositionError(const GURL& server_url, | 238 void FormatPositionError(const GURL& server_url, |
239 const std::string& message, | 239 const std::string& message, |
240 Geoposition* position) { | 240 content::Geoposition* position) { |
241 position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; | 241 position->error_code = |
| 242 content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; |
242 position->error_message = "Network location provider at '"; | 243 position->error_message = "Network location provider at '"; |
243 position->error_message += server_url.possibly_invalid_spec(); | 244 position->error_message += server_url.possibly_invalid_spec(); |
244 position->error_message += "' : "; | 245 position->error_message += "' : "; |
245 position->error_message += message; | 246 position->error_message += message; |
246 position->error_message += "."; | 247 position->error_message += "."; |
247 VLOG(1) << "NetworkLocationRequest::GetLocationFromResponse() : " | 248 VLOG(1) << "NetworkLocationRequest::GetLocationFromResponse() : " |
248 << position->error_message; | 249 << position->error_message; |
249 } | 250 } |
250 | 251 |
251 void GetLocationFromResponse(bool http_post_result, | 252 void GetLocationFromResponse(bool http_post_result, |
252 int status_code, | 253 int status_code, |
253 const std::string& response_body, | 254 const std::string& response_body, |
254 const base::Time& timestamp, | 255 const base::Time& timestamp, |
255 const GURL& server_url, | 256 const GURL& server_url, |
256 Geoposition* position, | 257 content::Geoposition* position, |
257 string16* access_token) { | 258 string16* access_token) { |
258 DCHECK(position); | 259 DCHECK(position); |
259 DCHECK(access_token); | 260 DCHECK(access_token); |
260 | 261 |
261 // HttpPost can fail for a number of reasons. Most likely this is because | 262 // HttpPost can fail for a number of reasons. Most likely this is because |
262 // we're offline, or there was no response. | 263 // we're offline, or there was no response. |
263 if (!http_post_result) { | 264 if (!http_post_result) { |
264 FormatPositionError(server_url, "No response received", position); | 265 FormatPositionError(server_url, "No response received", position); |
265 return; | 266 return; |
266 } | 267 } |
267 if (status_code != 200) { // HTTP OK. | 268 if (status_code != 200) { // HTTP OK. |
268 std::string message = "Returned error code "; | 269 std::string message = "Returned error code "; |
269 message += base::IntToString(status_code); | 270 message += base::IntToString(status_code); |
270 FormatPositionError(server_url, message, position); | 271 FormatPositionError(server_url, message, position); |
271 return; | 272 return; |
272 } | 273 } |
273 // We use the timestamp from the device data that was used to generate | 274 // We use the timestamp from the device data that was used to generate |
274 // this position fix. | 275 // this position fix. |
275 if (!ParseServerResponse(response_body, timestamp, position, access_token)) { | 276 if (!ParseServerResponse(response_body, timestamp, position, access_token)) { |
276 // We failed to parse the repsonse. | 277 // We failed to parse the repsonse. |
277 FormatPositionError(server_url, "Response was malformed", position); | 278 FormatPositionError(server_url, "Response was malformed", position); |
278 return; | 279 return; |
279 } | 280 } |
280 // The response was successfully parsed, but it may not be a valid | 281 // The response was successfully parsed, but it may not be a valid |
281 // position fix. | 282 // position fix. |
282 if (!position->IsValidFix()) { | 283 if (!position->Validate()) { |
283 FormatPositionError(server_url, | 284 FormatPositionError(server_url, |
284 "Did not provide a good position fix", position); | 285 "Did not provide a good position fix", position); |
285 return; | 286 return; |
286 } | 287 } |
287 } | 288 } |
288 | 289 |
289 // Numeric values without a decimal point have type integer and IsDouble() will | 290 // Numeric values without a decimal point have type integer and IsDouble() will |
290 // return false. This is convenience function for detecting integer or floating | 291 // return false. This is convenience function for detecting integer or floating |
291 // point numeric values. Note that isIntegral() includes boolean values, which | 292 // point numeric values. Note that isIntegral() includes boolean values, which |
292 // is not what we want. | 293 // is not what we want. |
293 bool GetAsDouble(const DictionaryValue& object, | 294 bool GetAsDouble(const DictionaryValue& object, |
294 const std::string& property_name, | 295 const std::string& property_name, |
295 double* out) { | 296 double* out) { |
296 DCHECK(out); | 297 DCHECK(out); |
297 Value* value = NULL; | 298 Value* value = NULL; |
298 if (!object.Get(property_name, &value)) | 299 if (!object.Get(property_name, &value)) |
299 return false; | 300 return false; |
300 int value_as_int; | 301 int value_as_int; |
301 DCHECK(value); | 302 DCHECK(value); |
302 if (value->GetAsInteger(&value_as_int)) { | 303 if (value->GetAsInteger(&value_as_int)) { |
303 *out = value_as_int; | 304 *out = value_as_int; |
304 return true; | 305 return true; |
305 } | 306 } |
306 return value->GetAsDouble(out); | 307 return value->GetAsDouble(out); |
307 } | 308 } |
308 | 309 |
309 bool ParseServerResponse(const std::string& response_body, | 310 bool ParseServerResponse(const std::string& response_body, |
310 const base::Time& timestamp, | 311 const base::Time& timestamp, |
311 Geoposition* position, | 312 content::Geoposition* position, |
312 string16* access_token) { | 313 string16* access_token) { |
313 DCHECK(position); | 314 DCHECK(position); |
314 DCHECK(!position->IsInitialized()); | 315 DCHECK(!position->Validate()); |
| 316 DCHECK(position->error_code == content::Geoposition::ERROR_CODE_NONE); |
315 DCHECK(access_token); | 317 DCHECK(access_token); |
316 DCHECK(!timestamp.is_null()); | 318 DCHECK(!timestamp.is_null()); |
317 | 319 |
318 if (response_body.empty()) { | 320 if (response_body.empty()) { |
319 LOG(WARNING) << "ParseServerResponse() : Response was empty."; | 321 LOG(WARNING) << "ParseServerResponse() : Response was empty."; |
320 return false; | 322 return false; |
321 } | 323 } |
322 DVLOG(1) << "ParseServerResponse() : Parsing response " << response_body; | 324 DVLOG(1) << "ParseServerResponse() : Parsing response " << response_body; |
323 | 325 |
324 // Parse the response, ignoring comments. | 326 // Parse the response, ignoring comments. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 position->longitude = longitude; | 408 position->longitude = longitude; |
407 position->timestamp = timestamp; | 409 position->timestamp = timestamp; |
408 | 410 |
409 // Other fields are optional. | 411 // Other fields are optional. |
410 GetAsDouble(*response_object, kAccuracyString, &position->accuracy); | 412 GetAsDouble(*response_object, kAccuracyString, &position->accuracy); |
411 | 413 |
412 return true; | 414 return true; |
413 } | 415 } |
414 | 416 |
415 } // namespace | 417 } // namespace |
OLD | NEW |