blob: 39d74f60b5806dccc17c542644c7abab12bbea87 [file] [log] [blame]
// Copyright 2019 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/board_info_provider.h"
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <optional>
#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/developer/forensics/utils/fit/promise.h"
#include "src/lib/fxl/strings/join_strings.h"
namespace forensics {
namespace feedback_data {
namespace {
using fuchsia::hwinfo::BoardInfo;
const AnnotationKeys kSupportedAnnotations = {
kAnnotationHardwareBoardName,
kAnnotationHardwareBoardRevision,
};
} // namespace
BoardInfoProvider::BoardInfoProvider(async_dispatcher_t* dispatcher,
std::shared_ptr<sys::ServiceDirectory> services,
cobalt::Logger* cobalt)
: dispatcher_(dispatcher),
services_(services),
cobalt_(cobalt),
board_ptr_(dispatcher_, services_, [this] { GetInfo(); }) {}
::fit::promise<Annotations> BoardInfoProvider::GetAnnotations(zx::duration timeout,
const AnnotationKeys& allowlist) {
const AnnotationKeys annotations_to_get = RestrictAllowlist(allowlist, kSupportedAnnotations);
if (annotations_to_get.empty()) {
return ::fit::make_result_promise<Annotations>(::fit::ok<Annotations>({}));
}
return board_ptr_
.GetValue(fit::Timeout(
timeout,
/*action*/ [=] { cobalt_->LogOccurrence(cobalt::TimedOutData::kBoardInfo); }))
.then([=](const ::fit::result<std::map<AnnotationKey, std::string>, Error>& result) {
Annotations annotations;
if (result.is_error()) {
for (const auto& key : annotations_to_get) {
annotations.insert({key, AnnotationOr(result.error())});
}
} else {
for (const auto& key : annotations_to_get) {
const auto& board_info = result.value();
if (board_info.find(key) == board_info.end()) {
annotations.insert({key, AnnotationOr(Error::kMissingValue)});
} else {
annotations.insert({key, board_info.at(key)});
}
}
}
return ::fit::ok(std::move(annotations));
});
}
void BoardInfoProvider::GetInfo() {
board_ptr_->GetInfo([this](BoardInfo info) {
std::map<AnnotationKey, std::string> board_info;
if (info.has_name()) {
board_info[kAnnotationHardwareBoardName] = info.name();
}
if (info.has_revision()) {
board_info[kAnnotationHardwareBoardRevision] = info.revision();
}
board_ptr_.SetValue(board_info);
});
}
} // namespace feedback_data
} // namespace forensics