[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 1 | // Copyright 2013 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 | |
lukasza | 8acc4eb | 2015-07-20 20:57:20 | [diff] [blame] | 5 | #ifndef COMPONENTS_DRIVE_DRIVE_NOTIFICATION_MANAGER_H_ |
| 6 | #define COMPONENTS_DRIVE_DRIVE_NOTIFICATION_MANAGER_H_ |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 7 | |
Sam McNally | e4bd01c | 2018-10-17 23:51:11 | [diff] [blame] | 8 | #include <stdint.h> |
| 9 | |
| 10 | #include <map> |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 11 | #include <memory> |
Stuart Langley | 664e229 | 2018-08-31 04:58:28 | [diff] [blame] | 12 | #include <set> |
| 13 | #include <string> |
| 14 | |
avi | bc5337b | 2015-12-25 23:16:33 | [diff] [blame] | 15 | #include "base/macros.h" |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 16 | #include "base/memory/weak_ptr.h" |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 17 | #include "base/observer_list.h" |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 18 | #include "base/sequence_checker.h" |
| 19 | #include "base/time/default_tick_clock.h" |
[email protected] | 41a17c5 | 2013-06-28 00:27:53 | [diff] [blame] | 20 | #include "base/timer/timer.h" |
lukasza | 8acc4eb | 2015-07-20 20:57:20 | [diff] [blame] | 21 | #include "components/drive/drive_notification_observer.h" |
knn | 062cdbb | 2015-06-26 18:18:42 | [diff] [blame] | 22 | #include "components/invalidation/public/invalidation_handler.h" |
Maksim Moskvitin | 1817bfa | 2020-03-03 11:01:16 | [diff] [blame] | 23 | #include "components/invalidation/public/invalidation_util.h" |
[email protected] | 95003d52 | 2014-03-13 20:22:31 | [diff] [blame] | 24 | #include "components/keyed_service/core/keyed_service.h" |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 25 | |
[email protected] | a5ec28b | 2013-09-03 12:36:48 | [diff] [blame] | 26 | namespace invalidation { |
| 27 | class InvalidationService; |
maxbogue | 0a37945 | 2016-09-22 21:35:05 | [diff] [blame] | 28 | } // namespace invalidation |
[email protected] | a5ec28b | 2013-09-03 12:36:48 | [diff] [blame] | 29 | |
[email protected] | e50af765 | 2013-06-20 06:39:31 | [diff] [blame] | 30 | namespace drive { |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 31 | |
| 32 | // Informs observers when they should check Google Drive for updates. |
| 33 | // Conditions under which updates should be searched: |
| 34 | // 1. XMPP invalidation is received from Google Drive. |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 35 | // 2. Polling timer counts down. |
[email protected] | 95003d52 | 2014-03-13 20:22:31 | [diff] [blame] | 36 | class DriveNotificationManager : public KeyedService, |
| 37 | public syncer::InvalidationHandler { |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 38 | public: |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 39 | // |clock| can be injected for testing. |
[email protected] | a5ec28b | 2013-09-03 12:36:48 | [diff] [blame] | 40 | explicit DriveNotificationManager( |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 41 | invalidation::InvalidationService* invalidation_service, |
| 42 | const base::TickClock* clock = base::DefaultTickClock::GetInstance()); |
dcheng | a8d0774 | 2014-10-21 11:27:13 | [diff] [blame] | 43 | ~DriveNotificationManager() override; |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 44 | |
[email protected] | 95003d52 | 2014-03-13 20:22:31 | [diff] [blame] | 45 | // KeyedService override. |
dcheng | a8d0774 | 2014-10-21 11:27:13 | [diff] [blame] | 46 | void Shutdown() override; |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 47 | |
[email protected] | 71a84dec | 2013-04-17 03:26:11 | [diff] [blame] | 48 | // syncer::InvalidationHandler implementation. |
dcheng | a8d0774 | 2014-10-21 11:27:13 | [diff] [blame] | 49 | void OnInvalidatorStateChange(syncer::InvalidatorState state) override; |
| 50 | void OnIncomingInvalidation( |
Maksim Moskvitin | 1817bfa | 2020-03-03 11:01:16 | [diff] [blame] | 51 | const syncer::TopicInvalidationMap& invalidation_map) override; |
dcheng | a8d0774 | 2014-10-21 11:27:13 | [diff] [blame] | 52 | std::string GetOwnerName() const override; |
Sam McNally | 1305d3b6 | 2019-05-17 21:43:16 | [diff] [blame] | 53 | bool IsPublicTopic(const syncer::Topic& topic) const override; |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 54 | |
| 55 | void AddObserver(DriveNotificationObserver* observer); |
| 56 | void RemoveObserver(DriveNotificationObserver* observer); |
| 57 | |
Stuart Langley | 664e229 | 2018-08-31 04:58:28 | [diff] [blame] | 58 | // There has been a change in the users team drives, and as a result we need |
| 59 | // to update which objects we receive invalidations for. |
| 60 | void UpdateTeamDriveIds(const std::set<std::string>& added_team_drive_ids, |
| 61 | const std::set<std::string>& removed_team_drive_ids); |
| 62 | |
Austin Tankiang | 6f52aa0 | 2020-09-30 14:44:36 | [diff] [blame] | 63 | // Unsubscribe from invalidations from all team drives. |
| 64 | void ClearTeamDriveIds(); |
| 65 | |
[email protected] | a9a0c76 | 2013-05-07 07:01:30 | [diff] [blame] | 66 | // True when XMPP notification is currently enabled. |
| 67 | bool push_notification_enabled() const { |
| 68 | return push_notification_enabled_; |
| 69 | } |
| 70 | |
| 71 | // True when XMPP notification has been registered. |
| 72 | bool push_notification_registered() const { |
| 73 | return push_notification_registered_; |
| 74 | } |
[email protected] | 0fa4844 | 2013-04-26 05:16:23 | [diff] [blame] | 75 | |
Sam McNally | 4f4e429 | 2018-10-19 03:50:29 | [diff] [blame] | 76 | const std::set<std::string>& team_drive_ids_for_test() const { |
| 77 | return team_drive_ids_; |
| 78 | } |
| 79 | |
Sam McNally | 6e8c550 | 2018-10-19 04:05:57 | [diff] [blame] | 80 | const base::ObserverList<DriveNotificationObserver>::Unchecked& |
| 81 | observers_for_test() { |
| 82 | return observers_; |
| 83 | } |
| 84 | |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 85 | private: |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 86 | enum NotificationSource { |
| 87 | NOTIFICATION_XMPP, |
| 88 | NOTIFICATION_POLLING, |
| 89 | }; |
| 90 | |
| 91 | // Restarts the polling timer. Used for polling-based notification. |
| 92 | void RestartPollingTimer(); |
| 93 | |
Stuart Langley | 6477fb06 | 2018-11-15 03:03:36 | [diff] [blame] | 94 | // Restarts the batch notification timer. Used for batching together XMPP |
| 95 | // notifications so we can smooth out the traffic on the drive backends. |
| 96 | void RestartBatchTimer(); |
| 97 | |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 98 | // Notifies the observers that it's time to check for updates. |
| 99 | // |source| indicates where the notification comes from. |
Stuart Langley | 664e229 | 2018-08-31 04:58:28 | [diff] [blame] | 100 | void NotifyObserversToUpdate(NotificationSource source, |
Sam McNally | e4bd01c | 2018-10-17 23:51:11 | [diff] [blame] | 101 | std::map<std::string, int64_t> invalidations); |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 102 | |
| 103 | // Registers for Google Drive invalidation notifications through XMPP. |
[email protected] | 71a84dec | 2013-04-17 03:26:11 | [diff] [blame] | 104 | void RegisterDriveNotifications(); |
[email protected] | 71a84dec | 2013-04-17 03:26:11 | [diff] [blame] | 105 | |
Stuart Langley | 664e229 | 2018-08-31 04:58:28 | [diff] [blame] | 106 | // Updates the list of notifications that we're expecting |
| 107 | void UpdateRegisteredDriveNotifications(); |
| 108 | |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 109 | // Dispatches batched invalidations to observers. |
| 110 | void OnBatchTimerExpired(); |
| 111 | |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 112 | // Returns a string representation of NotificationSource. |
| 113 | static std::string NotificationSourceToString(NotificationSource source); |
| 114 | |
Maksim Moskvitin | 1817bfa | 2020-03-03 11:01:16 | [diff] [blame] | 115 | syncer::Topic GetDriveInvalidationTopic() const; |
| 116 | syncer::Topic GetTeamDriveInvalidationTopic( |
Sam McNally | a037ff9 | 2019-05-16 15:38:32 | [diff] [blame] | 117 | const std::string& team_drive_id) const; |
Maksim Moskvitin | 1817bfa | 2020-03-03 11:01:16 | [diff] [blame] | 118 | std::string ExtractTeamDriveId(base::StringPiece topic_name) const; |
Sam McNally | a037ff9 | 2019-05-16 15:38:32 | [diff] [blame] | 119 | |
[email protected] | a5ec28b | 2013-09-03 12:36:48 | [diff] [blame] | 120 | invalidation::InvalidationService* invalidation_service_; |
Trent Apted | a250ec3ab | 2018-08-19 08:52:19 | [diff] [blame] | 121 | base::ObserverList<DriveNotificationObserver>::Unchecked observers_; |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 122 | |
[email protected] | 71a84dec | 2013-04-17 03:26:11 | [diff] [blame] | 123 | // True when Drive File Sync Service is registered for Drive notifications. |
| 124 | bool push_notification_registered_; |
[email protected] | 3522561 | 2013-05-07 06:45:40 | [diff] [blame] | 125 | // True if the XMPP-based push notification is currently enabled. |
[email protected] | 71a84dec | 2013-04-17 03:26:11 | [diff] [blame] | 126 | bool push_notification_enabled_; |
[email protected] | 3522561 | 2013-05-07 06:45:40 | [diff] [blame] | 127 | // True once observers are notified for the first time. |
| 128 | bool observers_notified_; |
[email protected] | 71a84dec | 2013-04-17 03:26:11 | [diff] [blame] | 129 | |
Stuart Langley | 664e229 | 2018-08-31 04:58:28 | [diff] [blame] | 130 | // This is the set of team drive id's we're receiving notifications for. |
| 131 | std::set<std::string> team_drive_ids_; |
| 132 | |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 133 | // The timer is used for polling based notification. XMPP should usually be |
| 134 | // used but notification is done per polling when XMPP is not working. |
tzik | 32768d5 | 2018-07-10 01:08:32 | [diff] [blame] | 135 | base::OneShotTimer polling_timer_; |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 136 | |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 137 | // This timer is used to batch together invalidations. The invalidation |
| 138 | // service can send many invalidations for the same id in rapid succession, |
| 139 | // batching them together and removing duplicates is an optimzation. |
Stuart Langley | 6477fb06 | 2018-11-15 03:03:36 | [diff] [blame] | 140 | base::OneShotTimer batch_timer_; |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 141 | |
| 142 | // The batch of invalidation id's that we've seen from the invaliation |
| 143 | // service, will be reset when when send the invalidations to the observers. |
Sam McNally | e4bd01c | 2018-10-17 23:51:11 | [diff] [blame] | 144 | std::map<std::string, int64_t> invalidated_change_ids_; |
Stuart Langley | 8084586 | 2018-09-05 00:47:29 | [diff] [blame] | 145 | |
| 146 | SEQUENCE_CHECKER(sequence_checker_); |
| 147 | |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 148 | // Note: This should remain the last member so it'll be destroyed and |
| 149 | // invalidate its weak pointers before any other members are destroyed. |
Jeremy Roman | 5c341f6d | 2019-07-15 15:56:10 | [diff] [blame] | 150 | base::WeakPtrFactory<DriveNotificationManager> weak_ptr_factory_{this}; |
[email protected] | 983efa80 | 2013-05-02 23:39:09 | [diff] [blame] | 151 | |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 152 | DISALLOW_COPY_AND_ASSIGN(DriveNotificationManager); |
| 153 | }; |
| 154 | |
[email protected] | e50af765 | 2013-06-20 06:39:31 | [diff] [blame] | 155 | } // namespace drive |
[email protected] | bc7d1ba | 2013-04-11 05:54:19 | [diff] [blame] | 156 | |
lukasza | 8acc4eb | 2015-07-20 20:57:20 | [diff] [blame] | 157 | #endif // COMPONENTS_DRIVE_DRIVE_NOTIFICATION_MANAGER_H_ |