1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GOOGLE_APIS_GCM_ENGINE_UNREGISTRATION_REQUEST_H_
#define GOOGLE_APIS_GCM_ENGINE_UNREGISTRATION_REQUEST_H_
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "google_apis/gcm/base/gcm_export.h"
#include "net/base/backoff_entry.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h"
namespace net {
class URLRequestContextGetter;
}
namespace gcm {
class GCMStatsRecorder;
// Encapsulates the common logic applying to both GCM unregistration requests
// and InstanceID delete-token requests. In case an attempt fails, it will retry
// using the backoff policy.
// TODO(fgorski): Consider sharing code with RegistrationRequest if possible.
class GCM_EXPORT UnregistrationRequest : public net::URLFetcherDelegate {
public:
// Outcome of the response parsing. Note that these enums are consumed by a
// histogram, so ordering should not be modified.
enum Status {
SUCCESS, // Unregistration completed successfully.
URL_FETCHING_FAILED, // URL fetching failed.
NO_RESPONSE_BODY, // No response body.
RESPONSE_PARSING_FAILED, // Failed to parse a meaningful output from
// response
// body.
INCORRECT_APP_ID, // App ID returned by the fetcher does not match
// request.
INVALID_PARAMETERS, // Request parameters were invalid.
SERVICE_UNAVAILABLE, // Unregistration service unavailable.
INTERNAL_SERVER_ERROR, // Internal server error happened during request.
HTTP_NOT_OK, // HTTP response code was not OK.
UNKNOWN_ERROR, // Unknown error.
REACHED_MAX_RETRIES, // Reached maximum number of retries.
// NOTE: Always keep this entry at the end. Add new status types only
// immediately above this line. Make sure to update the corresponding
// histogram enum accordingly.
UNREGISTRATION_STATUS_COUNT,
};
// Callback completing the unregistration request.
typedef base::Callback<void(Status success)> UnregistrationCallback;
// Defines the common info about an unregistration/token-deletion request.
// All parameters are mandatory.
struct GCM_EXPORT RequestInfo {
RequestInfo(uint64 android_id,
uint64 security_token,
const std::string& app_id);
~RequestInfo();
// Android ID of the device.
uint64 android_id;
// Security token of the device.
uint64 security_token;
// Application ID.
std::string app_id;
};
// Encapsulates the custom logic that is needed to build and process the
// unregistration request.
class GCM_EXPORT CustomRequestHandler {
public:
CustomRequestHandler();
virtual ~CustomRequestHandler();
// Builds the HTTP request body data. It is called after
// UnregistrationRequest::BuildRequestBody to append more custom info to
// |body|. Note that the request body is encoded in HTTP form format.
virtual void BuildRequestBody(std::string* body) = 0;
// Parses the HTTP response. It is called after
// UnregistrationRequest::ParseResponse to proceed the parsing.
virtual Status ParseResponse(const net::URLFetcher* source) = 0;
// Reports various UMAs, including status, retry count and completion time.
virtual void ReportUMAs(Status status,
int retry_count,
base::TimeDelta complete_time) = 0;
};
// Creates an instance of UnregistrationRequest. |callback| will be called
// once registration has been revoked or there has been an error that makes
// further retries pointless.
UnregistrationRequest(
const GURL& registration_url,
const RequestInfo& request_info,
scoped_ptr<CustomRequestHandler> custom_request_handler,
const net::BackoffEntry::Policy& backoff_policy,
const UnregistrationCallback& callback,
int max_retry_count,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
GCMStatsRecorder* recorder,
const std::string& source_to_record);
~UnregistrationRequest() override;
// Starts an unregistration request.
void Start();
private:
// URLFetcherDelegate implementation.
void OnURLFetchComplete(const net::URLFetcher* source) override;
void BuildRequestHeaders(std::string* extra_headers);
void BuildRequestBody(std::string* body);
Status ParseResponse(const net::URLFetcher* source);
// Schedules a retry attempt with a backoff.
void RetryWithBackoff();
UnregistrationCallback callback_;
RequestInfo request_info_;
scoped_ptr<CustomRequestHandler> custom_request_handler_;
GURL registration_url_;
net::BackoffEntry backoff_entry_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
scoped_ptr<net::URLFetcher> url_fetcher_;
base::TimeTicks request_start_time_;
int retries_left_;
// Recorder that records GCM activities for debugging purpose. Not owned.
GCMStatsRecorder* recorder_;
std::string source_to_record_;
base::WeakPtrFactory<UnregistrationRequest> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(UnregistrationRequest);
};
} // namespace gcm
#endif // GOOGLE_APIS_GCM_ENGINE_UNREGISTRATION_REQUEST_H_
|