blob: 3a0c905d5f7088de5853457d0c60b0214063abac [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_DOWNLOAD_MANAGER_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_DOWNLOAD_MANAGER_H_
#include <map>
#include <memory>
#include <set>
#include "src/developer/debug/zxdb/client/symbol_server.h"
#include "src/developer/debug/zxdb/client/system_observer.h"
#include "src/developer/debug/zxdb/symbols/debug_symbol_file_type.h"
#include "src/lib/fxl/memory/weak_ptr.h"
namespace zxdb {
class Download;
class System;
// This class manages all downloads that are requested when they are not found locally.
class DownloadManager : public SystemObserver {
public:
explicit DownloadManager(System* system);
~DownloadManager();
// Requests to download |build_id| from any remote source, the first returning a valid symbol file
// with a matching build id will be loaded. |file_type| determines whether the file should be a
// binary with symbols or a separate file with a ".debug" suffix with just debug info and no
// binary information.
void RequestDownload(const std::string& build_id, DebugSymbolFileType file_type);
bool HasDownload(const std::string& build_id) const;
// SystemObserver implementation.
void DidCreateSymbolServer(SymbolServer* server) override;
void OnSymbolServerStatusChanged(SymbolServer* server) override;
// Get a test download object.
Download* InjectDownloadForTesting(const std::string& build_id);
// Abandons a download injected with |InjectDownloadForTesting|.
void AbandonTestingDownload(const std::string& build_id);
bool DownloadsInProgress() const { return !downloads_.empty(); }
private:
using DownloadIdentifier = std::pair<std::string, DebugSymbolFileType>;
// Get a download object corresponding to |build_id| and |file_type|. If no matching object is
// found, a new one is allocated and will request a download against all configured and ready
// symbol servers.
Download* GetDownload(std::string build_id, DebugSymbolFileType file_type);
// Creates a Download object with the given |build_id| and |file_type|, note the caller is
// responsible for adding the resulting pointer to |downloads_|.
std::unique_ptr<Download> MakeDownload(const std::string& build_id,
DebugSymbolFileType file_type);
// A download succeeded,
void OnDownloadSucceeded(const std::string& path, const std::string& build_id,
DebugSymbolFileType file_type);
// Adds |server| to the download object associated with any modules that are missing
// symbols in the current process.
void OnSymbolServerBecomesReady(SymbolServer* server);
// Called every time a new download starts.
void DownloadStarted(const DownloadIdentifier& dl_id, Download* download);
// Called every time a download ends.
void DownloadFinished();
size_t download_count_ = 0;
size_t download_success_count_ = 0;
size_t download_fail_count_ = 0;
size_t servers_ready_ = 0;
// These servers have failed to authenticate and will never become ready.
size_t servers_failed_auth_ = 0;
// These servers accountered repeated errors and will never becomre ready again.
size_t servers_unreachable_ = 0;
// Downloads currently in progress or pending server availability. This holds an owning pointer to
// the Download object so it can be persisted while we wait for servers to become ready.
std::map<DownloadIdentifier, std::unique_ptr<Download>> downloads_;
System* system_; // owns |this|.
fxl::WeakPtrFactory<DownloadManager> weak_factory_;
};
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_DOWNLOAD_MANAGER_H_