1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package oshi.software.os.mac.local;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import oshi.hardware.PowerSource;
23 import oshi.software.os.mac.local.CoreFoundation.CFArrayRef;
24 import oshi.software.os.mac.local.CoreFoundation.CFDictionaryRef;
25 import oshi.software.os.mac.local.CoreFoundation.CFTypeRef;
26
27 import com.sun.jna.Memory;
28 import com.sun.jna.Pointer;
29 import com.sun.jna.ptr.IntByReference;
30
31
32
33
34
35
36 public class MacPowerSource implements PowerSource {
37
38 private String name;
39
40 private double remainingCapacity;
41
42 private double timeRemaining;
43
44 public MacPowerSource(String name, double remainingCapacity,
45 double timeRemaining) {
46 this.name = name;
47 this.remainingCapacity = remainingCapacity;
48 this.timeRemaining = timeRemaining;
49 }
50
51 @Override
52 public String getName() {
53 return this.name;
54 }
55
56 @Override
57 public double getRemainingCapacity() {
58 return this.remainingCapacity;
59 }
60
61 @Override
62 public double getTimeRemaining() {
63 return this.timeRemaining;
64 }
65
66
67
68
69 public static PowerSource[] getPowerSources() {
70
71 CFTypeRef powerSourcesInfo = IOKit.INSTANCE.IOPSCopyPowerSourcesInfo();
72 CFArrayRef powerSourcesList = IOKit.INSTANCE
73 .IOPSCopyPowerSourcesList(powerSourcesInfo);
74 int powerSourcesCount = CoreFoundation.INSTANCE
75 .CFArrayGetCount(powerSourcesList);
76
77
78
79 double timeRemaining = IOKit.INSTANCE.IOPSGetTimeRemainingEstimate();
80
81
82 List<MacPowerSource> psList = new ArrayList<>(
83 powerSourcesCount);
84 for (int ps = 0; ps < powerSourcesCount; ps++) {
85
86 CFTypeRef powerSource = CoreFoundation.INSTANCE
87 .CFArrayGetValueAtIndex(powerSourcesList, ps);
88 CFDictionaryRef dictionary = IOKit.INSTANCE
89 .IOPSGetPowerSourceDescription(powerSourcesInfo,
90 powerSource);
91
92
93
94 boolean isPresent = false;
95 Pointer isPresentRef = CoreFoundation.INSTANCE
96 .CFDictionaryGetValue(dictionary, IOKit.IOPS_IS_PRESENT_KEY);
97 if (isPresentRef != null)
98 isPresent = CoreFoundation.INSTANCE
99 .CFBooleanGetValue(isPresentRef);
100 if (!isPresent)
101 continue;
102
103
104 Pointer name = CoreFoundation.INSTANCE.CFDictionaryGetValue(
105 dictionary, IOKit.IOPS_NAME_KEY);
106 long length = CoreFoundation.INSTANCE.CFStringGetLength(name);
107 long maxSize = CoreFoundation.INSTANCE
108 .CFStringGetMaximumSizeForEncoding(length,
109 CoreFoundation.UTF_8);
110 Pointer nameBuf = new Memory(maxSize);
111 CoreFoundation.INSTANCE.CFStringGetCString(name, nameBuf, maxSize,
112 CoreFoundation.UTF_8);
113
114
115 IntByReference currentCapacity = new IntByReference();
116 if (!CoreFoundation.INSTANCE.CFDictionaryGetValueIfPresent(
117 dictionary, IOKit.IOPS_CURRENT_CAPACITY_KEY,
118 currentCapacity))
119 currentCapacity = new IntByReference(0);
120 IntByReference maxCapacity = new IntByReference();
121 if (!CoreFoundation.INSTANCE.CFDictionaryGetValueIfPresent(
122 dictionary, IOKit.IOPS_MAX_CAPACITY_KEY, maxCapacity))
123 maxCapacity = new IntByReference(1);
124
125
126 psList.add(new MacPowerSource(nameBuf != null ? nameBuf
127 .getString(0) : "Unknown", (double) currentCapacity
128 .getValue() / maxCapacity.getValue(), timeRemaining));
129 }
130
131 CoreFoundation.INSTANCE.CFRelease(powerSourcesInfo);
132
133 return psList.toArray(new MacPowerSource[psList.size()]);
134 }
135 }