1 // Copyright 2014 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 #ifndef CHROME_BROWSER_CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_H_ 6 #define CHROME_BROWSER_CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_H_ 7 8 #include "base/basictypes.h" 9 #include "base/callback.h" 10 #include "base/compiler_specific.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/threading/thread_checker.h" 14 #include "base/timer/timer.h" 15 #include "chrome/browser/chromeos/geolocation/geoposition.h" 16 #include "net/url_request/url_fetcher.h" 17 #include "net/url_request/url_fetcher_delegate.h" 18 #include "url/gurl.h" 19 20 namespace net { 21 class URLRequestContextGetter; 22 } 23 24 namespace chromeos { 25 26 // Sends request to a server to get local geolocation information. 27 // It performs formatting of the request and interpretation of the response. 28 // Request is owned and destroyed by caller (usually SimpleGeolocationProvider). 29 // - If error occurs, request is retried until timeout. 30 // - On successul response, callback is called. 31 // - On timeout, callback with last (failed) position is called. 32 // (position.status is set to STATUS_TIMEOUT.) 33 // - If request is destroyed while callback has not beed called yet, request 34 // is silently cancelled. 35 class SimpleGeolocationRequest : private net::URLFetcherDelegate { 36 public: 37 // Called when a new geo geolocation information is available. 38 // The second argument indicates whether there was a server error or not. 39 // It is true when there was a server or network error - either no response 40 // or a 500 error code. 41 typedef base::Callback<void(const Geoposition& /* position*/, 42 bool /* server_error */, 43 const base::TimeDelta elapsed)> ResponseCallback; 44 45 // |url| is the server address to which the request wil be sent. 46 // |timeout| retry request on error until timeout. 47 SimpleGeolocationRequest(net::URLRequestContextGetter* url_context_getter, 48 const GURL& service_url, 49 base::TimeDelta timeout); 50 51 virtual ~SimpleGeolocationRequest(); 52 53 // Initiates request. 54 // Note: if request object is destroyed before callback is called, 55 // request will be silently cancelled. 56 void MakeRequest(const ResponseCallback& callback); 57 set_retry_sleep_on_server_error_for_testing(const base::TimeDelta value)58 void set_retry_sleep_on_server_error_for_testing( 59 const base::TimeDelta value) { 60 retry_sleep_on_server_error_ = value; 61 } 62 set_retry_sleep_on_bad_response_for_testing(const base::TimeDelta value)63 void set_retry_sleep_on_bad_response_for_testing( 64 const base::TimeDelta value) { 65 retry_sleep_on_bad_response_ = value; 66 } 67 68 private: 69 // net::URLFetcherDelegate 70 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 71 72 // Start new request. 73 void StartRequest(); 74 75 // Schedules retry. 76 void Retry(bool server_error); 77 78 // Run callback and destroy "this". 79 void ReplyAndDestroySelf(const base::TimeDelta elapsed, bool server_error); 80 81 // Called by timeout_timer_ . 82 void OnTimeout(); 83 84 scoped_refptr<net::URLRequestContextGetter> url_context_getter_; 85 86 // Service URL from constructor arguments. 87 const GURL service_url_; 88 89 ResponseCallback callback_; 90 91 // Actual URL with parameters. 92 GURL request_url_; 93 94 scoped_ptr<net::URLFetcher> url_fetcher_; 95 96 // When request was actually started. 97 base::Time request_started_at_; 98 99 base::TimeDelta retry_sleep_on_server_error_; 100 101 base::TimeDelta retry_sleep_on_bad_response_; 102 103 const base::TimeDelta timeout_; 104 105 // Pending retry. 106 base::OneShotTimer<SimpleGeolocationRequest> request_scheduled_; 107 108 // Stop request on timeout. 109 base::OneShotTimer<SimpleGeolocationRequest> timeout_timer_; 110 111 // Number of retry attempts. 112 unsigned retries_; 113 114 // This is updated on each retry. 115 Geoposition position_; 116 117 // Creation and destruction should happen on the same thread. 118 base::ThreadChecker thread_checker_; 119 120 DISALLOW_COPY_AND_ASSIGN(SimpleGeolocationRequest); 121 }; 122 123 } // namespace chromeos 124 125 #endif // CHROME_BROWSER_CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_H_ 126