123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- // Copyright 2020 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.
- #include <map>
- #include <memory>
- #include <utility>
- #include <vector>
- #include "base/containers/cxx20_erase.h"
- #include "base/feature_list.h"
- #include "base/metrics/field_trial_params.h"
- #include "base/ranges/algorithm.h"
- #include "components/browser_sync/active_devices_provider_impl.h"
- #include "components/browser_sync/browser_sync_switches.h"
- #include "components/sync/base/model_type.h"
- namespace browser_sync {
- ActiveDevicesProviderImpl::ActiveDevicesProviderImpl(
- syncer::DeviceInfoTracker* device_info_tracker,
- base::Clock* clock)
- : device_info_tracker_(device_info_tracker), clock_(clock) {
- DCHECK(device_info_tracker_);
- device_info_tracker_->AddObserver(this);
- }
- ActiveDevicesProviderImpl::~ActiveDevicesProviderImpl() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(callback_.is_null());
- device_info_tracker_->RemoveObserver(this);
- }
- syncer::ActiveDevicesInvalidationInfo
- ActiveDevicesProviderImpl::CalculateInvalidationInfo(
- const std::string& local_cache_guid) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- const std::vector<std::unique_ptr<syncer::DeviceInfo>> active_devices =
- GetActiveDevicesSortedByUpdateTime();
- if (active_devices.empty()) {
- // This may happen if the engine is not initialized yet. In other cases,
- // |active_devices| must contain at least the local device.
- return syncer::ActiveDevicesInvalidationInfo::CreateUninitialized();
- }
- std::vector<std::string> all_fcm_registration_tokens;
- // List of interested data types for all other clients.
- syncer::ModelTypeSet all_interested_data_types;
- // FCM registration tokens with corresponding interested data types for all
- // the clients with enabled sync standalone invalidations.
- std::map<std::string, syncer::ModelTypeSet>
- fcm_token_and_interested_data_types;
- for (const std::unique_ptr<syncer::DeviceInfo>& device : active_devices) {
- if (!local_cache_guid.empty() && device->guid() == local_cache_guid) {
- continue;
- }
- all_interested_data_types.PutAll(device->interested_data_types());
- if (!device->fcm_registration_token().empty()) {
- // If there is a duplicate FCM registration token, use the latest one. To
- // achieve this, rely on sorted |active_devices| by update time. Two
- // DeviceInfo entities can have the same FCM registration token if the
- // sync engine was reset without signout.
- fcm_token_and_interested_data_types[device->fcm_registration_token()] =
- device->interested_data_types();
- if (base::FeatureList::IsEnabled(
- switches::kSyncUseFCMRegistrationTokensList)) {
- all_fcm_registration_tokens.push_back(device->fcm_registration_token());
- }
- }
- }
- // Do not send tokens if the list of active devices is huge. This is similar
- // to the case when the client doesn't know about other devices, so return an
- // empty list. Otherwise the client would return only a part of all active
- // clients and other clients might miss an invalidation.
- if (all_fcm_registration_tokens.size() >
- static_cast<size_t>(
- switches::kSyncFCMRegistrationTokensListMaxSize.Get())) {
- all_fcm_registration_tokens.clear();
- }
- return syncer::ActiveDevicesInvalidationInfo::Create(
- std::move(all_fcm_registration_tokens), all_interested_data_types,
- std::move(fcm_token_and_interested_data_types));
- }
- void ActiveDevicesProviderImpl::SetActiveDevicesChangedCallback(
- ActiveDevicesChangedCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // The |callback_| must not be replaced with another non-null |callback|.
- DCHECK(callback_.is_null() || callback.is_null());
- callback_ = std::move(callback);
- }
- void ActiveDevicesProviderImpl::OnDeviceInfoChange() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (callback_) {
- callback_.Run();
- }
- }
- std::vector<std::unique_ptr<syncer::DeviceInfo>>
- ActiveDevicesProviderImpl::GetActiveDevicesSortedByUpdateTime() const {
- std::vector<std::unique_ptr<syncer::DeviceInfo>> all_devices =
- device_info_tracker_->GetAllDeviceInfo();
- base::ranges::sort(
- all_devices, [](const std::unique_ptr<syncer::DeviceInfo>& left_device,
- const std::unique_ptr<syncer::DeviceInfo>& right_device) {
- return left_device->last_updated_timestamp() <
- right_device->last_updated_timestamp();
- });
- if (!base::FeatureList::IsEnabled(
- switches::kSyncFilterOutInactiveDevicesForSingleClient)) {
- return all_devices;
- }
- base::EraseIf(
- all_devices, [this](const std::unique_ptr<syncer::DeviceInfo>& device) {
- const base::Time expected_expiration_time =
- device->last_updated_timestamp() + device->pulse_interval() +
- switches::kSyncActiveDeviceMargin.Get();
- // If the device's expiration time hasn't been reached, then
- // it is considered active device.
- return expected_expiration_time <= clock_->Now();
- });
- return all_devices;
- }
- } // namespace browser_sync
|