| // Copyright 2021 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 "ash/quick_pair/keyed_service/quick_pair_mediator.h" |
| |
| #include <cstdint> |
| #include <memory> |
| |
| #include "ash/quick_pair/common/device.h" |
| #include "ash/quick_pair/common/logging.h" |
| #include "ash/quick_pair/fast_pair_handshake/fast_pair_handshake_lookup.h" |
| #include "ash/quick_pair/feature_status_tracker/fast_pair_pref_enabled_provider.h" |
| #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker.h" |
| #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker_impl.h" |
| #include "ash/quick_pair/keyed_service/battery_update_message_handler.h" |
| #include "ash/quick_pair/keyed_service/fast_pair_bluetooth_config_delegate.h" |
| #include "ash/quick_pair/keyed_service/quick_pair_metrics_logger.h" |
| #include "ash/quick_pair/message_stream/message_stream_lookup.h" |
| #include "ash/quick_pair/message_stream/message_stream_lookup_impl.h" |
| #include "ash/quick_pair/pairing/pairer_broker_impl.h" |
| #include "ash/quick_pair/pairing/retroactive_pairing_detector_impl.h" |
| #include "ash/quick_pair/repository/fast_pair/device_id_map.h" |
| #include "ash/quick_pair/repository/fast_pair/device_image_store.h" |
| #include "ash/quick_pair/repository/fast_pair/pending_write_store.h" |
| #include "ash/quick_pair/repository/fast_pair/saved_device_registry.h" |
| #include "ash/quick_pair/repository/fast_pair_repository_impl.h" |
| #include "ash/quick_pair/scanning/scanner_broker_impl.h" |
| #include "ash/quick_pair/ui/actions.h" |
| #include "ash/quick_pair/ui/ui_broker_impl.h" |
| #include "ash/services/quick_pair/quick_pair_process.h" |
| #include "ash/services/quick_pair/quick_pair_process_manager_impl.h" |
| #include "chromeos/services/bluetooth_config/fast_pair_delegate.h" |
| #include "components/prefs/pref_registry_simple.h" |
| |
| namespace ash { |
| namespace quick_pair { |
| |
| namespace { |
| |
| Mediator::Factory* g_test_factory = nullptr; |
| |
| } |
| |
| // static |
| std::unique_ptr<Mediator> Mediator::Factory::Create() { |
| if (g_test_factory) |
| return g_test_factory->BuildInstance(); |
| |
| auto process_manager = std::make_unique<QuickPairProcessManagerImpl>(); |
| auto pairer_broker = std::make_unique<PairerBrokerImpl>(); |
| auto message_stream_lookup = std::make_unique<MessageStreamLookupImpl>(); |
| |
| return std::make_unique<Mediator>( |
| std::make_unique<FeatureStatusTrackerImpl>(), |
| std::make_unique<ScannerBrokerImpl>(process_manager.get()), |
| std::make_unique<RetroactivePairingDetectorImpl>( |
| pairer_broker.get(), message_stream_lookup.get()), |
| std::move(message_stream_lookup), std::move(pairer_broker), |
| std::make_unique<UIBrokerImpl>(), |
| std::make_unique<FastPairRepositoryImpl>(), std::move(process_manager)); |
| } |
| |
| // static |
| void Mediator::Factory::SetFactoryForTesting(Factory* factory) { |
| g_test_factory = factory; |
| } |
| |
| Mediator::Mediator( |
| std::unique_ptr<FeatureStatusTracker> feature_status_tracker, |
| std::unique_ptr<ScannerBroker> scanner_broker, |
| std::unique_ptr<RetroactivePairingDetector> retroactive_pairing_detector, |
| std::unique_ptr<MessageStreamLookup> message_stream_lookup, |
| std::unique_ptr<PairerBroker> pairer_broker, |
| std::unique_ptr<UIBroker> ui_broker, |
| std::unique_ptr<FastPairRepository> fast_pair_repository, |
| std::unique_ptr<QuickPairProcessManager> process_manager) |
| : feature_status_tracker_(std::move(feature_status_tracker)), |
| scanner_broker_(std::move(scanner_broker)), |
| message_stream_lookup_(std::move(message_stream_lookup)), |
| pairer_broker_(std::move(pairer_broker)), |
| retroactive_pairing_detector_(std::move(retroactive_pairing_detector)), |
| ui_broker_(std::move(ui_broker)), |
| fast_pair_repository_(std::move(fast_pair_repository)), |
| process_manager_(std::move(process_manager)), |
| fast_pair_bluetooth_config_delegate_( |
| std::make_unique<FastPairBluetoothConfigDelegate>()) { |
| metrics_logger_ = std::make_unique<QuickPairMetricsLogger>( |
| scanner_broker_.get(), pairer_broker_.get(), ui_broker_.get(), |
| retroactive_pairing_detector_.get()); |
| battery_update_message_handler_ = |
| std::make_unique<BatteryUpdateMessageHandler>( |
| message_stream_lookup_.get()); |
| feature_status_tracker_observation_.Observe(feature_status_tracker_.get()); |
| scanner_broker_observation_.Observe(scanner_broker_.get()); |
| retroactive_pairing_detector_observation_.Observe( |
| retroactive_pairing_detector_.get()); |
| pairer_broker_observation_.Observe(pairer_broker_.get()); |
| ui_broker_observation_.Observe(ui_broker_.get()); |
| |
| SetFastPairState(feature_status_tracker_->IsFastPairEnabled()); |
| quick_pair_process::SetProcessManager(process_manager_.get()); |
| } |
| |
| Mediator::~Mediator() { |
| // The metrics logger must be deleted first because it depends on other |
| // members. |
| metrics_logger_.reset(); |
| } |
| |
| // static |
| void Mediator::RegisterProfilePrefs(PrefRegistrySimple* registry) { |
| FastPairPrefEnabledProvider::RegisterProfilePrefs(registry); |
| SavedDeviceRegistry::RegisterProfilePrefs(registry); |
| PendingWriteStore::RegisterProfilePrefs(registry); |
| } |
| |
| // static |
| void Mediator::RegisterLocalStatePrefs(PrefRegistrySimple* registry) { |
| DeviceIdMap::RegisterLocalStatePrefs(registry); |
| DeviceImageStore::RegisterLocalStatePrefs(registry); |
| } |
| |
| chromeos::bluetooth_config::FastPairDelegate* Mediator::GetFastPairDelegate() { |
| return fast_pair_bluetooth_config_delegate_.get(); |
| } |
| |
| void Mediator::OnFastPairEnabledChanged(bool is_enabled) { |
| SetFastPairState(is_enabled); |
| } |
| |
| void Mediator::OnDeviceFound(scoped_refptr<Device> device) { |
| QP_LOG(INFO) << __func__ << ": " << device; |
| // On discovery, download and decode device images. |
| ui_broker_->ShowDiscovery(device); |
| fast_pair_repository_->FetchDeviceImages(device); |
| } |
| |
| void Mediator::OnDeviceLost(scoped_refptr<Device> device) { |
| QP_LOG(INFO) << __func__ << ": " << device; |
| ui_broker_->RemoveNotifications(device); |
| FastPairHandshakeLookup::GetInstance()->Erase(device); |
| } |
| |
| void Mediator::OnRetroactivePairFound(scoped_refptr<Device> device) { |
| QP_LOG(INFO) << __func__ << ": " << device; |
| ui_broker_->ShowAssociateAccount(std::move(device)); |
| } |
| |
| void Mediator::SetFastPairState(bool is_enabled) { |
| QP_LOG(VERBOSE) << __func__ << ": " << is_enabled; |
| |
| if (is_enabled) |
| scanner_broker_->StartScanning(Protocol::kFastPairInitial); |
| else |
| scanner_broker_->StopScanning(Protocol::kFastPairInitial); |
| } |
| |
| void Mediator::OnDevicePaired(scoped_refptr<Device> device) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device; |
| ui_broker_->RemoveNotifications(device); |
| fast_pair_repository_->PersistDeviceImages(device); |
| } |
| |
| void Mediator::OnPairFailure(scoped_refptr<Device> device, |
| PairFailure failure) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device << ",Failure=" << failure; |
| ui_broker_->ShowPairingFailed(std::move(device)); |
| } |
| |
| void Mediator::OnAccountKeyWrite(scoped_refptr<Device> device, |
| absl::optional<AccountKeyFailure> error) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device; |
| } |
| |
| void Mediator::OnDiscoveryAction(scoped_refptr<Device> device, |
| DiscoveryAction action) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device << ", Action=" << action; |
| |
| switch (action) { |
| case DiscoveryAction::kPairToDevice: { |
| absl::optional<std::vector<uint8_t>> additional_data = |
| device->GetAdditionalData( |
| Device::AdditionalDataType::kFastPairVersion); |
| |
| // Skip showing the in-progress UI for Fast Pair v1 because that pairing |
| // is not handled by us E2E. |
| if (!additional_data.has_value() || additional_data->size() != 1 || |
| (*additional_data)[0] != 1) { |
| ui_broker_->ShowPairing(device); |
| } |
| |
| pairer_broker_->PairDevice(device); |
| } break; |
| case DiscoveryAction::kDismissedByUser: |
| case DiscoveryAction::kDismissed: |
| break; |
| } |
| } |
| |
| void Mediator::OnPairingFailureAction(scoped_refptr<Device> device, |
| PairingFailedAction action) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device << ", Action=" << action; |
| } |
| |
| void Mediator::OnCompanionAppAction(scoped_refptr<Device> device, |
| CompanionAppAction action) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device << ", Action=" << action; |
| } |
| |
| void Mediator::OnAssociateAccountAction(scoped_refptr<Device> device, |
| AssociateAccountAction action) { |
| QP_LOG(INFO) << __func__ << ": Device=" << device << ", Action=" << action; |
| |
| switch (action) { |
| case AssociateAccountAction::kAssoicateAccount: |
| pairer_broker_->PairDevice(device); |
| break; |
| case AssociateAccountAction::kLearnMore: |
| break; |
| case AssociateAccountAction::kDismissedByUser: |
| case AssociateAccountAction::kDismissed: |
| break; |
| } |
| } |
| |
| } // namespace quick_pair |
| } // namespace ash |