blob: 1d027d513571dd7be4310bdebee42b9fb6e28ecc [file] [log] [blame]
// Copyright 2020 The Chromium OS 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 "diagnostics/cros_healthd/fetchers/backlight_fetcher.h"
#include <string>
#include <utility>
#include <base/files/file_enumerator.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/strings/string_number_conversions.h>
#include "diagnostics/cros_healthd/utils/error_utils.h"
#include "diagnostics/cros_healthd/utils/file_utils.h"
namespace diagnostics {
namespace {
namespace mojo_ipc = ::chromeos::cros_healthd::mojom;
constexpr char kRelativeBacklightDirectoryPath[] = "sys/class/backlight";
// Fetches backlight information for a specific sysfs path. On success,
// populates |output_info| with the fetched information and returns a
// base::nullopt. When an error occurs, a ProbeError is returned and
// |output_info| does not contain valid information.
base::Optional<mojo_ipc::ProbeErrorPtr> FetchBacklightInfoForPath(
const base::FilePath& path, mojo_ipc::BacklightInfoPtr* output_info) {
DCHECK(output_info);
mojo_ipc::BacklightInfo info;
info.path = path.value();
if (!ReadInteger(path, "max_brightness", &base::StringToUint,
&info.max_brightness)) {
return CreateAndLogProbeError(
mojo_ipc::ErrorType::kFileReadError,
"Failed to read max_brightness for " + path.value());
}
if (!ReadInteger(path, "brightness", &base::StringToUint, &info.brightness)) {
return CreateAndLogProbeError(
mojo_ipc::ErrorType::kFileReadError,
"Failed to read brightness for " + path.value());
}
*output_info = info.Clone();
return base::nullopt;
}
} // namespace
BacklightFetcher::BacklightFetcher(Context* context) : context_(context) {
DCHECK(context_);
}
BacklightFetcher::~BacklightFetcher() = default;
mojo_ipc::BacklightResultPtr BacklightFetcher::FetchBacklightInfo(
const base::FilePath& root) {
std::vector<mojo_ipc::BacklightInfoPtr> backlights;
if (!context_->system_config()->HasBacklight())
return mojo_ipc::BacklightResult::NewBacklightInfo(std::move(backlights));
base::FileEnumerator backlight_dirs(
root.AppendASCII(kRelativeBacklightDirectoryPath),
false /* is_recursive */,
base::FileEnumerator::SHOW_SYM_LINKS | base::FileEnumerator::FILES |
base::FileEnumerator::DIRECTORIES);
for (base::FilePath path = backlight_dirs.Next(); !path.empty();
path = backlight_dirs.Next()) {
VLOG(1) << "Processing the node " << path.value();
mojo_ipc::BacklightInfoPtr backlight;
auto error = FetchBacklightInfoForPath(path, &backlight);
if (error.has_value()) {
return mojo_ipc::BacklightResult::NewError(std::move(error.value()));
}
DCHECK_NE(backlight->path, "");
DCHECK_LE(backlight->brightness, backlight->max_brightness);
backlights.push_back(std::move(backlight));
}
if (backlights.empty()) {
return mojo_ipc::BacklightResult::NewError(CreateAndLogProbeError(
mojo_ipc::ErrorType::kFileReadError,
"Device supports backlight, but no backlight information found in " +
root.AppendASCII(kRelativeBacklightDirectoryPath).value()));
}
return mojo_ipc::BacklightResult::NewBacklightInfo(std::move(backlights));
}
} // namespace diagnostics