Skip to content

Commit 8c7826f

Browse files
Zentaro KavanaghCommit Bot
Zentaro Kavanagh
authored and
Commit Bot
committed
Add recursive sysfs lookup
- For vivaldi we need to traverse up the path looking for the attribute that defines the top row mapping. - Simple helper function that walks up until it finds the key or no more parents. - Add additional tests to UdevTest BUG=1076241 TEST=device_unittests --gtestfilter='UdevTest.*' Change-Id: I1ead2c3ecefbe1ef27408b4393cce2aa8ab9be06 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2170852 Commit-Queue: Reilly Grant <reillyg@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Cr-Commit-Position: refs/heads/master@{#764444}
1 parent 9d20c64 commit 8c7826f

File tree

6 files changed

+93
-7
lines changed

6 files changed

+93
-7
lines changed

device/BUILD.gn

+4-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,10 @@ test("device_unittests") {
180180

181181
if (use_udev) {
182182
sources += [ "udev_linux/udev_unittest.cc" ]
183-
deps += [ "//device/udev_linux" ]
183+
deps += [
184+
"//device/udev_linux",
185+
"//device/udev_linux:test_support",
186+
]
184187
}
185188

186189
if (is_android) {

device/udev_linux/fake_udev_loader.cc

+13-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "device/udev_linux/fake_udev_loader.h"
66

77
#include <base/logging.h>
8+
#include "base/files/file_path.h"
89

910
struct udev {
1011
// empty
@@ -46,14 +47,15 @@ FakeUdevLoader::~FakeUdevLoader() {
4647
UdevLoader::SetForTesting(nullptr, false);
4748
}
4849

49-
void FakeUdevLoader::AddFakeDevice(
50+
udev_device* FakeUdevLoader::AddFakeDevice(
5051
std::string name,
5152
std::string syspath,
5253
std::map<std::string, std::string> sysattrs,
5354
std::map<std::string, std::string> properties) {
5455
devices_.emplace_back(new udev_device(std::move(name), std::move(syspath),
5556
std::move(sysattrs),
5657
std::move(properties)));
58+
return devices_.back().get();
5759
}
5860

5961
bool FakeUdevLoader::Init() {
@@ -69,7 +71,16 @@ const char* FakeUdevLoader::udev_device_get_devnode(udev_device* udev_device) {
6971
}
7072

7173
udev_device* FakeUdevLoader::udev_device_get_parent(udev_device* udev_device) {
72-
return nullptr;
74+
if (!udev_device) {
75+
return nullptr;
76+
}
77+
78+
const base::FilePath syspath(udev_device->syspath_);
79+
auto it =
80+
std::find_if(devices_.begin(), devices_.end(), [syspath](const auto& d) {
81+
return base::FilePath(d->syspath_).IsParent(syspath);
82+
});
83+
return it == devices_.end() ? nullptr : it->get();
7384
}
7485

7586
udev_device* FakeUdevLoader::udev_device_get_parent_with_subsystem_devtype(

device/udev_linux/fake_udev_loader.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ class FakeUdevLoader : public device::UdevLoader {
2020
FakeUdevLoader();
2121
~FakeUdevLoader() override;
2222

23-
void AddFakeDevice(std::string name,
24-
std::string syspath,
25-
std::map<std::string, std::string> sysattrs,
26-
std::map<std::string, std::string> properties);
23+
udev_device* AddFakeDevice(std::string name,
24+
std::string syspath,
25+
std::map<std::string, std::string> sysattrs,
26+
std::map<std::string, std::string> properties);
2727

2828
private:
2929
bool Init() override;

device/udev_linux/udev.cc

+14
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,20 @@ std::string UdevDeviceGetSysattrValue(udev_device* udev_device,
167167
return StringOrEmptyIfNull(udev_device_get_sysattr_value(udev_device, key));
168168
}
169169

170+
std::string UdevDeviceRecursiveGetSysattrValue(udev_device* udev_device,
171+
const char* key) {
172+
while (udev_device) {
173+
const char* result = udev_device_get_sysattr_value(udev_device, key);
174+
if (result) {
175+
return result;
176+
}
177+
178+
udev_device = udev_device_get_parent(udev_device);
179+
}
180+
181+
return "";
182+
}
183+
170184
std::string UdevDecodeString(const std::string& encoded) {
171185
std::string decoded;
172186
const size_t size = encoded.size();

device/udev_linux/udev.h

+5
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ std::string UdevDeviceGetPropertyValue(udev_device* udev_device,
8484
std::string UdevDeviceGetSysattrValue(udev_device* udev_device,
8585
const char* key);
8686

87+
// Walks up the chain of parent devices calling udev_device_get_sysattr_value()
88+
// until a value is found. If no value is found, an empty string is returned.
89+
std::string UdevDeviceRecursiveGetSysattrValue(udev_device* udev_device,
90+
const char* key);
91+
8792
// Decodes udev-encoded string. Useful for decoding "*_ENC" udev properties.
8893
std::string UdevDecodeString(const std::string& encoded);
8994

device/udev_linux/udev_unittest.cc

+53
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// found in the LICENSE file.
44

55
#include "device/udev_linux/udev.h"
6+
7+
#include "base/files/file_path.h"
8+
#include "device/udev_linux/fake_udev_loader.h"
69
#include "device/udev_linux/udev_loader.h"
710

811
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,4 +26,54 @@ TEST(UdevTest, Loader) {
2326
ASSERT_NE(nullptr, UdevLoader::Get());
2427
}
2528

29+
TEST(UdevTest, GetSysAttrNoAttrs) {
30+
testing::FakeUdevLoader fake_udev;
31+
udev_device* device = fake_udev.AddFakeDevice("Foo", "/device/foo", {}, {});
32+
33+
const std::string attr_value = UdevDeviceGetSysattrValue(device, "attr");
34+
EXPECT_TRUE(attr_value.empty());
35+
}
36+
37+
TEST(UdevTest, GetSysAttrSimple) {
38+
testing::FakeUdevLoader fake_udev;
39+
std::map<std::string, std::string> attrs;
40+
attrs.emplace("attr", "attr value");
41+
udev_device* device =
42+
fake_udev.AddFakeDevice("Foo", "/device/foo", std::move(attrs), {});
43+
44+
std::string attr_value = UdevDeviceGetSysattrValue(device, "attr");
45+
EXPECT_EQ("attr value", attr_value);
46+
47+
attr_value = UdevDeviceGetSysattrValue(device, "unknown attr");
48+
EXPECT_TRUE(attr_value.empty());
49+
}
50+
51+
TEST(UdevTest, GetParent) {
52+
testing::FakeUdevLoader fake_udev;
53+
std::map<std::string, std::string> attrs;
54+
udev_device* parent = fake_udev.AddFakeDevice("Foo", "/device/foo", {}, {});
55+
udev_device* device =
56+
fake_udev.AddFakeDevice("Foo", "/device/foo/bar", {}, {});
57+
58+
EXPECT_EQ(parent, udev_device_get_parent(device));
59+
EXPECT_EQ(nullptr, udev_device_get_parent(parent));
60+
}
61+
62+
TEST(UdevTest, GetSysAttrRecursiveOneLevel) {
63+
testing::FakeUdevLoader fake_udev;
64+
std::map<std::string, std::string> attrs;
65+
attrs.emplace("attr", "attr value");
66+
fake_udev.AddFakeDevice("Foo", "/device/foo", std::move(attrs), {});
67+
udev_device* device =
68+
fake_udev.AddFakeDevice("Foo", "/device/foo/bar", {}, {});
69+
70+
// Don't find the attr on the current device.
71+
std::string attr_value = UdevDeviceGetSysattrValue(device, "attr");
72+
EXPECT_TRUE(attr_value.empty());
73+
74+
// Find it when searching recursive.
75+
attr_value = UdevDeviceRecursiveGetSysattrValue(device, "attr");
76+
EXPECT_EQ("attr value", attr_value);
77+
}
78+
2679
} // namespace device

0 commit comments

Comments
 (0)