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 20namespace net { 21class URLRequestContextGetter; 22} 23 24namespace 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. 35class 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 58 void set_retry_sleep_on_server_error_for_testing( 59 const base::TimeDelta value) { 60 retry_sleep_on_server_error_ = value; 61 } 62 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