blob: d630d16450ff8f62fc006b91895b00bb65163f8a [file] [log] [blame]
// Copyright 2020 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.
#include "src/developer/forensics/feedback_data/annotations/static_annotations.h"
#include <lib/syslog/cpp/macros.h>
#include <optional>
#include <string>
#include "src/developer/forensics/feedback_data/annotations/board_name_provider.h"
#include "src/developer/forensics/feedback_data/annotations/types.h"
#include "src/developer/forensics/feedback_data/annotations/utils.h"
#include "src/developer/forensics/feedback_data/constants.h"
#include "src/developer/forensics/utils/errors.h"
#include "src/lib/files/file.h"
#include "src/lib/fxl/strings/trim.h"
namespace forensics {
namespace feedback_data {
namespace {
const AnnotationKeys kSupportedAnnotations = {
kAnnotationBuildBoard,
kAnnotationBuildProduct,
kAnnotationBuildLatestCommitDate,
kAnnotationBuildVersion,
kAnnotationBuildIsDebug,
kAnnotationDeviceBoardName,
kAnnotationSystemBootIdCurrent,
kAnnotationSystemBootIdPrevious,
};
AnnotationOr ReadStringFromFilepath(const std::string& filepath) {
std::string content;
if (!files::ReadFileToString(filepath, &content)) {
return AnnotationOr(Error::kFileReadFailure);
}
return AnnotationOr(std::string(fxl::TrimString(content, "\r\n")));
}
AnnotationOr ReadAnnotationOrFromFilepath(const AnnotationKey& key, const std::string& filepath) {
const auto value = ReadStringFromFilepath(filepath);
return value;
}
AnnotationOr BuildAnnotationOr(const AnnotationKey& key, const PreviousBootFile boot_id_file) {
if (key == kAnnotationBuildBoard) {
return ReadAnnotationOrFromFilepath(key, "/config/build-info/board");
} else if (key == kAnnotationBuildProduct) {
return ReadAnnotationOrFromFilepath(key, "/config/build-info/product");
} else if (key == kAnnotationBuildLatestCommitDate) {
return ReadAnnotationOrFromFilepath(key, "/config/build-info/latest-commit-date");
} else if (key == kAnnotationBuildVersion) {
return ReadAnnotationOrFromFilepath(key, "/config/build-info/version");
} else if (key == kAnnotationBuildIsDebug) {
#ifndef NDEBUG
return AnnotationOr("true");
#else
return AnnotationOr("false");
#endif
} else if (key == kAnnotationDeviceBoardName) {
return GetBoardName();
} else if (key == kAnnotationSystemBootIdCurrent) {
return ReadAnnotationOrFromFilepath(key, boot_id_file.CurrentBootPath());
} else if (key == kAnnotationSystemBootIdPrevious) {
return ReadAnnotationOrFromFilepath(key, boot_id_file.PreviousBootPath());
}
// We should never attempt to build a non-static annotation as a static annotation.
FX_LOGS(FATAL) << "Attempting to get non-static annotation " << key << " as a static annotation";
return AnnotationOr(Error::kNotSet);
}
} // namespace
Annotations GetStaticAnnotations(const AnnotationKeys& allowlist,
const PreviousBootFile boot_id_file) {
Annotations annotations;
for (const auto& key : RestrictAllowlist(allowlist, kSupportedAnnotations)) {
annotations.insert({key, BuildAnnotationOr(key, boot_id_file)});
}
return annotations;
}
} // namespace feedback_data
} // namespace forensics