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_TIMEZONE_TIMEZONE_REQUEST_H_ 6#define CHROME_BROWSER_CHROMEOS_TIMEZONE_TIMEZONE_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 26struct TimeZoneResponseData { 27 enum Status { 28 OK, 29 INVALID_REQUEST, 30 OVER_QUERY_LIMIT, 31 REQUEST_DENIED, 32 UNKNOWN_ERROR, 33 ZERO_RESULTS, 34 REQUEST_ERROR // local problem 35 }; 36 37 TimeZoneResponseData(); 38 39 std::string ToStringForDebug() const; 40 41 double dstOffset; 42 double rawOffset; 43 std::string timeZoneId; 44 std::string timeZoneName; 45 std::string error_message; 46 Status status; 47}; 48 49// Returns default timezone service URL. 50GURL DefaultTimezoneProviderURL(); 51 52// Takes Geoposition and sends it to a server to get local timezone information. 53// It performs formatting of the request and interpretation of the response. 54// If error occurs, request is retried until timeout. 55// Zero timeout indicates single request. 56// Request is owned and destroyed by caller (usually TimeZoneProvider). 57// If request is destroyed while callback has not beed called yet, request 58// is silently cancelled. 59class TimeZoneRequest : private net::URLFetcherDelegate { 60 public: 61 // Called when a new geo timezone information is available. 62 // The second argument indicates whether there was a server error or not. 63 // It is true when there was a server or network error - either no response 64 // or a 500 error code. 65 typedef base::Callback<void(scoped_ptr<TimeZoneResponseData> /* timezone */, 66 bool /* server_error */)> 67 TimeZoneResponseCallback; 68 69 // |url| is the server address to which the request wil be sent. 70 // |geoposition| is the location to query timezone for. 71 // |sensor| if this location was determined using hardware sensor. 72 // |retry_timeout| retry request on error until timeout. 73 TimeZoneRequest(net::URLRequestContextGetter* url_context_getter, 74 const GURL& service_url, 75 const Geoposition& geoposition, 76 bool sensor, 77 base::TimeDelta retry_timeout); 78 79 virtual ~TimeZoneRequest(); 80 81 // Initiates request. 82 // Note: if request object is destroyed before callback is called, 83 // request will be silently cancelled. 84 void MakeRequest(TimeZoneResponseCallback callback); 85 86 void set_retry_sleep_on_server_error_for_testing( 87 const base::TimeDelta value) { 88 retry_sleep_on_server_error_ = value; 89 } 90 91 void set_retry_sleep_on_bad_response_for_testing( 92 const base::TimeDelta value) { 93 retry_sleep_on_bad_response_ = value; 94 } 95 96 private: 97 // net::URLFetcherDelegate 98 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 99 100 // Start new request. 101 void StartRequest(); 102 103 // Schedules retry. 104 void Retry(bool server_error); 105 106 scoped_refptr<net::URLRequestContextGetter> url_context_getter_; 107 const GURL service_url_; 108 Geoposition geoposition_; 109 const bool sensor_; 110 111 TimeZoneResponseCallback callback_; 112 113 GURL request_url_; 114 scoped_ptr<net::URLFetcher> url_fetcher_; 115 116 // When request was actually started. 117 base::Time request_started_at_; 118 119 // Absolute time, when it is passed no more retry requests are allowed. 120 base::Time retry_timeout_abs_; 121 122 // Pending retry. 123 base::OneShotTimer<TimeZoneRequest> timezone_request_scheduled_; 124 125 base::TimeDelta retry_sleep_on_server_error_; 126 127 base::TimeDelta retry_sleep_on_bad_response_; 128 129 // Number of retry attempts. 130 unsigned retries_; 131 132 // Creation and destruction should happen on the same thread. 133 base::ThreadChecker thread_checker_; 134 135 DISALLOW_COPY_AND_ASSIGN(TimeZoneRequest); 136}; 137 138} // namespace chromeos 139 140#endif // CHROME_BROWSER_CHROMEOS_TIMEZONE_TIMEZONE_REQUEST_H_ 141