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