1
2
3
4
5 package oshi.hardware.platform.linux;
6
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import oshi.annotation.concurrent.Immutable;
11 import oshi.hardware.GraphicsCard;
12 import oshi.hardware.common.AbstractGraphicsCard;
13 import oshi.util.Constants;
14 import oshi.util.ExecutingCommand;
15 import oshi.util.ParseUtil;
16 import oshi.util.tuples.Pair;
17
18
19
20
21 @Immutable
22 final class LinuxGraphicsCard extends AbstractGraphicsCard {
23
24
25
26
27
28
29
30
31
32
33 LinuxGraphicsCard(String name, String deviceId, String vendor, String versionInfo, long vram) {
34 super(name, deviceId, vendor, versionInfo, vram);
35 }
36
37
38
39
40
41
42 public static List<GraphicsCard> getGraphicsCards() {
43 List<GraphicsCard> cardList = getGraphicsCardsFromLspci();
44 if (cardList.isEmpty()) {
45 cardList = getGraphicsCardsFromLshw();
46 }
47 return cardList;
48 }
49
50
51 private static List<GraphicsCard> getGraphicsCardsFromLspci() {
52 List<GraphicsCard> cardList = new ArrayList<>();
53
54 List<String> lspci = ExecutingCommand.runNative("lspci -vnnm");
55 String name = Constants.UNKNOWN;
56 String deviceId = Constants.UNKNOWN;
57 String vendor = Constants.UNKNOWN;
58 List<String> versionInfoList = new ArrayList<>();
59 boolean found = false;
60 String lookupDevice = null;
61 for (String line : lspci) {
62 String[] split = line.trim().split(":", 2);
63 String prefix = split[0];
64
65 if (prefix.equals("Class") && line.contains("VGA")) {
66 found = true;
67 } else if (prefix.equals("Device") && !found && split.length > 1) {
68 lookupDevice = split[1].trim();
69 }
70 if (found) {
71 if (split.length < 2) {
72
73 cardList.add(new LinuxGraphicsCard(name, deviceId, vendor,
74 versionInfoList.isEmpty() ? Constants.UNKNOWN : String.join(", ", versionInfoList),
75 queryLspciMemorySize(lookupDevice)));
76 versionInfoList.clear();
77 found = false;
78 } else {
79 if (prefix.equals("Device")) {
80 Pair<String, String> pair = ParseUtil.parseLspciMachineReadable(split[1].trim());
81 if (pair != null) {
82 name = pair.getA();
83 deviceId = "0x" + pair.getB();
84 }
85 } else if (prefix.equals("Vendor")) {
86 Pair<String, String> pair = ParseUtil.parseLspciMachineReadable(split[1].trim());
87 if (pair != null) {
88 vendor = pair.getA() + " (0x" + pair.getB() + ")";
89 } else {
90 vendor = split[1].trim();
91 }
92 } else if (prefix.equals("Rev:")) {
93 versionInfoList.add(line.trim());
94 }
95 }
96 }
97 }
98
99 if (found) {
100 cardList.add(new LinuxGraphicsCard(name, deviceId, vendor,
101 versionInfoList.isEmpty() ? Constants.UNKNOWN : String.join(", ", versionInfoList),
102 queryLspciMemorySize(lookupDevice)));
103 }
104 return cardList;
105 }
106
107 private static long queryLspciMemorySize(String lookupDevice) {
108 long vram = 0L;
109
110
111 List<String> lspciMem = ExecutingCommand.runNative("lspci -v -s " + lookupDevice);
112 for (String mem : lspciMem) {
113 if (mem.contains(" prefetchable")) {
114 vram += ParseUtil.parseLspciMemorySize(mem);
115 }
116 }
117 return vram;
118 }
119
120
121 private static List<GraphicsCard> getGraphicsCardsFromLshw() {
122 List<GraphicsCard> cardList = new ArrayList<>();
123 List<String> lshw = ExecutingCommand.runNative("lshw -C display");
124 String name = Constants.UNKNOWN;
125 String deviceId = Constants.UNKNOWN;
126 String vendor = Constants.UNKNOWN;
127 List<String> versionInfoList = new ArrayList<>();
128 long vram = 0;
129 int cardNum = 0;
130 for (String line : lshw) {
131 String[] split = line.trim().split(":");
132 if (split[0].startsWith("*-display")) {
133
134 if (cardNum++ > 0) {
135 cardList.add(new LinuxGraphicsCard(name, deviceId, vendor,
136 versionInfoList.isEmpty() ? Constants.UNKNOWN : String.join(", ", versionInfoList), vram));
137 versionInfoList.clear();
138 }
139 } else if (split.length == 2) {
140 String prefix = split[0];
141 if (prefix.equals("product")) {
142 name = split[1].trim();
143 } else if (prefix.equals("vendor")) {
144 vendor = split[1].trim();
145 } else if (prefix.equals("version")) {
146 versionInfoList.add(line.trim());
147 } else if (prefix.startsWith("resources")) {
148 vram = ParseUtil.parseLshwResourceString(split[1].trim());
149 }
150 }
151 }
152 cardList.add(new LinuxGraphicsCard(name, deviceId, vendor,
153 versionInfoList.isEmpty() ? Constants.UNKNOWN : String.join(", ", versionInfoList), vram));
154 return cardList;
155 }
156 }