host_status_provider_impl.cc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2018 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. #include "ash/services/multidevice_setup/host_status_provider_impl.h"
  5. #include <algorithm>
  6. #include "ash/components/multidevice/logging/logging.h"
  7. #include "ash/services/multidevice_setup/eligible_host_devices_provider.h"
  8. #include "base/bind.h"
  9. #include "base/memory/ptr_util.h"
  10. #include "base/metrics/histogram_functions.h"
  11. #include "base/time/time.h"
  12. namespace ash {
  13. namespace multidevice_setup {
  14. namespace {
  15. constexpr base::TimeDelta kHostStatusLoggingPeriod = base::Minutes(30);
  16. } // namespace
  17. // static
  18. HostStatusProviderImpl::Factory*
  19. HostStatusProviderImpl::Factory::test_factory_ = nullptr;
  20. // static
  21. std::unique_ptr<HostStatusProvider> HostStatusProviderImpl::Factory::Create(
  22. EligibleHostDevicesProvider* eligible_host_devices_provider,
  23. HostBackendDelegate* host_backend_delegate,
  24. HostVerifier* host_verifier,
  25. device_sync::DeviceSyncClient* device_sync_client) {
  26. if (test_factory_) {
  27. return test_factory_->CreateInstance(eligible_host_devices_provider,
  28. host_backend_delegate, host_verifier,
  29. device_sync_client);
  30. }
  31. return base::WrapUnique(new HostStatusProviderImpl(
  32. eligible_host_devices_provider, host_backend_delegate, host_verifier,
  33. device_sync_client));
  34. }
  35. // static
  36. void HostStatusProviderImpl::Factory::SetFactoryForTesting(
  37. Factory* test_factory) {
  38. test_factory_ = test_factory;
  39. }
  40. HostStatusProviderImpl::Factory::~Factory() = default;
  41. HostStatusProviderImpl::HostStatusProviderImpl(
  42. EligibleHostDevicesProvider* eligible_host_devices_provider,
  43. HostBackendDelegate* host_backend_delegate,
  44. HostVerifier* host_verifier,
  45. device_sync::DeviceSyncClient* device_sync_client)
  46. : eligible_host_devices_provider_(eligible_host_devices_provider),
  47. host_backend_delegate_(host_backend_delegate),
  48. host_verifier_(host_verifier),
  49. device_sync_client_(device_sync_client),
  50. current_status_and_device_(mojom::HostStatus::kNoEligibleHosts,
  51. absl::nullopt /* host_device */) {
  52. host_backend_delegate_->AddObserver(this);
  53. host_verifier_->AddObserver(this);
  54. device_sync_client_->AddObserver(this);
  55. CheckForUpdatedStatusAndNotifyIfChanged(
  56. /*force_notify_host_status_change=*/false);
  57. RecordMultiDeviceHostStatus();
  58. host_status_metric_timer_.Start(
  59. FROM_HERE, kHostStatusLoggingPeriod,
  60. base::BindRepeating(&HostStatusProviderImpl::RecordMultiDeviceHostStatus,
  61. base::Unretained(this)));
  62. }
  63. HostStatusProviderImpl::~HostStatusProviderImpl() {
  64. host_backend_delegate_->RemoveObserver(this);
  65. host_verifier_->RemoveObserver(this);
  66. device_sync_client_->RemoveObserver(this);
  67. }
  68. HostStatusProvider::HostStatusWithDevice
  69. HostStatusProviderImpl::GetHostWithStatus() const {
  70. return current_status_and_device_;
  71. }
  72. void HostStatusProviderImpl::OnHostChangedOnBackend() {
  73. CheckForUpdatedStatusAndNotifyIfChanged(
  74. /*force_notify_host_status_change=*/false);
  75. }
  76. void HostStatusProviderImpl::OnPendingHostRequestChange() {
  77. CheckForUpdatedStatusAndNotifyIfChanged(
  78. /*force_notify_host_status_change=*/false);
  79. }
  80. void HostStatusProviderImpl::OnHostVerified() {
  81. CheckForUpdatedStatusAndNotifyIfChanged(
  82. /*force_notify_host_status_change=*/false);
  83. }
  84. void HostStatusProviderImpl::OnNewDevicesSynced() {
  85. CheckForUpdatedStatusAndNotifyIfChanged(
  86. /*force_notify_host_status_change=*/true);
  87. }
  88. void HostStatusProviderImpl::CheckForUpdatedStatusAndNotifyIfChanged(
  89. bool force_notify_host_status_change) {
  90. HostStatusWithDevice current_status_and_device = GetCurrentStatus();
  91. if (current_status_and_device == current_status_and_device_) {
  92. if (force_notify_host_status_change) {
  93. // If the RemoteDevice the host device references has changed, but not its
  94. // contents, fire a host status change. Note that since the status doesn't
  95. // actually change, neither logging nor metric collection should occur.
  96. NotifyHostStatusChange(current_status_and_device_.host_status(),
  97. current_status_and_device_.host_device());
  98. }
  99. return;
  100. }
  101. PA_LOG(INFO) << "HostStatusProviderImpl::"
  102. << "CheckForUpdatedStatusAndNotifyIfChanged(): Host status "
  103. << "changed. New status: "
  104. << current_status_and_device.host_status()
  105. << ", Old status: " << current_status_and_device_.host_status()
  106. << ", Host device: "
  107. << (current_status_and_device.host_device()
  108. ? current_status_and_device.host_device()
  109. ->GetInstanceIdDeviceIdForLogs()
  110. : "[no host]");
  111. current_status_and_device_ = current_status_and_device;
  112. NotifyHostStatusChange(current_status_and_device_.host_status(),
  113. current_status_and_device_.host_device());
  114. RecordMultiDeviceHostStatus();
  115. }
  116. HostStatusProvider::HostStatusWithDevice
  117. HostStatusProviderImpl::GetCurrentStatus() {
  118. if (host_verifier_->IsHostVerified()) {
  119. return HostStatusWithDevice(
  120. mojom::HostStatus::kHostVerified,
  121. *host_backend_delegate_->GetMultiDeviceHostFromBackend());
  122. }
  123. if (host_backend_delegate_->GetMultiDeviceHostFromBackend() &&
  124. !host_backend_delegate_->HasPendingHostRequest()) {
  125. return HostStatusWithDevice(
  126. mojom::HostStatus::kHostSetButNotYetVerified,
  127. *host_backend_delegate_->GetMultiDeviceHostFromBackend());
  128. }
  129. if (host_backend_delegate_->HasPendingHostRequest() &&
  130. host_backend_delegate_->GetPendingHostRequest()) {
  131. return HostStatusWithDevice(
  132. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  133. *host_backend_delegate_->GetPendingHostRequest());
  134. }
  135. if (!eligible_host_devices_provider_->GetEligibleHostDevices().empty()) {
  136. return HostStatusWithDevice(
  137. mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  138. absl::nullopt /* host_device */);
  139. }
  140. return HostStatusWithDevice(mojom::HostStatus::kNoEligibleHosts,
  141. absl::nullopt /* host_device */);
  142. }
  143. void HostStatusProviderImpl::RecordMultiDeviceHostStatus() {
  144. base::UmaHistogramEnumeration("MultiDevice.Setup.HostStatus",
  145. current_status_and_device_.host_status());
  146. }
  147. } // namespace multidevice_setup
  148. } // namespace ash