MCPcopy Create free account
hub / github.com/actuallyaridan/linux-devmgmt / scanHidrawBatteries

Function scanHidrawBatteries

src/scanner/SysfsScanner.cpp:2136–2298  ·  view source on GitHub ↗

Scans /sys/class/hidraw for HID devices that advertise a Battery System feature report in their report descriptor but have no kernel power_supply entry (e.g. some 2.4 GHz wireless keyboards whose battery the kernel doesn't surface via the standard power_supply class).

Source from the content-addressed store, hash-verified

2134// entry (e.g. some 2.4 GHz wireless keyboards whose battery the kernel doesn't
2135// surface via the standard power_supply class).
2136QVector<Device> scanHidrawBatteries() {
2137 QVector<Device> out;
2138
2139 // Collect canonical sysfs paths of HID devices already covered by a
2140 // kernel power_supply entry so we don't create duplicate entries.
2141 QSet<QString> coveredHidPaths;
2142 {
2143 QDir ps("/sys/class/power_supply");
2144 for (const QString &e : ps.entryList(QDir::AllEntries | QDir::NoDotAndDotDot)) {
2145 QString canon = QFileInfo(ps.absoluteFilePath(e)).canonicalFilePath();
2146 if (readSysFile(canon + "/type") == QLatin1String("Battery"))
2147 coveredHidPaths.insert(canon);
2148 }
2149 }
2150
2151 QDir hidrawDir("/sys/class/hidraw");
2152 if (!hidrawDir.exists())
2153 return out;
2154
2155 QSet<QString> seenHidDevs;
2156
2157 for (const QString &entry : hidrawDir.entryList(
2158 QDir::AllEntries | QDir::NoDotAndDotDot)) {
2159 // Resolve the HID device that backs this hidraw node.
2160 QString hidDevPath = QFileInfo(
2161 hidrawDir.absoluteFilePath(entry) + "/device"
2162 ).canonicalFilePath();
2163 if (hidDevPath.isEmpty() || seenHidDevs.contains(hidDevPath))
2164 continue;
2165
2166 // Skip if a power_supply entry already covers this HID device.
2167 bool covered = false;
2168 for (const QString &cp : coveredHidPaths) {
2169 if (cp.startsWith(hidDevPath + '/')) { covered = true; break; }
2170 }
2171 if (covered)
2172 continue;
2173
2174 QString devNode = "/dev/" + entry;
2175
2176 // O_RDWR is required for HIDIOCGFEATURE; fall back to O_RDONLY for
2177 // descriptor-only detection when the user only has read permission.
2178 int fd = ::open(devNode.toLocal8Bit().constData(), O_RDWR | O_NONBLOCK);
2179 bool canGetFeature = (fd >= 0);
2180 if (fd < 0)
2181 fd = ::open(devNode.toLocal8Bit().constData(), O_RDONLY | O_NONBLOCK);
2182 if (fd < 0)
2183 continue;
2184
2185 // Read the HID report descriptor.
2186 int descSize = 0;
2187 struct hidraw_report_descriptor rptDesc = {};
2188 bool gotDesc = (::ioctl(fd, HIDIOCGRDESCSIZE, &descSize) >= 0
2189 && descSize > 0);
2190 if (gotDesc) {
2191 rptDesc.size = (unsigned int)descSize;
2192 gotDesc = (::ioctl(fd, HIDIOCGRDESC, &rptDesc) >= 0);
2193 }

Callers 1

scanDevicesFunction · 0.85

Calls 6

readSysFileFunction · 0.85
queryMonsGeekBatteryFunction · 0.85
kernelReleaseFunction · 0.85
hidBatteryReportIdsFunction · 0.85
readHidFeatureBatteryFunction · 0.85

Tested by

no test coverage detected