Find script for gsm
[gregoa/zavai.git] / src / power.vala
1 /*
2  * power - zavai power event handling
3  *
4  * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 using GLib;
22
23 namespace zavai {
24 namespace power {
25
26 public class Power : Service
27 {
28     public enum State
29     {
30         UNKNOWN,
31         CHARGING,
32         DISCHARGING,
33         FULLY_CHARGED,
34     }
35
36     protected string battery_device;
37     protected uint timeout;
38     public signal void changed();
39     public State state;
40     public int percentage;
41
42     public Power()
43     {
44         battery_device = "/sys/class/power_supply/battery/";
45         if (Posix.access(battery_device, Posix.R_OK) != 0)
46             battery_device = null;
47         timeout = 0;
48         state = State.UNKNOWN;
49         percentage = 0;
50     }
51
52     /// Activate the service
53     protected override void start()
54     {
55         if (started) return;
56
57         uint poll_time;
58         if (uevent.uevent != null)
59         {
60             zavai.log.info("We have uevent: poll rarely");
61             uevent.uevent.event += on_uevent;
62             uevent.uevent.request("zavai.power");
63             // If we can get plug/unplug notifications, it's ok to just poll
64             // every 5 minutes
65             poll_time = 300 * 1000;
66         } else {
67             if (battery_device == null)
68             {
69                 zavai.log.warning("No battery device found that I know how to read: try building with devkit-power");
70                 poll_time = 0;
71             } else {
72                 zavai.log.info("Polling battery device only");
73                 // Else poll every 30 seconds to be somehow reactive to plug/unplug
74                 // events
75                 poll_time = 30 * 1000;
76             }
77         }
78
79         poll();
80
81         // Poll battery every minute
82         if (poll_time != 0)
83             timeout = Timeout.add(poll_time, on_timeout);
84
85         base.start();
86     }
87
88     /// Deactivate the service
89     protected override void stop()
90     {
91         if (!started) return;
92
93         // Stop polling
94         if (timeout != 0)
95             Source.remove(timeout);
96
97         if (uevent.uevent != null)
98         {
99             uevent.uevent.release("zavai.power");
100             uevent.uevent.event -= on_uevent;
101         }
102
103         base.stop();
104     }
105
106     protected void poll()
107     {
108         if (battery_device == null)
109             return;
110
111         char buf[200];
112         State new_state = State.UNKNOWN;
113         int new_percentage = 0;
114
115         FileStream state_fd = FileStream.open(battery_device + "/status", "r");
116         string val = state_fd.gets(buf);
117         if (val == "Charging")
118             new_state = State.CHARGING;
119         else if (val == "Discharging")
120             new_state = State.DISCHARGING;
121         else if (val == "Not charging")
122             new_state = State.FULLY_CHARGED;
123
124         FileStream cap_fd = FileStream.open(battery_device + "/capacity", "r");
125         val = cap_fd.gets(buf);
126         new_percentage = val.to_int();
127
128         if (new_state != state || new_percentage != percentage)
129         {
130             state = new_state;
131             percentage = new_percentage;
132             changed();
133         }
134     }
135
136     protected bool on_timeout()
137     {
138         poll();
139         return true;
140     }
141
142     protected void on_uevent()
143     {
144         /* if (uevent.uevent.event_data.buffer.has_prefix("change@/class/power_supply/ac"))
145         {
146             changed();
147         }
148         else */
149         if (uevent.uevent.event_data.buffer.has_prefix("change@/class/power_supply/battery"))
150         {
151             State new_state = State.UNKNOWN;
152             int new_percentage = 0;
153
154             Omhacks.UEvent.parse(ref uevent.uevent.event_data);
155             for (int i = 0; uevent.uevent.event_data.envp[i] != null; ++i)
156             {
157                 if (uevent.uevent.event_data.envp[i].has_prefix("POWER_SUPPLY_STATUS="))
158                 {
159                     var val = uevent.uevent.event_data.envp[i].offset(20);
160                     if (val == "Charging")
161                         new_state = State.CHARGING;
162                     else if (val == "Discharging")
163                         new_state = State.DISCHARGING;
164                     else if (val == "Not charging")
165                         new_state = State.FULLY_CHARGED;
166                     else
167                         zavai.log.warning("Unknown state: " + uevent.uevent.event_data.envp[i]);
168                 }
169                 else if (uevent.uevent.event_data.envp[i].has_prefix("POWER_SUPPLY_CAPACITY="))
170                 {
171                     new_percentage = uevent.uevent.event_data.envp[i].offset(22).to_int();
172                 }
173             }
174             if (new_state != state || new_percentage != percentage)
175             {
176                 state = new_state;
177                 percentage = new_percentage;
178                 changed();
179             }
180         }
181     }
182 }
183
184 public Power power;
185
186 public void init()
187 {
188     power = new Power();
189 }
190
191 }
192 }