View Javadoc
1   /*
2    * Copyright 2020-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.unix.freebsd;
6   
7   import java.util.ArrayList;
8   import java.util.Collections;
9   import java.util.List;
10  
11  import oshi.annotation.concurrent.Immutable;
12  import oshi.hardware.GraphicsCard;
13  import oshi.hardware.common.AbstractGraphicsCard;
14  import oshi.util.Constants;
15  import oshi.util.ExecutingCommand;
16  import oshi.util.ParseUtil;
17  
18  /**
19   * Graphics Card info obtained from pciconf
20   */
21  @Immutable
22  final class FreeBsdGraphicsCard extends AbstractGraphicsCard {
23  
24      private static final String PCI_CLASS_DISPLAY = "0x03";
25  
26      /**
27       * Constructor for FreeBsdGraphicsCard
28       *
29       * @param name        The name
30       * @param deviceId    The device ID
31       * @param vendor      The vendor
32       * @param versionInfo The version info
33       * @param vram        The VRAM
34       */
35      FreeBsdGraphicsCard(String name, String deviceId, String vendor, String versionInfo, long vram) {
36          super(name, deviceId, vendor, versionInfo, vram);
37      }
38  
39      /**
40       * public method used by {@link oshi.hardware.common.AbstractHardwareAbstractionLayer} to access the graphics cards.
41       *
42       * @return List of {@link oshi.hardware.platform.unix.freebsd.FreeBsdGraphicsCard} objects.
43       */
44      public static List<GraphicsCard> getGraphicsCards() {
45          List<GraphicsCard> cardList = new ArrayList<>();
46          // Enumerate all devices and add if required
47          List<String> devices = ExecutingCommand.runNative("pciconf -lv");
48          if (devices.isEmpty()) {
49              return Collections.emptyList();
50          }
51          String name = Constants.UNKNOWN;
52          String vendorId = Constants.UNKNOWN;
53          String productId = Constants.UNKNOWN;
54          String classCode = "";
55          String versionInfo = Constants.UNKNOWN;
56          for (String line : devices) {
57              if (line.contains("class=0x")) {
58                  // Identifies start of a new device. Save previous if it's a graphics card
59                  if (PCI_CLASS_DISPLAY.equals(classCode)) {
60                      cardList.add(new FreeBsdGraphicsCard(name.isEmpty() ? Constants.UNKNOWN : name,
61                              productId.isEmpty() ? Constants.UNKNOWN : productId,
62                              vendorId.isEmpty() ? Constants.UNKNOWN : vendorId,
63                              versionInfo.isEmpty() ? Constants.UNKNOWN : versionInfo, 0L));
64                  }
65                  // Parse this line
66                  String[] split = ParseUtil.whitespaces.split(line);
67                  for (String s : split) {
68                      String[] keyVal = s.split("=");
69                      if (keyVal.length > 1) {
70                          if (keyVal[0].equals("class") && keyVal[1].length() >= 4) {
71                              // class=0x030000
72                              classCode = keyVal[1].substring(0, 4);
73                          } else if (keyVal[0].equals("chip") && keyVal[1].length() >= 10) {
74                              // chip=0x3ea08086
75                              productId = keyVal[1].substring(0, 6);
76                              vendorId = "0x" + keyVal[1].substring(6, 10);
77                          } else if (keyVal[0].contains("rev")) {
78                              // rev=0x00
79                              versionInfo = s;
80                          }
81                      }
82                  }
83                  // Reset name
84                  name = Constants.UNKNOWN;
85              } else {
86                  String[] split = line.trim().split("=", 2);
87                  if (split.length == 2) {
88                      String key = split[0].trim();
89                      if (key.equals("vendor")) {
90                          vendorId = ParseUtil.getSingleQuoteStringValue(line)
91                                  + (vendorId.equals(Constants.UNKNOWN) ? "" : " (" + vendorId + ")");
92                      } else if (key.equals("device")) {
93                          name = ParseUtil.getSingleQuoteStringValue(line);
94                      }
95                  }
96              }
97          }
98          // In case we reached end before saving
99          if (PCI_CLASS_DISPLAY.equals(classCode)) {
100             cardList.add(new FreeBsdGraphicsCard(name.isEmpty() ? Constants.UNKNOWN : name,
101                     productId.isEmpty() ? Constants.UNKNOWN : productId,
102                     vendorId.isEmpty() ? Constants.UNKNOWN : vendorId,
103                     versionInfo.isEmpty() ? Constants.UNKNOWN : versionInfo, 0L));
104         }
105         return cardList;
106     }
107 }