Home | History | Annotate | Download | only in geolocation
      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 
     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