chromium/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.h"

#include <limits>

#include "base/feature_list.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/reporting/metrics/sampler.h"
#include "components/reporting/proto/synced/metric_data.pb.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/network/public/cpp/network_quality_tracker.h"

namespace reporting {

// static
BASE_FEATURE(kEnableNetworkBandwidthReporting,
             "EnableNetworkBandwidthReporting",
             base::FEATURE_ENABLED_BY_DEFAULT);

NetworkBandwidthSampler::NetworkBandwidthSampler(
    ::network::NetworkQualityTracker* network_quality_tracker,
    base::WeakPtr<Profile> profile)
    : network_quality_tracker_(network_quality_tracker), profile_(profile) {
  CHECK(network_quality_tracker_);
  CHECK(profile_);
}

NetworkBandwidthSampler::~NetworkBandwidthSampler() = default;

void NetworkBandwidthSampler::MaybeCollect(OptionalMetricCallback callback) {
  if (!::content::BrowserThread::CurrentlyOn(::content::BrowserThread::UI)) {
    ::content::GetUIThreadTaskRunner({})->PostTask(
        FROM_HERE,
        base::BindOnce(&NetworkBandwidthSampler::MaybeCollect,
                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
    return;
  }
  if (!profile_) {
    // Profile destructed so we collect no data.
    std::move(callback).Run(std::nullopt);
    return;
  }
  if (!profile_->GetPrefs()->GetBoolean(::prefs::kInsightsExtensionEnabled) &&
      !base::FeatureList::IsEnabled(kEnableNetworkBandwidthReporting)) {
    // Both policy and feature flag not set, so we return.
    std::move(callback).Run(std::nullopt);
    return;
  }

  const auto downlink_speed_kbps =
      network_quality_tracker_->GetDownstreamThroughputKbps();
  if (downlink_speed_kbps == std::numeric_limits<int32_t>::max()) {
    // Network quality tracker returns std::numeric_limits<int32_t>::max() if
    // downstream throughput is unavailable, so we return no data.
    std::move(callback).Run(std::nullopt);
    return;
  }

  MetricData metric_data;
  metric_data.mutable_telemetry_data()
      ->mutable_networks_telemetry()
      ->mutable_bandwidth_data()
      ->set_download_speed_kbps(downlink_speed_kbps);
  std::move(callback).Run(metric_data);
}

}  // namespace reporting