Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: chromeos/system/cpu_temperature_reader.cc

Issue 2823583002: chromeos: Add CPU temperature reader (Closed)
Patch Set: Answered derat's feedback Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chromeos/system/cpu_temperature_reader.h"
6
7 #include "base/files/file_enumerator.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/location.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/task_scheduler/post_task.h"
14 #include "base/task_scheduler/task_traits.h"
15
16 namespace chromeos {
17 namespace system {
18
19 using CPUTemperatureInfo = CPUTemperatureReader::CPUTemperatureInfo;
20
21 namespace {
22
23 // The location we read our CPU temperature and channel label from.
24 constexpr char kDefaultHwmonDir[] = "/sys/class/hwmon/";
25 constexpr char kDeviceDir[] = "device";
26 constexpr char kHwmonDirectoryPattern[] = "hwmon*";
27 constexpr char kCPUTempFilePattern[] = "temp*_input";
28
29 // The contents of sysfs files might contain a newline at the end. Use this
30 // function to read from a sysfs file and remove the newline.
31 bool ReadFileContentsAndTrimWhitespace(const base::FilePath& path,
32 std::string* contents_out) {
33 if (!base::ReadFileToString(path, contents_out))
34 return false;
35 base::TrimWhitespaceASCII(*contents_out, base::TRIM_TRAILING, contents_out);
36 return true;
37 }
38
39 // Reads the temperature as degrees Celsius from the file at |path|, which is
40 // expected to contain the temperature in millidegrees Celsius. Converts the
41 // value into degrees and then stores it in |*temp_celsius_out|. returns true if
42 // the value was successfully read from file, parsed as an int, and converted.
43 bool ReadTemperatureFromPath(const base::FilePath& path,
44 double* temp_celsius_out) {
45 std::string temperature_string;
46 if (!ReadFileContentsAndTrimWhitespace(path, &temperature_string))
47 return false;
48 uint32_t temperature = 0;
49 if (!base::StringToUint(temperature_string, &temperature))
50 return false;
51 *temp_celsius_out = temperature / 1000.0;
52 return true;
53 }
54
55 // Gets the label describing this temperature. Use the file "temp*_label" if it
56 // is present, or fall back on the file "name" or |label_path|.
57 std::string GetLabelFromPath(const base::FilePath& label_path) {
58 std::string label;
59 if (base::PathExists(label_path) &&
60 ReadFileContentsAndTrimWhitespace(base::FilePath(label_path), &label) &&
61 !label.empty()) {
62 return label;
63 }
64
65 base::FilePath name_path = label_path.DirName().Append("name");
66 if (base::PathExists(name_path) &&
67 ReadFileContentsAndTrimWhitespace(name_path, &label) && !label.empty()) {
68 return label;
69 }
70 return label_path.value();
71 }
72
73 } // namespace
74
75 CPUTemperatureReader::CPUTemperatureInfo::CPUTemperatureInfo() {}
76
77 CPUTemperatureReader::CPUTemperatureInfo::~CPUTemperatureInfo() = default;
78
79 CPUTemperatureReader::CPUTemperatureReader() : hwmon_dir_(kDefaultHwmonDir) {}
80
81 CPUTemperatureReader::~CPUTemperatureReader() = default;
82
83 std::vector<CPUTemperatureInfo> CPUTemperatureReader::GetCPUTemperatures() {
84 std::vector<CPUTemperatureInfo> result;
85
86 // Get directories /sys/class/hwmon/hwmon*.
87 base::FileEnumerator hwmon_enumerator(base::FilePath(hwmon_dir_), false,
88 base::FileEnumerator::DIRECTORIES,
89 kHwmonDirectoryPattern);
90 for (base::FilePath hwmon_path = hwmon_enumerator.Next(); !hwmon_path.empty();
91 hwmon_path = hwmon_enumerator.Next()) {
92 // Get temp*_input files in hwmon*/ and hwmon*/device/.
93 if (base::PathExists(hwmon_path.Append(kDeviceDir))) {
94 hwmon_path = hwmon_path.Append(kDeviceDir);
95 }
96 base::FileEnumerator enumerator(
97 hwmon_path, false, base::FileEnumerator::FILES, kCPUTempFilePattern);
98 for (base::FilePath temperature_path = enumerator.Next();
99 !temperature_path.empty(); temperature_path = enumerator.Next()) {
100 CPUTemperatureInfo info;
101 if (!ReadTemperatureFromPath(temperature_path, &info.temp_celsius)) {
102 LOG(WARNING) << "Unable to read CPU temperature from "
103 << temperature_path.value();
104 continue;
105 }
106 // Get appropriate temp*_label file.
107 if (temperature_path.value().empty()) {
Daniel Erat 2017/04/24 20:16:50 what are you trying to catch with this check? look
Simon Que 2017/04/24 22:25:48 Done.
108 LOG(WARNING) << "Unable to parse a path to temp*_input file as ASCII";
109 continue;
110 }
111 std::string label_path = temperature_path.value();
112 base::ReplaceSubstringsAfterOffset(&label_path, 0, "input", "label");
113 info.label = GetLabelFromPath(base::FilePath(label_path));
114 result.push_back(info);
115 }
116 }
117 return result;
118 }
119
120 } // namespace system
121 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698