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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
// Copyright 2014 The Chromium Authors
// 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 <stdint.h>
#include <memory>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "google_apis/gcm/base/gcm_export.h"
#include "net/base/backoff_entry.h"
#include "url/gurl.h"
namespace net {
class HttpRequestHeaders;
}
namespace network {
class SharedURLLoaderFactory;
class SimpleURLLoader;
}
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:
// 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.
DEVICE_REGISTRATION_ERROR,// Chrome is not properly registered.
// 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.
using UnregistrationCallback = base::OnceCallback<void(Status success)>;
// Defines the common info about an unregistration/token-deletion request.
// All parameters are mandatory.
struct GCM_EXPORT RequestInfo {
RequestInfo(uint64_t android_id,
uint64_t security_token,
const std::string& category,
const std::string& subtype);
~RequestInfo();
// Android ID of the device.
uint64_t android_id;
// Security token of the device.
uint64_t security_token;
// Application ID used in Chrome to refer to registration/token's owner.
const std::string& app_id() { return subtype.empty() ? category : subtype; }
// GCM category field derived from the |app_id|.
std::string category;
// GCM subtype field derived from the |app_id|.
std::string subtype;
};
// 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 std::string& response) = 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,
std::unique_ptr<CustomRequestHandler> custom_request_handler,
const net::BackoffEntry::Policy& backoff_policy,
UnregistrationCallback callback,
int max_retry_count,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
scoped_refptr<base::SequencedTaskRunner> io_task_runner,
GCMStatsRecorder* recorder,
const std::string& source_to_record);
UnregistrationRequest(const UnregistrationRequest&) = delete;
UnregistrationRequest& operator=(const UnregistrationRequest&) = delete;
~UnregistrationRequest();
// Starts an unregistration request.
void Start();
private:
// Invoked from SimpleURLLoader.
void OnURLLoadComplete(const network::SimpleURLLoader* source,
std::unique_ptr<std::string> body);
void BuildRequestHeaders(net::HttpRequestHeaders* headers);
void BuildRequestBody(std::string* body);
Status ParseResponse(const network::SimpleURLLoader* source,
std::unique_ptr<std::string> body);
// Schedules a retry attempt with a backoff.
void RetryWithBackoff();
UnregistrationCallback callback_;
RequestInfo request_info_;
std::unique_ptr<CustomRequestHandler> custom_request_handler_;
GURL registration_url_;
net::BackoffEntry backoff_entry_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
int retries_left_;
const scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
// Recorder that records GCM activities for debugging purpose. Not owned.
raw_ptr<GCMStatsRecorder> recorder_;
std::string source_to_record_;
base::WeakPtrFactory<UnregistrationRequest> weak_ptr_factory_{this};
};
} // namespace gcm
#endif // GOOGLE_APIS_GCM_ENGINE_UNREGISTRATION_REQUEST_H_
|