blob: 34aef15549845d4f2ce2a8d0384a1cb8fc973f66 [file] [log] [blame]
// Copyright 2020 The Chromium OS 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 <cstdint>
#include <map>
#include <memory>
#include <set>
#include <vector>
#include <base/memory/weak_ptr.h>
#include <base/synchronization/lock.h>
#include "diagnostics/cros_healthd/fetchers/backlight_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/battery_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/bluetooth_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/cpu_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/disk_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/fan_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/network_fetcher.h"
#include "diagnostics/cros_healthd/fetchers/system_fetcher.h"
#include "diagnostics/cros_healthd/system/context.h"
#include "mojo/cros_healthd.mojom.h"
#include "mojo/cros_healthd_probe.mojom.h"
namespace diagnostics {
// This class is responsible for aggregating probe data from various fetchers,
// some of which may be asynchronous, and running the given callback when all
// probe data has been fetched.
class FetchAggregator final {
explicit FetchAggregator(Context* context);
FetchAggregator(const FetchAggregator&) = delete;
FetchAggregator& operator=(const FetchAggregator&) = delete;
// Runs the aggregator, which will collect all relevant data and then run the
// callback.
void Run(const std::vector<chromeos::cros_healthd::mojom::ProbeCategoryEnum>&
ProbeTelemetryInfoCallback callback);
// Holds all state related to a single call to Run().
struct ProbeState {
// Contains requested categories which have not been fetched yet.
// Callback which will be run once all requested categories have been
// fetched.
ProbeTelemetryInfoCallback callback;
// Holds all fetched data.
chromeos::cros_healthd::mojom::TelemetryInfo fetched_data;
// Wraps a fetch operation from either a synchronous or asynchronous fetcher.
template <class T>
void WrapFetchProbeData(
chromeos::cros_healthd::mojom::ProbeCategoryEnum category,
std::map<uint32_t, std::unique_ptr<ProbeState>>::iterator itr,
T* response_data,
T fetched_data);
// Returns the next available key in |pending_calls_|.
uint32_t GetNextAvailableKey();
// Maps call state to individual calls to Run(). This allows a single
// FetchAggregator instance to have multiple pending asychronous fetches
// corresponding to distinct Run() calls.
std::map<uint32_t, std::unique_ptr<ProbeState>> pending_calls_;
// Protects against one fetcher setting the last bit of a |fetched_data| map
// to true while another fetcher reads it. Without the lock, the reading
// fetcher would then take ownership of the callback and run it, then the
// setting fetcher would later attempt to run the invalid callback a second
// time.
base::Lock lock_;
// Unowned. The backlight fetcher should outlive this instance.
std::unique_ptr<BacklightFetcher> const backlight_fetcher_ = nullptr;
// Unowned. The battery fetcher should outlive this instance.
std::unique_ptr<BatteryFetcher> const battery_fetcher_ = nullptr;
// Unowned. The Bluetooth fetcher should outlive this instance.
std::unique_ptr<BluetoothFetcher> const bluetooth_fetcher_ = nullptr;
// Unowned. The CPU fetcher should outlive this instance.
std::unique_ptr<CpuFetcher> const cpu_fetcher_ = nullptr;
// Unowned. The disk fetcher should outlive this instance.
std::unique_ptr<DiskFetcher> const disk_fetcher_ = nullptr;
// Unowned. The fan fetcher should outlive this instance.
std::unique_ptr<FanFetcher> const fan_fetcher_ = nullptr;
// Unowned. The system fetcher should outlive this instance.
std::unique_ptr<SystemFetcher> const system_fetcher_ = nullptr;
// Unowned. The network fetcher should outlive this instance.
std::unique_ptr<NetworkFetcher> const network_fetcher_ = nullptr;
// Must be the last member of the class.
base::WeakPtrFactory<FetchAggregator> weak_factory_{this};
} // namespace diagnostics