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 GOOGLE_APIS_GCM_ENGINE_REGISTRATION_REQUEST_H_
6#define GOOGLE_APIS_GCM_ENGINE_REGISTRATION_REQUEST_H_
7
8#include <map>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/callback.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/time/time.h"
17#include "google_apis/gcm/base/gcm_export.h"
18#include "net/base/backoff_entry.h"
19#include "net/url_request/url_fetcher_delegate.h"
20#include "url/gurl.h"
21
22namespace net {
23class URLRequestContextGetter;
24}
25
26namespace gcm {
27
28class GCMStatsRecorder;
29
30// Registration request is used to obtain registration IDs for applications that
31// want to use GCM. It requires a set of parameters to be specified to identify
32// the Chrome instance, the user, the application and a set of senders that will
33// be authorized to address the application using it's assigned registration ID.
34class GCM_EXPORT RegistrationRequest : public net::URLFetcherDelegate {
35 public:
36  // This enum is also used in an UMA histogram (GCMRegistrationRequestStatus
37  // enum defined in tools/metrics/histograms/histogram.xml). Hence the entries
38  // here shouldn't be deleted or re-ordered and new ones should be added to
39  // the end.
40  enum Status {
41    SUCCESS,                    // Registration completed successfully.
42    INVALID_PARAMETERS,         // One of request paramteres was invalid.
43    INVALID_SENDER,             // One of the provided senders was invalid.
44    AUTHENTICATION_FAILED,      // Authentication failed.
45    DEVICE_REGISTRATION_ERROR,  // Chrome is not properly registered.
46    UNKNOWN_ERROR,              // Unknown error.
47    URL_FETCHING_FAILED,        // URL fetching failed.
48    HTTP_NOT_OK,                // HTTP status was not OK.
49    RESPONSE_PARSING_FAILED,    // Registration response parsing failed.
50    REACHED_MAX_RETRIES,        // Reached maximum number of retries.
51    // NOTE: always keep this entry at the end. Add new status types only
52    // immediately above this line. Make sure to update the corresponding
53    // histogram enum accordingly.
54    STATUS_COUNT
55  };
56
57  // Callback completing the registration request.
58  typedef base::Callback<void(Status status,
59                              const std::string& registration_id)>
60      RegistrationCallback;
61
62  // Details of the of the Registration Request. Only user's android ID and
63  // its serial number are optional and can be set to 0. All other parameters
64  // have to be specified to successfully complete the call.
65  struct GCM_EXPORT RequestInfo {
66    RequestInfo(uint64 android_id,
67                uint64 security_token,
68                const std::string& app_id,
69                const std::vector<std::string>& sender_ids);
70    ~RequestInfo();
71
72    // Android ID of the device.
73    uint64 android_id;
74    // Security token of the device.
75    uint64 security_token;
76    // Application ID.
77    std::string app_id;
78    // Certificate of the application.
79    std::string cert;
80    // List of IDs of senders. Allowed up to 100.
81    std::vector<std::string> sender_ids;
82  };
83
84  RegistrationRequest(
85      const GURL& registration_url,
86      const RequestInfo& request_info,
87      const net::BackoffEntry::Policy& backoff_policy,
88      const RegistrationCallback& callback,
89      int max_retry_count,
90      scoped_refptr<net::URLRequestContextGetter> request_context_getter,
91      GCMStatsRecorder* recorder);
92  virtual ~RegistrationRequest();
93
94  void Start();
95
96  // URLFetcherDelegate implementation.
97  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
98
99 private:
100  // Schedules a retry attempt, informs the backoff of a previous request's
101  // failure, when |update_backoff| is true.
102  void RetryWithBackoff(bool update_backoff);
103
104  // Parse the response returned by the URL fetcher into token, and returns the
105  // status.
106  Status ParseResponse(const net::URLFetcher* source, std::string* token);
107
108  RegistrationCallback callback_;
109  RequestInfo request_info_;
110  GURL registration_url_;
111
112  net::BackoffEntry backoff_entry_;
113  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
114  scoped_ptr<net::URLFetcher> url_fetcher_;
115  int retries_left_;
116  base::TimeTicks request_start_time_;
117
118  // Recorder that records GCM activities for debugging purpose. Not owned.
119  GCMStatsRecorder* recorder_;
120
121  base::WeakPtrFactory<RegistrationRequest> weak_ptr_factory_;
122
123  DISALLOW_COPY_AND_ASSIGN(RegistrationRequest);
124};
125
126}  // namespace gcm
127
128#endif  // GOOGLE_APIS_GCM_ENGINE_REGISTRATION_REQUEST_H_
129