| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/dbus/missive/history_tracker.h" |
| |
| #include <atomic> |
| |
| #include "base/functional/callback_forward.h" |
| #include "base/logging.h" |
| #include "base/task/thread_pool.h" |
| #include "components/reporting/proto/synced/health.pb.h" |
| |
| namespace reporting { |
| |
| HistoryTracker::HistoryTracker( |
| scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner) |
| : sequenced_task_runner_(sequenced_task_runner) { |
| DETACH_FROM_SEQUENCE(sequence_checker_); |
| } |
| |
| HistoryTracker::~HistoryTracker() = default; |
| |
| // static |
| HistoryTracker* HistoryTracker::Get() { |
| static HistoryTracker tracker{ |
| base::ThreadPool::CreateSequencedTaskRunner({})}; |
| return &tracker; |
| } |
| |
| void HistoryTracker::AddObserver(HistoryTracker::Observer* observer) { |
| sequenced_task_runner_->PostTask( |
| FROM_HERE, |
| base::BindOnce( |
| [](HistoryTracker::Observer* observer) { |
| auto* const tracker = HistoryTracker::Get(); |
| DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); |
| tracker->observer_list_.AddObserver(observer); |
| }, |
| observer)); |
| } |
| |
| void HistoryTracker::RemoveObserver(const HistoryTracker::Observer* observer) { |
| sequenced_task_runner_->PostTask( |
| FROM_HERE, |
| base::BindOnce( |
| [](const HistoryTracker::Observer* observer) { |
| auto* const tracker = HistoryTracker::Get(); |
| DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); |
| tracker->observer_list_.RemoveObserver(observer); |
| }, |
| observer)); |
| } |
| |
| bool HistoryTracker::debug_state() const { |
| return debug_state_.load(); |
| } |
| |
| void HistoryTracker::set_debug_state(bool state) { |
| const bool old_state = debug_state_.exchange(state); |
| LOG_IF(WARNING, old_state != state) |
| << "Debug state " << (state ? "enabled" : "disabled"); |
| } |
| |
| void HistoryTracker::retrieve_data( |
| base::OnceCallback<void(const ERPHealthData&)> cb) { |
| sequenced_task_runner_->PostTaskAndReplyWithResult( |
| FROM_HERE, base::BindOnce([]() { |
| auto* const tracker = HistoryTracker::Get(); |
| DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); |
| return tracker->data_; |
| }), |
| std::move(cb)); // Call cb(tracker->data_) on the current thread. |
| } |
| |
| void HistoryTracker::set_data(ERPHealthData data, base::OnceClosure cb) { |
| sequenced_task_runner_->PostTaskAndReply( |
| FROM_HERE, |
| base::BindOnce( |
| [](ERPHealthData data) { |
| auto* const tracker = HistoryTracker::Get(); |
| DCHECK_CALLED_ON_VALID_SEQUENCE(tracker->sequence_checker_); |
| tracker->data_ = std::move(data); |
| for (const auto& observer : tracker->observer_list_) { |
| observer.OnNewData(tracker->data_); |
| } |
| }, |
| std::move(data)), |
| std::move(cb)); // Call cb() on the current thread. |
| } |
| } // namespace reporting |