File: fcm_handler.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 (141 lines) | stat: -rw-r--r-- 5,310 bytes parent folder | download | duplicates (6)
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
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SYNC_INVALIDATIONS_FCM_HANDLER_H_
#define COMPONENTS_SYNC_INVALIDATIONS_FCM_HANDLER_H_

#include <optional>
#include <string>

#include "base/containers/circular_deque.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/gcm_driver/gcm_app_handler.h"
#include "components/gcm_driver/instance_id/instance_id.h"
#include "components/keyed_service/core/keyed_service.h"

namespace gcm {
class GCMDriver;
}

namespace instance_id {
class InstanceIDDriver;
}

namespace syncer {

class FCMRegistrationTokenObserver;
class InvalidationsListener;

// This handler is used to register with FCM and to process incoming messages.
class FCMHandler : public gcm::GCMAppHandler {
 public:
  FCMHandler(gcm::GCMDriver* gcm_driver,
             instance_id::InstanceIDDriver* instance_id_driver,
             const std::string& sender_id,
             const std::string& app_id);
  ~FCMHandler() override;
  FCMHandler(const FCMHandler&) = delete;
  FCMHandler& operator=(const FCMHandler&) = delete;

  // Used to start handling incoming invalidations from the server and to obtain
  // an FCM token. This method gets called after data types are configured.
  // Before StartListening() is called for the first time, the FCM registration
  // token will be null.
  void StartListening();

  // Stop handling incoming invalidations. It doesn't cleanup the FCM
  // registration token and doesn't unsubscribe from FCM. All incoming
  // invalidations will be dropped. This method gets called during browser
  // shutdown.
  void StopListening();

  // Stop handling incoming invalidations and delete Instance ID. It clears the
  // FCM registration token. This method gets called during sign-out.
  void StopListeningPermanently();

  // Returns if the handler is listening for incoming invalidations.
  bool IsListening() const;

  // Add a new `listener` which will be notified on each new incoming
  // invalidation. `listener` must not be nullptr. Does nothing if the
  // `listener` has already been added before. When a new `listener` is added,
  // previously received messages will be immediately replayed.
  void AddListener(InvalidationsListener* listener);

  // Returns whether `listener` was added before.
  bool HasListener(InvalidationsListener* listener);

  // Removes `listener`, does nothing if it wasn't added before. `listener` must
  // not be nullptr.
  void RemoveListener(InvalidationsListener* listener);

  // Add or remove an FCM token change observer. `observer` must not be nullptr.
  void AddTokenObserver(FCMRegistrationTokenObserver* observer);
  void RemoveTokenObserver(FCMRegistrationTokenObserver* observer);

  // Used to get an obtained FCM token. Returns null if it doesn't have a token.
  const std::optional<std::string>& GetFCMRegistrationToken() const;

  // GCMAppHandler overrides.
  void ShutdownHandler() override;
  void OnStoreReset() override;
  void OnMessage(const std::string& app_id,
                 const gcm::IncomingMessage& message) override;
  void OnMessagesDeleted(const std::string& app_id) override;
  void OnSendError(const std::string& app_id,
                   const gcm::GCMClient::SendErrorDetails& details) override;
  void OnSendAcknowledged(const std::string& app_id,
                          const std::string& message_id) override;

 private:
  // Called when a subscription token is obtained from the GCM server.
  void DidRetrieveToken(base::TimeTicks fetch_time_for_metrics,
                        bool is_validation,
                        const std::string& subscription_token,
                        instance_id::InstanceID::Result result);
  void ScheduleNextTokenValidation();
  void StartTokenValidation();

  void StartTokenFetch(bool is_validation);

  SEQUENCE_CHECKER(sequence_checker_);

  raw_ptr<gcm::GCMDriver> gcm_driver_ = nullptr;
  raw_ptr<instance_id::InstanceIDDriver> instance_id_driver_ = nullptr;
  const std::string sender_id_;
  const std::string app_id_;

  // Contains an FCM registration token. Token is null if the experiment is off
  // or we don't have a valid token yet and contains valid token otherwise.
  std::optional<std::string> fcm_registration_token_;

  base::OneShotTimer token_validation_timer_;

  // A list of the latest incoming messages, used to replay incoming messages
  // whenever a new listener is added.
  base::circular_deque<std::string> last_received_messages_;

  // Contains all listeners to notify about each incoming message in OnMessage
  // method.
  base::ObserverList<InvalidationsListener,
                     /*check_empty=*/true,
                     /*allow_reentrancy=*/false>
      listeners_;

  // Contains all FCM token observers to notify about each token change.
  base::ObserverList<FCMRegistrationTokenObserver,
                     /*check_empty=*/true,
                     /*allow_reentrancy=*/false>
      token_observers_;

  base::WeakPtrFactory<FCMHandler> weak_ptr_factory_{this};
};

}  // namespace syncer

#endif  // COMPONENTS_SYNC_INVALIDATIONS_FCM_HANDLER_H_