-
Notifications
You must be signed in to change notification settings - Fork 0
/
monitor.go
122 lines (103 loc) · 2.28 KB
/
monitor.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
package main
import (
"github.com/guelfey/go.dbus"
"log"
"sync"
)
type Monitor struct {
Resources *map[string]*Resource
ResourceLck sync.Mutex
OnBatteryCh chan bool
DoneCh chan bool
}
func NewMonitor() *Monitor {
resources := make(map[string]*Resource)
m := &Monitor{
Resources: &resources,
OnBatteryCh: make(chan bool),
DoneCh: make(chan bool),
}
return m
}
func (m *Monitor) SetResources(resources *map[string]*Resource) {
m.ResourceLck.Lock()
defer m.ResourceLck.Unlock()
m.Resources = resources
}
func (m *Monitor) UpdateResources(onBattery bool) {
m.ResourceLck.Lock()
defer m.ResourceLck.Unlock()
var wg sync.WaitGroup
for _, resource := range *m.Resources {
wg.Add(1)
go func(r *Resource) {
defer wg.Done()
if onBattery {
r.Unplug()
} else {
r.Plug()
}
}(resource)
}
wg.Wait()
}
func (m *Monitor) CheckDBus() (onBattery bool) {
conn, connErr := dbus.SystemBus()
if connErr != nil {
log.Fatalf("Failed to connect to bus: %v", connErr)
}
msg, getErr := conn.
Object("org.freedesktop.UPower", "/org/freedesktop/UPower").
GetProperty("org.freedesktop.UPower.OnBattery")
if getErr != nil {
log.Fatalf("Failed to get property: ", getErr)
}
onBattery = msg.Value().(bool)
return
}
func (m *Monitor) ListenDBus() {
m.OnBatteryCh <- m.CheckDBus()
conn, connErr := dbus.SystemBus()
if connErr != nil {
log.Fatalf("Failed to connect to bus: %v", connErr)
}
matchRule := "type='signal',sender='org.freedesktop.UPower',path='/org/freedesktop/UPower'"
call := conn.
BusObject().
Call("org.freedesktop.DBus.AddMatch", 0, matchRule)
if call.Err != nil {
log.Fatalf("Failed to add match", call.Err)
}
c := make(chan *dbus.Signal)
conn.Signal(c)
for {
select {
case v := <-c:
switch v.Path {
case "/org/freedesktop/UPower":
changedProperties := v.Body[1].(map[string]dbus.Variant)
if property, ok := changedProperties["OnBattery"]; ok {
onBattery := property.Value().(bool)
m.OnBatteryCh <- onBattery
}
}
case <-m.DoneCh:
return
}
}
}
func (m *Monitor) Listen() {
go m.ListenDBus()
for {
select {
case onBattery := <-m.OnBatteryCh:
m.UpdateResources(onBattery)
case <-m.DoneCh:
return
}
}
}
func (m *Monitor) Stop() {
log.Printf("Stopping monitor")
close(m.DoneCh)
}