forked from wtfutil/wtf
/
managed_devices.go
151 lines (114 loc) · 3.5 KB
/
managed_devices.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package power
import (
"bufio"
"fmt"
"os/exec"
"strconv"
"strings"
"github.com/wtfutil/wtf/utils"
)
// ManageDevices are ...
type ManagedDevices struct {
Devices []*ManagedDevice
args []string
cmd string
}
func NewManagedDevices() *ManagedDevices {
manDevices := &ManagedDevices{
Devices: []*ManagedDevice{},
// This command queries for all managed devices
args: []string{"-c", "AppleDeviceManagementHIDEventService", "-r", "-l"},
cmd: "ioreg",
}
return manDevices
}
func (manDevices *ManagedDevices) Refresh() {
cmd := exec.Command(manDevices.cmd, manDevices.args...)
data := utils.ExecuteCommand(cmd)
manDevices.Devices = manDevices.parse(data)
}
/* -------------------- Unexported Functions -------------------- */
// parse takes the output of the command and turns it into ManagedDevice instances
func (manDevices *ManagedDevices) parse(data string) []*ManagedDevice {
devices := []*ManagedDevice{}
chunks := utils.FindBetween(data, "{\n", "}\n")
for _, chunk := range chunks {
manDev := NewManagedDevice()
manDev.Add(chunk)
devices = append(devices, manDev)
}
return devices
}
/* -------------------- And Another Thing -------------------- */
// ManagedDevice represents an entry in the output returned by ioreg when
// passed AppleDeviceManagementHIDEventService
type ManagedDevice struct {
Attributes map[string]string
}
func NewManagedDevice() *ManagedDevice {
manDev := &ManagedDevice{
Attributes: map[string]string{},
}
return manDev
}
/* -------------------- Exported Functions -------------------- */
// Add takes a chunk of raw text and attempts to parse it as managed device data
// and create an attribute map from it.
/*
A typical chunk will look like:
"LowBatteryNotificationPercentage" = 2
"BatteryFaultNotificationType" = "TPBatteryFault"
...
"VersionNumber" = 0
which should become:
{
"LowBatteryNotificationPercentage": 2,
"BatteryFaultNotificationType": "TPBatteryFault",
"VersionNumber": 0,
}
*/
func (manDev *ManagedDevice) Add(chunk string) {
scanner := bufio.NewScanner(strings.NewReader(chunk))
for scanner.Scan() {
line := strings.ReplaceAll(scanner.Text(), "\"", "")
pieces := strings.Split(line, "=")
if len(pieces) == 2 {
left := strings.TrimSpace(pieces[0])
right := strings.TrimSpace(pieces[1])
manDev.Attributes[left] = right
}
}
}
// Dump writes out all the device attributes as a single string
func (manDev *ManagedDevice) Dump() string {
out := ""
for attribute, value := range manDev.Attributes {
out += fmt.Sprintf("%s %s\n", attribute, value)
}
return out
}
/* -------------------- Attributes -------------------- */
// BatteryPercent returns the percent of the device battery
func (manDev *ManagedDevice) BatteryPercent() int64 {
percent, err := strconv.ParseInt(manDev.Attributes["BatteryPercent"], 10, 64)
if err != nil {
return -1
}
return percent
}
// BluetoothDevice returns whether or not the device supports bluetooth
func (manDev *ManagedDevice) BluetoothDevice() bool {
return manDev.Attributes["BluetoothDevice"] == "Yes"
}
// BuiltIn returns whether or not the device is built into the computer
func (manDev *ManagedDevice) BuiltIn() bool {
return manDev.Attributes["BuiltIn"] == "Yes"
}
// HasBattery returns whether or not the device has a battery
func (manDev *ManagedDevice) HasBattery() bool {
return manDev.Attributes["HasBattery"] == "Yes"
}
// Product returns the name of the device
func (manDev *ManagedDevice) Product() string {
return manDev.Attributes["Product"]
}