File: unregistration_request.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (163 lines) | stat: -rw-r--r-- 6,023 bytes parent folder | download | duplicates (10)
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_