diff --git a/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java b/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java index b04548b00..ddec26da0 100644 --- a/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java +++ b/app/src/main/java/com/droiddeck/launcher/runtime/LinuxRuntime.java @@ -249,30 +249,32 @@ public final class LinuxRuntime { /** * Valve's mangoapp (Deck mode's performance overlay) reads an Adreno GPU's load, clock and * temperatures from where they are on Valve's own hardware; every Adreno under Android keeps - * them in KGSL's sysfs, readable by the app. Only the GPU temperature has no KGSL file on older - * kernels, and thermal zones are numbered per device, so a zone is found by its sensor's name, - * which differs between Snapdragon generations. A value that cannot be found is left alone. + * them in KGSL's sysfs, readable by the app, though which files a kernel has differs between + * Snapdragon generations - so each value takes the first source that exists, the order other + * Android PC emulators (GameNative, Winlator forks) read them in. A value found nowhere is left + * alone. */ private static void bindAdrenoStats(List cmd) { String kgsl = "/sys/class/kgsl/kgsl-3d0/"; - String gpuTemp = new File(kgsl + "temp").canRead() ? kgsl + "temp" - : thermalZone("gpuss-0", "gpuss-0-usr", "gpu0-usr", "gpu-usr", "gpu"); + String gpuTemp = firstReadable(kgsl + "temp", kgsl + "devfreq/temp", thermalZone("gpu")); String[][] stats = { - {kgsl + "gpu_busy_percentage", "/sys/kernel/debug/dri/0/perf_now"}, - {kgsl + "devfreq/cur_freq", "/sys/devices/platform/soc@0/3d00000.gpu/devfreq/3d00000.gpu/cur_freq"}, + {firstReadable(kgsl + "gpu_busy_percentage", kgsl + "devfreq/gpu_load"), "/sys/kernel/debug/dri/0/perf_now"}, + {firstReadable(kgsl + "devfreq/cur_freq", kgsl + "gpuclk"), + "/sys/devices/platform/soc@0/3d00000.gpu/devfreq/3d00000.gpu/cur_freq"}, {gpuTemp, "/sys/class/thermal/thermal_zone28/temp"}, {gpuTemp, "/sys/class/thermal/thermal_zone26/temp"}, - {thermalZone("ddr", "ddr-usr", "ddr-thermal"), "/sys/class/thermal/thermal_zone22/temp"}, + {thermalZone("ddr"), "/sys/class/thermal/thermal_zone22/temp"}, }; for (String[] stat : stats) { - if (stat[0] != null && new File(stat[0]).canRead()) bind(cmd, stat[0] + ":" + stat[1]); + if (stat[0] != null) bind(cmd, stat[0] + ":" + stat[1]); } } /** * mangoapp's CPU temperature is the mean of the thermal zones named cpuN-thermal or * cpuN-top-thermal, as mainline kernels name them; Android kernels name the same sensors - * cpuss-0, cpu-1-0 and the like, so those zones are shown under the mainline name. + * cpuss-0, cpu-1-0, cpu0-silver-usr, apc1-cpu0-usr and the like, so those zones are shown + * under the mainline name. */ private static void bindCpuTemps(List cmd, File root) { File name = new File(root, "etc/bannerlator/cpu-thermal-type"); @@ -283,29 +285,37 @@ public final class LinuxRuntime { } for (java.util.Map.Entry zone : thermalZones().entrySet()) { String type = zone.getKey(); - if (type.startsWith("cpu") && !type.matches("cpu\\d-(top-)?thermal")) { + if (type.contains("cpu") && !type.contains("gpu") && !type.matches("cpu\\d-(top-)?thermal")) { bind(cmd, name.getPath() + ":" + new File(zone.getValue(), "type").getPath()); } } } - /** The temp file of the first thermal zone whose sensor has one of these names, in that order. */ - private static String thermalZone(String... types) { - java.util.Map zones = thermalZones(); - for (String type : types) { - if (zones.containsKey(type)) return new File(zones.get(type), "temp").getPath(); + private static String firstReadable(String... paths) { + for (String path : paths) { + if (path != null && new File(path).canRead()) return path; } return null; } - /** The device's thermal zones by their sensor's name. */ + /** The temp file of the thermal zone for a sensor: the one named so, else the first whose name has it. */ + private static String thermalZone(String sensor) { + java.util.Map zones = thermalZones(); + File zone = zones.get(sensor); + for (java.util.Map.Entry e : new java.util.TreeMap<>(zones).entrySet()) { + if (zone == null && e.getKey().contains(sensor)) zone = e.getValue(); + } + return zone != null ? new File(zone, "temp").getPath() : null; + } + + /** The device's thermal zones by their sensor's name, in lower case. */ private static java.util.Map thermalZones() { java.util.Map byType = new java.util.HashMap<>(); File[] zones = new File("/sys/class/thermal").listFiles((dir, n) -> n.startsWith("thermal_zone")); if (zones == null) return byType; for (File zone : zones) { try (java.io.BufferedReader r = new java.io.BufferedReader(new java.io.FileReader(new File(zone, "type")))) { - byType.putIfAbsent(String.valueOf(r.readLine()).trim(), zone); + byType.putIfAbsent(String.valueOf(r.readLine()).trim().toLowerCase(java.util.Locale.ROOT), zone); } catch (IOException ignored) { } }