Home | History | Annotate | Download | only in timezone
      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 
     20 namespace net {
     21 class URLRequestContextGetter;
     22 }
     23 
     24 namespace chromeos {
     25 
     26 struct 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.
     50 GURL 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.
     59 class 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