~ubuntu-branches/ubuntu/vivid/upower/vivid

« back to all changes in this revision

Viewing changes to .pc/00git_updates.patch/src/openbsd/up-backend.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-10-08 18:26:25 UTC
  • mfrom: (49.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20131008182625-roccyppydypnly0t
Tags: 0.9.22-1
* New upstream release.
* Drop 00git_updates.patch, included in new release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2
 
 *
3
 
 * Copyright (C) 2011 Landry Breuil <landry@openbsd.org>
4
 
 *
5
 
 * Licensed under the GNU General Public License Version 2
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
10
 
 * (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 
 */
21
 
 
22
 
#include "up-apm-native.h"
23
 
 
24
 
#include "up-backend.h"
25
 
#include "up-daemon.h"
26
 
#include "up-marshal.h"
27
 
#include "up-device.h"
28
 
#include <string.h> /* strcmp() */
29
 
 
30
 
#define UP_BACKEND_SUSPEND_COMMAND      "/usr/sbin/zzz"
31
 
#define UP_BACKEND_POWERSAVE_TRUE_COMMAND       "/usr/sbin/apm -C"
32
 
#define UP_BACKEND_POWERSAVE_FALSE_COMMAND      "/usr/sbin/apm -A"
33
 
 
34
 
static void     up_backend_class_init   (UpBackendClass *klass);
35
 
static void     up_backend_init (UpBackend              *backend);
36
 
static void     up_backend_finalize     (GObject                *object);
37
 
 
38
 
static gboolean up_backend_apm_get_power_info(struct apm_power_info*);
39
 
UpDeviceState up_backend_apm_get_battery_state_value(u_char battery_state);
40
 
static void     up_backend_update_acpibat_state(UpDevice*, struct sensordev);
41
 
 
42
 
static gboolean         up_apm_device_get_on_battery    (UpDevice *device, gboolean *on_battery);
43
 
static gboolean         up_apm_device_get_low_battery   (UpDevice *device, gboolean *low_battery);
44
 
static gboolean         up_apm_device_get_online                (UpDevice *device, gboolean *online);
45
 
static gboolean         up_apm_device_refresh           (UpDevice *device);
46
 
 
47
 
#define UP_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UP_TYPE_BACKEND, UpBackendPrivate))
48
 
 
49
 
struct UpBackendPrivate
50
 
{
51
 
        UpDaemon                *daemon;
52
 
        UpDevice                *ac;
53
 
        UpDevice                *battery;
54
 
        GThread                 *apm_thread;
55
 
        gboolean                is_laptop;
56
 
};
57
 
 
58
 
enum {
59
 
        SIGNAL_DEVICE_ADDED,
60
 
        SIGNAL_DEVICE_REMOVED,
61
 
        SIGNAL_LAST
62
 
};
63
 
 
64
 
static guint signals [SIGNAL_LAST] = { 0 };
65
 
 
66
 
G_DEFINE_TYPE (UpBackend, up_backend, G_TYPE_OBJECT)
67
 
 
68
 
/**
69
 
 * functions called by upower daemon
70
 
 **/
71
 
 
72
 
 
73
 
/* those three ripped from freebsd/up-device-supply.c */
74
 
gboolean
75
 
up_apm_device_get_on_battery (UpDevice *device, gboolean * on_battery)
76
 
{
77
 
        UpDeviceKind type;
78
 
        UpDeviceState state;
79
 
        gboolean is_present;
80
 
 
81
 
        g_return_val_if_fail (on_battery != NULL, FALSE);
82
 
 
83
 
        g_object_get (device,
84
 
                      "type", &type,
85
 
                      "state", &state,
86
 
                      "is-present", &is_present,
87
 
                      (void*) NULL);
88
 
 
89
 
        if (type != UP_DEVICE_KIND_BATTERY)
90
 
                return FALSE;
91
 
        if (state == UP_DEVICE_STATE_UNKNOWN)
92
 
                return FALSE;
93
 
        if (!is_present)
94
 
                return FALSE;
95
 
 
96
 
        *on_battery = (state == UP_DEVICE_STATE_DISCHARGING);
97
 
        return TRUE;
98
 
}
99
 
gboolean
100
 
up_apm_device_get_low_battery (UpDevice *device, gboolean * low_battery)
101
 
{
102
 
        gboolean ret;
103
 
        gboolean on_battery;
104
 
        gdouble percentage;
105
 
 
106
 
        g_return_val_if_fail (low_battery != NULL, FALSE);
107
 
 
108
 
        ret = up_apm_device_get_on_battery (device, &on_battery);
109
 
        if (!ret)
110
 
                return FALSE;
111
 
 
112
 
        if (!on_battery) {
113
 
                *low_battery = FALSE;
114
 
                return TRUE;
115
 
        }
116
 
 
117
 
        g_object_get (device, "percentage", &percentage, (void*) NULL);
118
 
        *low_battery = (percentage < 10.0f);
119
 
        return TRUE;
120
 
}
121
 
 
122
 
gboolean
123
 
up_apm_device_get_online (UpDevice *device, gboolean * online)
124
 
{
125
 
        UpDeviceKind type;
126
 
        gboolean online_tmp;
127
 
 
128
 
        g_return_val_if_fail (online != NULL, FALSE);
129
 
 
130
 
        g_object_get (device,
131
 
                      "type", &type,
132
 
                      "online", &online_tmp,
133
 
                      (void*) NULL);
134
 
 
135
 
        if (type != UP_DEVICE_KIND_LINE_POWER)
136
 
                return FALSE;
137
 
 
138
 
        *online = online_tmp;
139
 
 
140
 
        return TRUE;
141
 
}
142
 
/**
143
 
 * up_backend_coldplug:
144
 
 * @backend: The %UpBackend class instance
145
 
 * @daemon: The %UpDaemon controlling instance
146
 
 *
147
 
 * Finds all the devices already plugged in, and emits device-add signals for
148
 
 * each of them.
149
 
 *
150
 
 * Return value: %TRUE for success
151
 
 **/
152
 
gboolean
153
 
up_backend_coldplug (UpBackend *backend, UpDaemon *daemon)
154
 
{
155
 
        UpApmNative *acnative = NULL;
156
 
        UpApmNative *battnative = NULL;
157
 
        backend->priv->daemon = g_object_ref (daemon);
158
 
        /* XXX no way to get lid status atm */
159
 
        up_daemon_set_lid_is_present (backend->priv->daemon, FALSE);
160
 
        if (backend->priv->is_laptop)
161
 
        {
162
 
                acnative = up_apm_native_new("/ac");
163
 
                if (!up_device_coldplug (backend->priv->ac, backend->priv->daemon, G_OBJECT(acnative)))
164
 
                        g_warning ("failed to coldplug ac");
165
 
                else
166
 
                        g_signal_emit (backend, signals[SIGNAL_DEVICE_ADDED], 0, acnative, backend->priv->ac);
167
 
 
168
 
                battnative = up_apm_native_new("/batt");
169
 
                if (!up_device_coldplug (backend->priv->battery, backend->priv->daemon, G_OBJECT(battnative)))
170
 
                        g_warning ("failed to coldplug battery");
171
 
                else
172
 
                        g_signal_emit (backend, signals[SIGNAL_DEVICE_ADDED], 0, battnative, backend->priv->battery);
173
 
        }
174
 
 
175
 
        return TRUE;
176
 
}
177
 
 
178
 
 
179
 
/**
180
 
 * up_backend_get_powersave_command:
181
 
 **/
182
 
const gchar *
183
 
up_backend_get_powersave_command (UpBackend *backend, gboolean powersave)
184
 
{
185
 
        if (powersave)
186
 
                return UP_BACKEND_POWERSAVE_TRUE_COMMAND;
187
 
        return UP_BACKEND_POWERSAVE_FALSE_COMMAND;
188
 
}
189
 
 
190
 
/**
191
 
 * up_backend_get_suspend_command:
192
 
 **/
193
 
const gchar *
194
 
up_backend_get_suspend_command (UpBackend *backend)
195
 
{
196
 
        return UP_BACKEND_SUSPEND_COMMAND;
197
 
}
198
 
 
199
 
/**
200
 
 * up_backend_get_hibernate_command:
201
 
 **/
202
 
const gchar *
203
 
up_backend_get_hibernate_command (UpBackend *backend)
204
 
{
205
 
        return NULL;
206
 
}
207
 
 
208
 
gboolean
209
 
up_backend_emits_resuming (UpBackend *backend)
210
 
{
211
 
        return FALSE;
212
 
}
213
 
 
214
 
/**
215
 
 * up_backend_kernel_can_suspend:
216
 
 **/
217
 
gboolean
218
 
up_backend_kernel_can_suspend (UpBackend *backend)
219
 
{
220
 
        return TRUE;
221
 
}
222
 
 
223
 
/**
224
 
 * up_backend_kernel_can_hibernate:
225
 
 **/
226
 
gboolean
227
 
up_backend_kernel_can_hibernate (UpBackend *backend)
228
 
{
229
 
        return FALSE;
230
 
}
231
 
 
232
 
gboolean
233
 
up_backend_has_encrypted_swap (UpBackend *backend)
234
 
{
235
 
        return FALSE;
236
 
}
237
 
 
238
 
/* Return value: a percentage value */
239
 
gfloat
240
 
up_backend_get_used_swap (UpBackend *backend)
241
 
{
242
 
        return 0;
243
 
}
244
 
 
245
 
/**
246
 
 * OpenBSD specific code
247
 
 **/
248
 
 
249
 
static gboolean
250
 
up_backend_apm_get_power_info(struct apm_power_info *bstate) {
251
 
        bstate->battery_state = 255;
252
 
        bstate->ac_state = 255;
253
 
        bstate->battery_life = 0;
254
 
        bstate->minutes_left = -1;
255
 
 
256
 
        if (-1 == ioctl(up_apm_get_fd(), APM_IOC_GETPOWER, bstate)) {
257
 
                g_error("ioctl on apm fd failed : %s", g_strerror(errno));
258
 
                return FALSE;
259
 
        }
260
 
        return TRUE;
261
 
}
262
 
 
263
 
UpDeviceState up_backend_apm_get_battery_state_value(u_char battery_state) {
264
 
        switch(battery_state) {
265
 
                case APM_BATT_HIGH:
266
 
                        return UP_DEVICE_STATE_FULLY_CHARGED;
267
 
                case APM_BATT_LOW:
268
 
                        return UP_DEVICE_STATE_DISCHARGING; // XXXX
269
 
                case APM_BATT_CRITICAL:
270
 
                        return UP_DEVICE_STATE_EMPTY;
271
 
                case APM_BATT_CHARGING:
272
 
                        return UP_DEVICE_STATE_CHARGING;
273
 
                case APM_BATTERY_ABSENT:
274
 
                        return UP_DEVICE_STATE_EMPTY;
275
 
                case APM_BATT_UNKNOWN:
276
 
                        return UP_DEVICE_STATE_UNKNOWN;
277
 
        }
278
 
        return -1;
279
 
}
280
 
 
281
 
static gboolean
282
 
up_backend_update_ac_state(UpDevice* device)
283
 
{
284
 
        gboolean ret, new_is_online, cur_is_online;
285
 
        struct apm_power_info a;
286
 
 
287
 
        ret = up_backend_apm_get_power_info(&a);
288
 
        if (!ret)
289
 
                return ret;
290
 
 
291
 
        g_object_get (device, "online", &cur_is_online, (void*) NULL);
292
 
        /* XXX use acpiac0.indicator0 if available */
293
 
        new_is_online = (a.ac_state == APM_AC_ON ? TRUE : FALSE);
294
 
        if (cur_is_online != new_is_online)
295
 
        {
296
 
                g_object_set (device,
297
 
                        "online", new_is_online,
298
 
                        (void*) NULL);
299
 
                return TRUE;
300
 
        }
301
 
        return FALSE;
302
 
}
303
 
 
304
 
static gboolean
305
 
up_backend_update_battery_state(UpDevice* device)
306
 
{
307
 
        gdouble percentage;
308
 
        gboolean ret;
309
 
        struct sensordev sdev;
310
 
        UpDeviceState cur_state, new_state;
311
 
        gint64 cur_time_to_empty, new_time_to_empty;
312
 
        struct apm_power_info a;
313
 
 
314
 
        ret = up_backend_apm_get_power_info(&a);
315
 
        if (!ret)
316
 
                return ret;
317
 
 
318
 
        g_object_get (device,
319
 
                "state", &cur_state,
320
 
                "percentage", &percentage,
321
 
                "time-to-empty", &cur_time_to_empty,
322
 
                (void*) NULL);
323
 
 
324
 
        /* XXX use acpibat0.raw0 if available */
325
 
        new_state = up_backend_apm_get_battery_state_value(a.battery_state);
326
 
        // if percentage/minutes goes down or ac is off, we're likely discharging..
327
 
        if (percentage < a.battery_life || cur_time_to_empty < new_time_to_empty || a.ac_state == APM_AC_OFF)
328
 
                new_state = UP_DEVICE_STATE_DISCHARGING;
329
 
        if (a.ac_state == APM_AC_ON)
330
 
                new_state = UP_DEVICE_STATE_CHARGING;
331
 
 
332
 
        // zero out new_time_to empty if we're not discharging or minutes_left is negative
333
 
        new_time_to_empty = (new_state == UP_DEVICE_STATE_DISCHARGING && a.minutes_left > 0 ? a.minutes_left : 0);
334
 
 
335
 
        if (cur_state != new_state ||
336
 
                percentage != (gdouble) a.battery_life ||
337
 
                cur_time_to_empty != new_time_to_empty)
338
 
        {
339
 
                g_object_set (device,
340
 
                        "state", new_state,
341
 
                        "percentage", (gdouble) a.battery_life,
342
 
                        "time-to-empty", new_time_to_empty * 60,
343
 
                        (void*) NULL);
344
 
                if(up_native_get_sensordev("acpibat0", &sdev))
345
 
                        up_backend_update_acpibat_state(device, sdev);
346
 
                return TRUE;
347
 
        }
348
 
        return FALSE;
349
 
}
350
 
 
351
 
/* update acpibat properties */
352
 
static void
353
 
up_backend_update_acpibat_state(UpDevice* device, struct sensordev s)
354
 
{
355
 
        enum sensor_type type;
356
 
        int numt;
357
 
        gdouble bst_volt, bst_rate, bif_lastfullcap, bst_cap, bif_lowcap;
358
 
        /* gdouble bif_dvolt, bif_dcap, capacity; */
359
 
        struct sensor sens;
360
 
        size_t slen = sizeof(sens);
361
 
        int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0};
362
 
 
363
 
        mib[2] = s.num;
364
 
        for (type = 0; type < SENSOR_MAX_TYPES; type++) {
365
 
                mib[3] = type;
366
 
                for (numt = 0; numt < s.maxnumt[type]; numt++) {
367
 
                        mib[4] = numt;
368
 
                        if (sysctl(mib, 5, &sens, &slen, NULL, 0) < 0)
369
 
                                g_error("failed to get sensor type %d(%s) numt %d on %s", type, sensor_type_s[type], numt, s.xname);
370
 
                        else if (slen > 0 && (sens.flags & SENSOR_FINVALID) == 0) {
371
 
                                if (sens.type == SENSOR_VOLTS_DC && !strcmp(sens.desc, "current voltage"))
372
 
                                        bst_volt = sens.value / 1000000.0f;
373
 
                                if ((sens.type == SENSOR_AMPHOUR || sens.type == SENSOR_WATTHOUR) && !strcmp(sens.desc, "last full capacity")) {
374
 
                                        bif_lastfullcap = (sens.type == SENSOR_AMPHOUR ? bst_volt : 1) * sens.value / 1000000.0f;
375
 
                                }
376
 
                                if ((sens.type == SENSOR_AMPHOUR || sens.type == SENSOR_WATTHOUR) && !strcmp(sens.desc, "low capacity")) {
377
 
                                        bif_lowcap = (sens.type == SENSOR_AMPHOUR ? bst_volt : 1) * sens.value / 1000000.0f;
378
 
                                }
379
 
                                if ((sens.type == SENSOR_AMPHOUR || sens.type == SENSOR_WATTHOUR) && !strcmp(sens.desc, "remaining capacity")) {
380
 
                                        bst_cap = (sens.type == SENSOR_AMPHOUR ? bst_volt : 1) * sens.value / 1000000.0f;
381
 
                                }
382
 
                                if ((sens.type == SENSOR_AMPS || sens.type == SENSOR_WATTS) && !strcmp(sens.desc, "rate")) {
383
 
                                        bst_rate = (sens.type == SENSOR_AMPS ? bst_volt : 1) * sens.value / 1000000.0f;
384
 
                                }
385
 
                                /*
386
 
                                bif_dvolt = "voltage" = unused ?
387
 
                                capacity = lastfull/dcap * 100 ?
388
 
                                amphour1 = warning capacity ?
389
 
                                raw0 = battery state
390
 
                                */
391
 
                        }
392
 
                }
393
 
        }
394
 
        g_object_set (device,
395
 
                "energy", bst_cap,
396
 
                "energy-full", bif_lastfullcap,
397
 
                "energy-rate", bst_rate,
398
 
                "energy-empty", bif_lowcap,
399
 
                "voltage", bst_volt,
400
 
                (void*) NULL);
401
 
}
402
 
 
403
 
/* callback updating the device */
404
 
static gboolean
405
 
up_backend_apm_powerchange_event_cb(gpointer object)
406
 
{
407
 
        UpBackend *backend;
408
 
 
409
 
        g_return_val_if_fail (UP_IS_BACKEND (object), FALSE);
410
 
        backend = UP_BACKEND (object);
411
 
        up_apm_device_refresh(backend->priv->ac);
412
 
        up_apm_device_refresh(backend->priv->battery);
413
 
        /* return false to not endless loop */
414
 
        return FALSE;
415
 
}
416
 
 
417
 
static gboolean
418
 
up_apm_device_refresh(UpDevice* device)
419
 
{
420
 
        UpDeviceKind type;
421
 
        GTimeVal timeval;
422
 
        gboolean ret;
423
 
        g_object_get (device, "type", &type, NULL);
424
 
 
425
 
        switch (type) {
426
 
                case UP_DEVICE_KIND_LINE_POWER:
427
 
                        ret = up_backend_update_ac_state(device);
428
 
                        break;
429
 
                case UP_DEVICE_KIND_BATTERY:
430
 
                        ret = up_backend_update_battery_state(device);
431
 
                        break;
432
 
                default:
433
 
                        g_assert_not_reached ();
434
 
                        break;
435
 
        }
436
 
 
437
 
        if (ret) {
438
 
                g_get_current_time (&timeval);
439
 
                g_object_set (device, "update-time", (guint64) timeval.tv_sec, NULL);
440
 
        }
441
 
 
442
 
        return ret;
443
 
}
444
 
 
445
 
/* thread doing kqueue() on apm device */
446
 
static gpointer
447
 
up_backend_apm_event_thread(gpointer object)
448
 
{
449
 
        int kq, nevents;
450
 
        struct kevent ev;
451
 
        struct timespec ts = {600, 0}, sts = {0, 0};
452
 
 
453
 
        UpBackend *backend;
454
 
 
455
 
        g_return_val_if_fail (UP_IS_BACKEND (object), NULL);
456
 
        backend = UP_BACKEND (object);
457
 
 
458
 
        g_debug("setting up apm thread");
459
 
 
460
 
        kq = kqueue();
461
 
        if (kq <= 0)
462
 
                g_error("kqueue");
463
 
        EV_SET(&ev, up_apm_get_fd(), EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR,
464
 
            0, 0, NULL);
465
 
        nevents = 1;
466
 
        if (kevent(kq, &ev, nevents, NULL, 0, &sts) < 0)
467
 
                g_error("kevent");
468
 
 
469
 
        /* blocking wait on kqueue */
470
 
        for (;;) {
471
 
                int rv;
472
 
 
473
 
                /* 10mn timeout */
474
 
                sts = ts;
475
 
                if ((rv = kevent(kq, NULL, 0, &ev, 1, &sts)) < 0)
476
 
                        break;
477
 
                if (!rv)
478
 
                        continue;
479
 
                if (ev.ident == (guint) up_apm_get_fd() && APM_EVENT_TYPE(ev.data) == APM_POWER_CHANGE ) {
480
 
                        /* g_idle_add the callback */
481
 
                        g_idle_add((GSourceFunc) up_backend_apm_powerchange_event_cb, backend);
482
 
                }
483
 
        }
484
 
        return NULL;
485
 
        /* shouldnt be reached ? */
486
 
}
487
 
 
488
 
/**
489
 
 * GObject class functions
490
 
 **/
491
 
 
492
 
/**
493
 
 * up_backend_new:
494
 
 *
495
 
 * Return value: a new %UpBackend object.
496
 
 **/
497
 
UpBackend *
498
 
up_backend_new (void)
499
 
{
500
 
        UpBackend *backend;
501
 
        backend = g_object_new (UP_TYPE_BACKEND, NULL);
502
 
        return UP_BACKEND (backend);
503
 
}
504
 
 
505
 
/**
506
 
 * up_backend_class_init:
507
 
 * @klass: The UpBackendClass
508
 
 **/
509
 
static void
510
 
up_backend_class_init (UpBackendClass *klass)
511
 
{
512
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
513
 
        object_class->finalize = up_backend_finalize;
514
 
 
515
 
        signals [SIGNAL_DEVICE_ADDED] =
516
 
                g_signal_new ("device-added",
517
 
                              G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
518
 
                              G_STRUCT_OFFSET (UpBackendClass, device_added),
519
 
                              NULL, NULL, up_marshal_VOID__POINTER_POINTER,
520
 
                              G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
521
 
        signals [SIGNAL_DEVICE_REMOVED] =
522
 
                g_signal_new ("device-removed",
523
 
                              G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
524
 
                              G_STRUCT_OFFSET (UpBackendClass, device_removed),
525
 
                              NULL, NULL, up_marshal_VOID__POINTER_POINTER,
526
 
                              G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
527
 
 
528
 
        g_type_class_add_private (klass, sizeof (UpBackendPrivate));
529
 
}
530
 
 
531
 
/**
532
 
 * up_backend_init:
533
 
 **/
534
 
static void
535
 
up_backend_init (UpBackend *backend)
536
 
{
537
 
        GError *err = NULL;
538
 
        GTimeVal timeval;
539
 
        UpDeviceClass *device_class;
540
 
 
541
 
        backend->priv = UP_BACKEND_GET_PRIVATE (backend);
542
 
        backend->priv->daemon = NULL;
543
 
        backend->priv->is_laptop = up_native_is_laptop();
544
 
        g_debug("is_laptop:%d",backend->priv->is_laptop);
545
 
        if (backend->priv->is_laptop)
546
 
        {
547
 
                backend->priv->ac = UP_DEVICE(up_device_new());
548
 
                backend->priv->battery = UP_DEVICE(up_device_new ());
549
 
                device_class = UP_DEVICE_GET_CLASS (backend->priv->battery);
550
 
                device_class->get_on_battery = up_apm_device_get_on_battery;
551
 
                device_class->get_low_battery = up_apm_device_get_low_battery;
552
 
                device_class->get_online = up_apm_device_get_online;
553
 
                device_class->refresh = up_apm_device_refresh;
554
 
                device_class = UP_DEVICE_GET_CLASS (backend->priv->ac);
555
 
                device_class->get_on_battery = up_apm_device_get_on_battery;
556
 
                device_class->get_low_battery = up_apm_device_get_low_battery;
557
 
                device_class->get_online = up_apm_device_get_online;
558
 
                device_class->refresh = up_apm_device_refresh;
559
 
                g_thread_init (NULL);
560
 
                /* creates thread */
561
 
                if((backend->priv->apm_thread = (GThread*) g_thread_create((GThreadFunc)up_backend_apm_event_thread, (void*) backend, FALSE, &err) == NULL))
562
 
                {
563
 
                        g_warning("Thread create failed: %s", err->message);
564
 
                        g_error_free (err);
565
 
                }
566
 
 
567
 
                /* setup dummy */
568
 
                g_get_current_time (&timeval);
569
 
                g_object_set (backend->priv->battery,
570
 
                              "type", UP_DEVICE_KIND_BATTERY,
571
 
                              "power-supply", TRUE,
572
 
                              "is-present", TRUE,
573
 
                              "is-rechargeable", TRUE,
574
 
                              "has-history", TRUE,
575
 
                              "state", UP_DEVICE_STATE_UNKNOWN,
576
 
                              "percentage", 0.0f,
577
 
                              "time-to-empty", (gint64) 0,
578
 
                              "update-time", (guint64) timeval.tv_sec,
579
 
                              (void*) NULL);
580
 
                g_object_set (backend->priv->ac,
581
 
                              "type", UP_DEVICE_KIND_LINE_POWER,
582
 
                              "online", TRUE,
583
 
                              "power-supply", TRUE,
584
 
                              "update-time", (guint64) timeval.tv_sec,
585
 
                              (void*) NULL);
586
 
        } else {
587
 
                backend->priv->ac = NULL;
588
 
                backend->priv->battery = NULL;
589
 
        }
590
 
}
591
 
/**
592
 
 * up_backend_finalize:
593
 
 **/
594
 
static void
595
 
up_backend_finalize (GObject *object)
596
 
{
597
 
        UpBackend *backend;
598
 
 
599
 
        g_return_if_fail (UP_IS_BACKEND (object));
600
 
 
601
 
        backend = UP_BACKEND (object);
602
 
 
603
 
        if (backend->priv->daemon != NULL)
604
 
                g_object_unref (backend->priv->daemon);
605
 
        if (backend->priv->battery != NULL)
606
 
                g_object_unref (backend->priv->battery);
607
 
        if (backend->priv->ac != NULL)
608
 
                g_object_unref (backend->priv->ac);
609
 
        /* XXX stop apm_thread ? */
610
 
 
611
 
        G_OBJECT_CLASS (up_backend_parent_class)->finalize (object);
612
 
}
613