| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/hud_display/ash_tracing_manager.h" |
| |
| #include <vector> |
| |
| #include "ash/hud_display/ash_tracing_request.h" |
| #include "ash/session/session_controller_impl.h" |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| #include "base/no_destructor.h" |
| #include "base/sequence_checker.h" |
| #include "base/strings/stringprintf.h" |
| |
| namespace ash { |
| namespace hud_display { |
| |
| AshTracingManager::AshTracingManager() { |
| SessionController::Get()->AddObserver(this); |
| } |
| |
| AshTracingManager::~AshTracingManager() { |
| if (SessionController::Get()) |
| SessionController::Get()->RemoveObserver(this); |
| } |
| |
| // static |
| AshTracingManager& AshTracingManager::Get() { |
| static base::NoDestructor<AshTracingManager> manager; |
| return *manager; |
| } |
| |
| bool AshTracingManager::IsBusy() const { |
| if (tracing_requests_.empty()) |
| return false; |
| |
| switch (GetLastRequestStatus()) { |
| case AshTracingRequest::Status::kEmpty: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kInitialized: |
| return true; |
| case AshTracingRequest::Status::kStarted: |
| return false; |
| case AshTracingRequest::Status::kStopping: |
| return true; |
| case AshTracingRequest::Status::kPendingMount: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kWritingFile: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kCompleted: |
| return false; |
| } |
| } |
| |
| bool AshTracingManager::IsTracingStarted() const { |
| if (tracing_requests_.empty()) |
| return false; |
| |
| switch (GetLastRequestStatus()) { |
| case AshTracingRequest::Status::kEmpty: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kInitialized: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kStarted: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kStopping: |
| return true; |
| case AshTracingRequest::Status::kPendingMount: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kWritingFile: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kCompleted: |
| return false; |
| } |
| } |
| |
| std::string AshTracingManager::GetStatusMessage() const { |
| std::string result; |
| if (tracing_requests_.empty()) |
| return result; |
| |
| unsigned started = 0; |
| unsigned waiting_for_login = 0; |
| unsigned writing_trace_file = 0; |
| unsigned completed = 0; |
| for (const auto& request : tracing_requests_) { |
| switch (request->status()) { |
| case AshTracingRequest::Status::kEmpty: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kInitialized: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kStarted: |
| [[fallthrough]]; |
| case AshTracingRequest::Status::kStopping: |
| ++started; |
| break; |
| case AshTracingRequest::Status::kPendingMount: |
| ++waiting_for_login; |
| break; |
| case AshTracingRequest::Status::kWritingFile: |
| ++writing_trace_file; |
| break; |
| case AshTracingRequest::Status::kCompleted: |
| ++completed; |
| } |
| } |
| if (started) |
| result = base::StringPrintf("%u active", started); |
| |
| if (waiting_for_login) { |
| if (!result.empty()) |
| result += ", "; |
| |
| result += base::StringPrintf("%u pending login", waiting_for_login); |
| } |
| if (writing_trace_file) { |
| if (!result.empty()) |
| result += ", "; |
| |
| result += base::StringPrintf("%u writing", writing_trace_file); |
| } |
| if (completed) { |
| if (!result.empty()) |
| result += ", "; |
| |
| result += base::StringPrintf("%u completed", completed); |
| } |
| if (!result.empty()) |
| result = std::string("Tracing: ") + result + "."; |
| |
| return result; |
| } |
| |
| void AshTracingManager::Start() { |
| DCHECK(!IsBusy()); |
| DCHECK(!IsTracingStarted()); |
| tracing_requests_.push_back(std::make_unique<AshTracingRequest>(this)); |
| } |
| |
| void AshTracingManager::Stop() { |
| DCHECK(!tracing_requests_.empty()); |
| DCHECK_EQ(GetLastRequestStatus(), AshTracingRequest::Status::kStarted); |
| tracing_requests_.back()->Stop(); |
| } |
| |
| void AshTracingManager::AddObserver(AshTracingManager::Observer* observer) { |
| observers_.AddObserver(observer); |
| } |
| |
| void AshTracingManager::RemoveObserver(AshTracingManager::Observer* observer) { |
| observers_.RemoveObserver(observer); |
| } |
| |
| void AshTracingManager::OnRequestStatusChanged(AshTracingRequest* request) { |
| for (Observer& observer : observers_) |
| observer.OnTracingStatusChange(); |
| } |
| |
| void AshTracingManager::OnFirstSessionStarted() { |
| for (auto& request : tracing_requests_) |
| request->OnUserLoggedIn(); |
| } |
| |
| const std::vector<std::unique_ptr<AshTracingRequest>>& |
| AshTracingManager::GetTracingRequestsForTesting() const { |
| return tracing_requests_; |
| } |
| |
| AshTracingRequest::Status AshTracingManager::GetLastRequestStatus() const { |
| return tracing_requests_.back()->status(); |
| } |
| |
| } // namespace hud_display |
| } // namespace ash |