10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file.
40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#ifndef CHROME_BROWSER_CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_H_
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#define CHROME_BROWSER_CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_H_
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/basictypes.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/callback.h"
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/compiler_specific.h"
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/ref_counted.h"
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/scoped_ptr.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/threading/thread_checker.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/timer/timer.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/chromeos/geolocation/geoposition.h"
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/url_request/url_fetcher.h"
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "net/url_request/url_fetcher_delegate.h"
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "url/gurl.h"
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace net {
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass URLRequestContextGetter;
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace chromeos {
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Sends request to a server to get local geolocation information.
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// It performs formatting of the request and interpretation of the response.
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Request is owned and destroyed by caller (usually SimpleGeolocationProvider).
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// - If error occurs, request is retried until timeout.
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// - On successul response, callback is called.
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// - On timeout, callback with last (failed) position is called.
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// (position.status is set to STATUS_TIMEOUT.)
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// - If request is destroyed while callback has not beed called yet, request
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// is silently cancelled.
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass SimpleGeolocationRequest : private net::URLFetcherDelegate {
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Called when a new geo geolocation information is available.
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // The second argument indicates whether there was a server error or not.
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // It is true when there was a server or network error - either no response
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // or a 500 error code.
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  typedef base::Callback<void(const Geoposition& /* position*/,
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              bool /* server_error */,
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              const base::TimeDelta elapsed)> ResponseCallback;
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // |url| is the server address to which the request wil be sent.
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // |timeout| retry request on error until timeout.
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SimpleGeolocationRequest(net::URLRequestContextGetter* url_context_getter,
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                           const GURL& service_url,
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                           base::TimeDelta timeout);
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~SimpleGeolocationRequest();
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Initiates request.
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Note: if request object is destroyed before callback is called,
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // request will be silently cancelled.
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void MakeRequest(const ResponseCallback& callback);
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void set_retry_sleep_on_server_error_for_testing(
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::TimeDelta value) {
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    retry_sleep_on_server_error_ = value;
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void set_retry_sleep_on_bad_response_for_testing(
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::TimeDelta value) {
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    retry_sleep_on_bad_response_ = value;
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // net::URLFetcherDelegate
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Start new request.
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void StartRequest();
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Schedules retry.
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void Retry(bool server_error);
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Run callback and destroy "this".
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void ReplyAndDestroySelf(const base::TimeDelta elapsed, bool server_error);
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Called by timeout_timer_ .
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void OnTimeout();
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<net::URLRequestContextGetter> url_context_getter_;
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Service URL from constructor arguments.
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const GURL service_url_;
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ResponseCallback callback_;
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Actual URL with parameters.
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  GURL request_url_;
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<net::URLFetcher> url_fetcher_;
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // When request was actually started.
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Time request_started_at_;
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta retry_sleep_on_server_error_;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeDelta retry_sleep_on_bad_response_;
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::TimeDelta timeout_;
1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Pending retry.
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::OneShotTimer<SimpleGeolocationRequest> request_scheduled_;
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Stop request on timeout.
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::OneShotTimer<SimpleGeolocationRequest> timeout_timer_;
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Number of retry attempts.
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  unsigned retries_;
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This is updated on each retry.
1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Geoposition position_;
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Creation and destruction should happen on the same thread.
1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::ThreadChecker thread_checker_;
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SimpleGeolocationRequest);
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace chromeos
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // CHROME_BROWSER_CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_H_
126