Merge lp:~charlesk/indicator-power/lp-1373511-low-battery-warning into lp:indicator-power/14.10

Proposed by Charles Kerr
Status: Merged
Approved by: Ted Gould
Approved revision: 276
Merged at revision: 269
Proposed branch: lp:~charlesk/indicator-power/lp-1373511-low-battery-warning
Merge into: lp:indicator-power/14.10
Diff against target: 917 lines (+547/-183)
11 files modified
data/com.canonical.indicator.power.Testing.xml (+39/-0)
src/CMakeLists.txt (+6/-0)
src/device-provider-mock.c (+1/-1)
src/main.c (+6/-7)
src/notifier.c (+34/-24)
src/service.c (+13/-0)
src/testing.c (+351/-0)
src/testing.h (+66/-0)
tests/CMakeLists.txt (+0/-9)
tests/indicator-power-service-cmdline-battery.cc (+0/-127)
tests/manual (+31/-15)
To merge this branch: bzr merge lp:~charlesk/indicator-power/lp-1373511-low-battery-warning
Reviewer Review Type Date Requested Status
Ted Gould (community) Approve
Antti Kaijanmäki (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+238034@code.launchpad.net

Commit message

Add mock battery support to make QA testing easier.

Description of the change

Add mock battery support for QA testing.

From the tests/manual's notes:

The indicator's schema name is "com.canonical.indicator.power" and there are four keys: "mock-battery-enabled" (a boolean), "mock-battery-level" (charger percent, an integer from 0-100), "mock-battery-charging" (a boolean of whether the mock battery is charging or discharging), and "mock-battery-minutes-left" (minutes remaining to charge/discharge).

Example use:

$ gsettings list-recursively com.canonical.indicator.power | grep mock # get mock state
$ gsettings set com.canonical.indicator.power mock-battery-enabled true
$ gsettings set com.canonical.indicator.power mock-battery-level 10
$ gsettings reset-recursively com.canonical.indicator.power # reset to non-test state

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

LGTM.

review: Approve
Revision history for this message
Ted Gould (ted) wrote :

I like the idea, but I don't love using gsettings. I think that the
problem could be that if a test fails half way, without its cleanup
step, things could be in a confusing state. I think we want a reboot "to
solve all ills." I think perhaps a couple of GActions or a DBus testing
interface would make more sense.

Revision history for this message
Charles Kerr (charlesk) wrote :

Ted, that was my first thought as well but the problem with implementing that is the service handles acquiring / owning the bus, and we don't necessarily want it to know anything about where the DeviceProvider is coming from.

To use GActions and a DBus interface for this, we'd need to pull name ownership out of the service, and sync the tests to match that too.

IMO there are positive arguments for that, but the refactoring would be much larger and would drift away from the goal of "let's make short-term QA testing easier".

Revision history for this message
Ted Gould (ted) wrote :

I'm not sure we're talking about the same thing, I was thinking,
modifying your example, of something like this:

- gsettings list-recursively com.canonical.indicator.power | grep mock #
show the current mock settings
+ gdbus call --session --dest com.canonical.indicator.power
--object-path /com/canonical/indicator/power/mock --method
org.freedesktop.DBus.Properties.GetAll

- gsettings set com.canonical.indicator.power mock-battery-enabled true
+ gdbus call --session --dest com.canonical.indicator.power
--object-path /com/canonical/indicator/power/mock --method
org.freedesktop.DBus.Properties.Set MockBattery "<@b true>"

- gsettings set com.canonical.indicator.power mock-battery-level 10
+ gdbus call --session --dest com.canonical.indicator.power
--object-path /com/canonical/indicator/power/mock --method
org.freedesktop.DBus.Properties.Set BatteryLevel "<@i 10>"

So it'd still be the same process, just not stored anywhere on disk.

Revision history for this message
Ted Gould (ted) :
review: Needs Information
271. By Charles Kerr

move the testing settings to a DBus interface

272. By Charles Kerr

make service's bus connection a property so that IndicatorPowerTesting can listen for it and export an object before the name is acquired

273. By Charles Kerr

fix notify get-capabilities startup blocking bug found in testing

274. By Charles Kerr

move the mock battery from GSettings to DBus

Revision history for this message
Charles Kerr (charlesk) wrote :

Ted, okay here you go. :)

275. By Charles Kerr

in testing.c, make 'bus' a private field instead of a public GObject property

Revision history for this message
Ted Gould (ted) :
review: Approve
276. By Charles Kerr

r273 tried to fix the blocking bug listed at http://paste.ubuntu.com/8562226/, but in the process introduced a new bug that manifested in RTM. This removes r273 and uses a different fix.

Revision history for this message
Charles Kerr (charlesk) wrote :

Ted/Antti, r276 was needed to fix a bug that showed up when I tested the silo on RTM.

Commit r276 tested & works -- mako + rtm r87

Revision history for this message
Ted Gould (ted) wrote :

WFM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/com.canonical.indicator.power.Testing.xml'
2--- data/com.canonical.indicator.power.Testing.xml 1970-01-01 00:00:00 +0000
3+++ data/com.canonical.indicator.power.Testing.xml 2014-10-15 01:58:54 +0000
4@@ -0,0 +1,39 @@
5+<?xml version="1.0" encoding="UTF-8" ?>
6+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
7+<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
8+ <interface name="com.canonical.indicator.power.Testing">
9+
10+ <property name="MockBatteryEnabled" type="b" access="readwrite">
11+ <doc:doc>
12+ <doc:description>
13+ <doc:para>Whether or not the mock battery is enabled. (Default: false)</doc:para>
14+ </doc:description>
15+ </doc:doc>
16+ </property>
17+
18+ <property name="MockBatteryLevel" type="u" access="readwrite">
19+ <doc:doc>
20+ <doc:description>
21+ <doc:para>The charge level of the mock battery (0-100%, Default: 50%)</doc:para>
22+ </doc:description>
23+ </doc:doc>
24+ </property>
25+
26+ <property name="MockBatteryState" type="s" access="readwrite">
27+ <doc:doc>
28+ <doc:description>
29+ <doc:para>The mock battery's state. Possible values: 'charging', 'discharging' (Defualt: 'discharging')</doc:para>
30+ </doc:description>
31+ </doc:doc>
32+ </property>
33+
34+ <property name="MockBatteryMinutesLeft" type="u" access="readwrite">
35+ <doc:doc>
36+ <doc:description>
37+ <doc:para>Muntes left until the mock battery finishes charging/dischargin (Default: 30)</doc:para>
38+ </doc:description>
39+ </doc:doc>
40+ </property>
41+
42+ </interface>
43+</node>
44
45=== modified file 'src/CMakeLists.txt'
46--- src/CMakeLists.txt 2014-09-10 21:28:42 +0000
47+++ src/CMakeLists.txt 2014-10-15 01:58:54 +0000
48@@ -6,10 +6,12 @@
49 # handwritten sources
50 set(SERVICE_MANUAL_SOURCES
51 brightness.c
52+ device-provider-mock.c
53 device-provider-upower.c
54 device-provider.c
55 device.c
56 notifier.c
57+ testing.c
58 service.c)
59
60 # generated sources
61@@ -19,6 +21,10 @@
62 com.canonical.indicator.power
63 Dbus
64 ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Battery.xml)
65+add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-testing
66+ com.canonical.indicator.power
67+ Dbus
68+ ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Testing.xml)
69 # add the bin dir to our include path so the code can find the generated header files
70 include_directories(${CMAKE_CURRENT_BINARY_DIR})
71
72
73=== renamed file 'tests/device-provider-mock.c' => 'src/device-provider-mock.c'
74--- tests/device-provider-mock.c 2014-07-22 14:58:29 +0000
75+++ src/device-provider-mock.c 2014-10-15 01:58:54 +0000
76@@ -81,7 +81,7 @@
77 }
78
79 static void
80-indicator_power_device_provider_mock_init (IndicatorPowerDeviceProviderMock * self)
81+indicator_power_device_provider_mock_init (IndicatorPowerDeviceProviderMock * self G_GNUC_UNUSED)
82 {
83 }
84
85
86=== renamed file 'tests/device-provider-mock.h' => 'src/device-provider-mock.h'
87=== modified file 'src/main.c'
88--- src/main.c 2014-07-21 05:50:24 +0000
89+++ src/main.c 2014-10-15 01:58:54 +0000
90@@ -18,14 +18,13 @@
91 */
92
93 #include <locale.h>
94-#include <stdlib.h> /* exit() */
95
96+#include <glib.h>
97 #include <glib/gi18n.h>
98-#include <gio/gio.h>
99
100 #include "device.h"
101-#include "device-provider-upower.h"
102 #include "service.h"
103+#include "testing.h"
104
105 /***
106 ****
107@@ -41,8 +40,8 @@
108 int
109 main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED)
110 {
111- IndicatorPowerDeviceProvider * device_provider;
112 IndicatorPowerService * service;
113+ IndicatorPowerTesting * testing;
114 GMainLoop * loop;
115
116 /* boilerplate i18n */
117@@ -51,8 +50,8 @@
118 textdomain (GETTEXT_PACKAGE);
119
120 /* run */
121- device_provider = indicator_power_device_provider_upower_new ();
122- service = indicator_power_service_new (device_provider);
123+ service = indicator_power_service_new (NULL);
124+ testing = indicator_power_testing_new (service);
125 loop = g_main_loop_new (NULL, FALSE);
126 g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST,
127 G_CALLBACK(on_name_lost), loop);
128@@ -61,6 +60,6 @@
129 /* cleanup */
130 g_main_loop_unref (loop);
131 g_clear_object (&service);
132- g_clear_object (&device_provider);
133+ g_clear_object (&testing);
134 return 0;
135 }
136
137=== modified file 'src/notifier.c'
138--- src/notifier.c 2014-10-07 15:58:22 +0000
139+++ src/notifier.c 2014-10-15 01:58:54 +0000
140@@ -55,8 +55,6 @@
141
142 static int instance_count = 0;
143
144-static gboolean actions_supported = FALSE;
145-
146 /**
147 ***
148 **/
149@@ -76,6 +74,9 @@
150
151 GDBusConnection * bus;
152 DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */
153+
154+ gboolean caps_queried;
155+ gboolean actions_supported;
156 }
157 IndicatorPowerNotifierPrivate;
158
159@@ -182,6 +183,33 @@
160 /* no-op; libnotify warns if we have a NULL action callback */
161 }
162
163+static gboolean
164+are_actions_supported(IndicatorPowerNotifier * self)
165+{
166+ priv_t * const p = get_priv(self);
167+
168+ if (!p->caps_queried)
169+ {
170+ gboolean actions_supported;
171+ GList * caps;
172+ GList * l;
173+
174+ /* see if actions are supported */
175+ actions_supported = FALSE;
176+ caps = notify_get_server_caps();
177+ for (l=caps; l!=NULL && !actions_supported; l=l->next)
178+ if (!g_strcmp0(l->data, "actions"))
179+ actions_supported = TRUE;
180+
181+ p->actions_supported = actions_supported;
182+ p->caps_queried = TRUE;
183+
184+ g_list_free_full(caps, g_free);
185+ }
186+
187+ return p->actions_supported;
188+}
189+
190 static void
191 notification_show(IndicatorPowerNotifier * self)
192 {
193@@ -214,7 +242,7 @@
194 g_strfreev (icon_names);
195 g_free (body);
196
197- if (actions_supported)
198+ if (are_actions_supported(self))
199 {
200 notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_string("true"));
201 notify_notification_set_hint(nn, "x-canonical-non-shaped-icon", g_variant_new_string("true"));
202@@ -354,6 +382,7 @@
203 **** Instantiation
204 ***/
205
206+
207 static void
208 indicator_power_notifier_init (IndicatorPowerNotifier * self)
209 {
210@@ -365,27 +394,8 @@
211
212 p->power_level = POWER_LEVEL_OK;
213
214- if (!instance_count++)
215- {
216- actions_supported = FALSE;
217-
218- if (!notify_init("indicator-power-service"))
219- {
220- g_critical("Unable to initialize libnotify! Notifications might not be shown.");
221- }
222- else
223- {
224- GList * caps;
225- GList * l;
226-
227- /* see if actions are supported */
228- caps = notify_get_server_caps();
229- for (l=caps; l!=NULL && !actions_supported; l=l->next)
230- if (!g_strcmp0(l->data, "actions"))
231- actions_supported = TRUE;
232- g_list_free_full(caps, g_free);
233- }
234- }
235+ if (!instance_count++ && !notify_init("indicator-power-service"))
236+ g_critical("Unable to initialize libnotify! Notifications might not be shown.");
237 }
238
239 static void
240
241=== modified file 'src/service.c'
242--- src/service.c 2014-10-09 13:42:03 +0000
243+++ src/service.c 2014-10-15 01:58:54 +0000
244@@ -51,6 +51,7 @@
245 enum
246 {
247 PROP_0,
248+ PROP_BUS,
249 PROP_DEVICE_PROVIDER,
250 LAST_PROP
251 };
252@@ -839,6 +840,7 @@
253 g_debug ("bus acquired: %s", name);
254
255 p->conn = g_object_ref (G_OBJECT (connection));
256+ g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_BUS]);
257
258 /* export the battery properties */
259 indicator_power_notifier_set_bus (p->notifier, connection);
260@@ -977,6 +979,10 @@
261
262 switch (property_id)
263 {
264+ case PROP_BUS:
265+ g_value_set_object (value, p->conn);
266+ break;
267+
268 case PROP_DEVICE_PROVIDER:
269 g_value_set_object (value, p->device_provider);
270 break;
271@@ -1113,6 +1119,13 @@
272
273 properties[PROP_0] = NULL;
274
275+ properties[PROP_BUS] = g_param_spec_object (
276+ "bus",
277+ "Bus",
278+ "GDBusConnection for exporting menus/actions",
279+ G_TYPE_OBJECT,
280+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
281+
282 properties[PROP_DEVICE_PROVIDER] = g_param_spec_object (
283 "device-provider",
284 "Device Provider",
285
286=== added file 'src/testing.c'
287--- src/testing.c 1970-01-01 00:00:00 +0000
288+++ src/testing.c 2014-10-15 01:58:54 +0000
289@@ -0,0 +1,351 @@
290+/*
291+ * Copyright 2014 Canonical Ltd.
292+ *
293+ * This program is free software: you can redistribute it and/or modify it
294+ * under the terms of the GNU General Public License version 3, as published
295+ * by the Free Software Foundation.
296+ *
297+ * This program is distributed in the hope that it will be useful, but
298+ * WITHOUT ANY WARRANTY; without even the implied warranties of
299+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
300+ * PURPOSE. See the GNU General Public License for more details.
301+ *
302+ * You should have received a copy of the GNU General Public License along
303+ * with this program. If not, see <http://www.gnu.org/licenses/>.
304+ *
305+ * Authors:
306+ * Charles Kerr <charles.kerr@canonical.com>
307+ */
308+
309+#include "dbus-shared.h"
310+#include "device-provider-mock.h"
311+#include "device-provider-upower.h"
312+#include "dbus-testing.h"
313+#include "service.h"
314+#include "testing.h"
315+
316+#include <glib-object.h>
317+
318+/**
319+*** GObject Properties
320+**/
321+
322+enum
323+{
324+ PROP_0,
325+ PROP_SERVICE,
326+ LAST_PROP
327+};
328+
329+static GParamSpec * properties[LAST_PROP];
330+
331+/**
332+***
333+**/
334+
335+typedef struct
336+{
337+ GDBusConnection * bus;
338+ DbusTesting * skeleton;
339+ IndicatorPowerService * service;
340+ IndicatorPowerDevice * battery_mock;
341+ gpointer provider_mock;
342+ gpointer provider_upower;
343+}
344+IndicatorPowerTestingPrivate;
345+
346+typedef IndicatorPowerTestingPrivate priv_t;
347+
348+G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerTesting,
349+ indicator_power_testing,
350+ G_TYPE_OBJECT)
351+
352+#define get_priv(o) ((priv_t*)indicator_power_testing_get_instance_private(o))
353+
354+/***
355+****
356+***/
357+
358+static void
359+update_device_provider (IndicatorPowerTesting * self)
360+{
361+ priv_t * const p = get_priv(self);
362+ IndicatorPowerDeviceProvider * device_provider;
363+
364+ device_provider = dbus_testing_get_mock_battery_enabled(p->skeleton)
365+ ? p->provider_mock
366+ : p->provider_upower;
367+ indicator_power_service_set_device_provider(p->service, device_provider);
368+}
369+
370+static void
371+set_bus(IndicatorPowerTesting * self, GDBusConnection * bus)
372+{
373+ priv_t * p;
374+ GDBusInterfaceSkeleton * skel;
375+
376+ g_return_if_fail(INDICATOR_IS_POWER_TESTING(self));
377+ g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus));
378+
379+ p = get_priv (self);
380+
381+ if (p->bus == bus)
382+ return;
383+
384+ skel = G_DBUS_INTERFACE_SKELETON(p->skeleton);
385+
386+ if (p->bus != NULL)
387+ {
388+ if (skel != NULL)
389+ g_dbus_interface_skeleton_unexport (skel);
390+
391+ g_clear_object (&p->bus);
392+ }
393+
394+ if (bus != NULL)
395+ {
396+ GError * error;
397+
398+ p->bus = g_object_ref (bus);
399+
400+ error = NULL;
401+ if (!g_dbus_interface_skeleton_export(skel,
402+ bus,
403+ BUS_PATH"/Testing",
404+ &error))
405+ {
406+ g_warning ("Unable to export Testing properties: %s", error->message);
407+ g_error_free (error);
408+ }
409+ }
410+}
411+
412+/***
413+****
414+***/
415+
416+static void
417+on_mock_battery_enabled_changed(DbusTesting * skeleton G_GNUC_UNUSED,
418+ GParamSpec * pspec G_GNUC_UNUSED,
419+ IndicatorPowerTesting * self)
420+{
421+ update_device_provider (self);
422+}
423+
424+static void
425+on_mock_battery_level_changed(DbusTesting * skeleton,
426+ GParamSpec * pspec G_GNUC_UNUSED,
427+ IndicatorPowerTesting * self)
428+{
429+ g_object_set(get_priv(self)->battery_mock,
430+ INDICATOR_POWER_DEVICE_PERCENTAGE, (gdouble)dbus_testing_get_mock_battery_level(skeleton),
431+ NULL);
432+}
433+
434+static void
435+on_mock_battery_state_changed(DbusTesting * skeleton,
436+ GParamSpec * pspec G_GNUC_UNUSED,
437+ IndicatorPowerTesting * self)
438+{
439+ const gchar* state_str = dbus_testing_get_mock_battery_state(skeleton);
440+ UpDeviceState state;
441+
442+ if (!g_strcmp0(state_str, "charging"))
443+ {
444+ state = UP_DEVICE_STATE_CHARGING;
445+ }
446+ else if (!g_strcmp0(state_str, "discharging"))
447+ {
448+ state = UP_DEVICE_STATE_DISCHARGING;
449+ }
450+ else
451+ {
452+ g_warning("%s unsupported state: '%s'", G_STRLOC, state_str);
453+ state = UP_DEVICE_STATE_UNKNOWN;
454+ }
455+
456+ g_object_set(get_priv(self)->battery_mock,
457+ INDICATOR_POWER_DEVICE_STATE, (gint)state,
458+ NULL);
459+}
460+
461+static void
462+on_mock_battery_minutes_left_changed(DbusTesting * skeleton,
463+ GParamSpec * pspec G_GNUC_UNUSED,
464+ IndicatorPowerTesting * self)
465+{
466+ g_object_set(get_priv(self)->battery_mock,
467+ INDICATOR_POWER_DEVICE_TIME, (guint64)dbus_testing_get_mock_battery_minutes_left(skeleton),
468+ NULL);
469+}
470+
471+static void
472+on_bus_changed(IndicatorPowerService * service,
473+ GParamSpec * spec G_GNUC_UNUSED,
474+ IndicatorPowerTesting * self)
475+{
476+ GObject * bus = NULL;
477+ g_object_get(service, "bus", &bus, NULL);
478+ set_bus(self, G_DBUS_CONNECTION(bus));
479+ g_clear_object(&bus);
480+}
481+
482+/***
483+**** GObject virtual functions
484+***/
485+
486+static void
487+my_get_property(GObject * o,
488+ guint property_id,
489+ GValue * value,
490+ GParamSpec * pspec)
491+{
492+ IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING (o);
493+ priv_t * const p = get_priv(self);
494+
495+ switch (property_id)
496+ {
497+ case PROP_SERVICE:
498+ g_value_set_object(value, p->service);
499+ break;
500+
501+ default:
502+ G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec);
503+ }
504+}
505+
506+static void
507+my_set_property(GObject * o,
508+ guint property_id,
509+ const GValue * value,
510+ GParamSpec * pspec)
511+{
512+ IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING (o);
513+ priv_t * const p = get_priv(self);
514+
515+ switch (property_id)
516+ {
517+ case PROP_SERVICE:
518+ g_assert(p->service == NULL); /* G_PARAM_CONSTRUCT_ONLY */
519+ p->service = g_value_dup_object(value);
520+ break;
521+
522+ default:
523+ G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec);
524+ }
525+}
526+
527+static void
528+my_dispose(GObject * o)
529+{
530+ IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING(o);
531+ priv_t * const p = get_priv (self);
532+
533+ set_bus(self, NULL);
534+ g_clear_object(&p->skeleton);
535+ g_clear_object(&p->provider_upower);
536+ g_clear_object(&p->provider_mock);
537+ g_clear_object(&p->battery_mock);
538+ g_clear_object(&p->service);
539+
540+ G_OBJECT_CLASS (indicator_power_testing_parent_class)->dispose(o);
541+}
542+
543+static void
544+my_finalize (GObject * o G_GNUC_UNUSED)
545+{
546+}
547+
548+static void
549+my_constructed (GObject * o)
550+{
551+ IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING(o);
552+ priv_t * const p = get_priv (self);
553+
554+ g_assert(p->service != NULL); /* G_PARAM_CONSTRUCT_ONLY */
555+ g_signal_connect(p->service, "notify::bus", G_CALLBACK(on_bus_changed), o);
556+ on_bus_changed(p->service, NULL, self);
557+ update_device_provider(self);
558+}
559+
560+
561+/***
562+**** Instantiation
563+***/
564+
565+static void
566+indicator_power_testing_init (IndicatorPowerTesting * self)
567+{
568+ priv_t * const p = get_priv (self);
569+
570+ /* DBus Skeleton */
571+
572+ p->skeleton = dbus_testing_skeleton_new();
573+ dbus_testing_set_mock_battery_level(p->skeleton, 50u);
574+ dbus_testing_set_mock_battery_state(p->skeleton, "discharging");
575+ dbus_testing_set_mock_battery_enabled(p->skeleton, FALSE);
576+ dbus_testing_set_mock_battery_minutes_left(p->skeleton, 30);
577+
578+ g_signal_connect(p->skeleton, "notify::mock-battery-enabled",
579+ G_CALLBACK(on_mock_battery_enabled_changed), self);
580+ g_signal_connect(p->skeleton, "notify::mock-battery-level",
581+ G_CALLBACK(on_mock_battery_level_changed), self);
582+ g_signal_connect(p->skeleton, "notify::mock-battery-state",
583+ G_CALLBACK(on_mock_battery_state_changed), self);
584+ g_signal_connect(p->skeleton, "notify::mock-battery-minutes-left",
585+ G_CALLBACK(on_mock_battery_minutes_left_changed), self);
586+
587+ /* Mock Battery */
588+
589+ p->battery_mock = indicator_power_device_new("/some/path",
590+ UP_DEVICE_KIND_BATTERY,
591+ 50.0,
592+ UP_DEVICE_STATE_DISCHARGING,
593+ 60*30);
594+
595+
596+ /* Mock Provider */
597+
598+ p->provider_mock = indicator_power_device_provider_mock_new();
599+
600+ indicator_power_device_provider_add_device(INDICATOR_POWER_DEVICE_PROVIDER_MOCK(p->provider_mock),
601+ p->battery_mock);
602+
603+ /* UPower Provider */
604+
605+ p->provider_upower = indicator_power_device_provider_upower_new();
606+}
607+
608+static void
609+indicator_power_testing_class_init (IndicatorPowerTestingClass * klass)
610+{
611+ GObjectClass * object_class = G_OBJECT_CLASS (klass);
612+
613+ object_class->dispose = my_dispose;
614+ object_class->finalize = my_finalize;
615+ object_class->constructed = my_constructed;
616+ object_class->get_property = my_get_property;
617+ object_class->set_property = my_set_property;
618+
619+ properties[PROP_SERVICE] = g_param_spec_object (
620+ "service",
621+ "Servie",
622+ "The IndicatorPower Service",
623+ G_TYPE_OBJECT,
624+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
625+
626+ g_object_class_install_properties (object_class, LAST_PROP, properties);
627+}
628+
629+/***
630+**** Public API
631+***/
632+
633+IndicatorPowerTesting *
634+indicator_power_testing_new (IndicatorPowerService * service)
635+{
636+ GObject * o = g_object_new (INDICATOR_TYPE_POWER_TESTING, "service", service, NULL);
637+
638+ return INDICATOR_POWER_TESTING (o);
639+}
640+
641
642=== added file 'src/testing.h'
643--- src/testing.h 1970-01-01 00:00:00 +0000
644+++ src/testing.h 2014-10-15 01:58:54 +0000
645@@ -0,0 +1,66 @@
646+/*
647+ * Copyright 2014 Canonical Ltd.
648+ *
649+ * This program is free software: you can redistribute it and/or modify it
650+ * under the terms of the GNU General Public License version 3, as published
651+ * by the Free Software Foundation.
652+ *
653+ * This program is distributed in the hope that it will be useful, but
654+ * WITHOUT ANY WARRANTY; without even the implied warranties of
655+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
656+ * PURPOSE. See the GNU General Public License for more details.
657+ *
658+ * You should have received a copy of the GNU General Public License along
659+ * with this program. If not, see <http://www.gnu.org/licenses/>.
660+ *
661+ * Authors:
662+ * Charles Kerr <charles.kerr@canonical.com>
663+ */
664+
665+#ifndef __INDICATOR_POWER_TESTING_H__
666+#define __INDICATOR_POWER_TESTING_H__
667+
668+#include <gio/gio.h>
669+
670+#include "service.h"
671+
672+G_BEGIN_DECLS
673+
674+/* standard GObject macros */
675+#define INDICATOR_POWER_TESTING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_TESTING, IndicatorPowerTesting))
676+#define INDICATOR_TYPE_POWER_TESTING (indicator_power_testing_get_type())
677+#define INDICATOR_IS_POWER_TESTING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_TESTING))
678+#define INDICATOR_POWER_TESTING_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_POWER_TESTING, IndicatorPowerTestingClass))
679+
680+typedef struct _IndicatorPowerTesting IndicatorPowerTesting;
681+typedef struct _IndicatorPowerTestingClass IndicatorPowerTestingClass;
682+
683+/**
684+ * The Indicator Power Testing.
685+ */
686+struct _IndicatorPowerTesting
687+{
688+ /*< private >*/
689+ GObject parent;
690+};
691+
692+struct _IndicatorPowerTestingClass
693+{
694+ GObjectClass parent_class;
695+};
696+
697+/***
698+****
699+***/
700+
701+GType indicator_power_testing_get_type (void);
702+
703+IndicatorPowerTesting * indicator_power_testing_new (IndicatorPowerService * service);
704+
705+void indicator_power_testing_set_bus (IndicatorPowerTesting * self,
706+ GDBusConnection * connection);
707+
708+
709+G_END_DECLS
710+
711+#endif /* __INDICATOR_POWER_TESTING_H__ */
712
713=== modified file 'tests/CMakeLists.txt'
714--- tests/CMakeLists.txt 2014-07-22 14:58:29 +0000
715+++ tests/CMakeLists.txt 2014-10-15 01:58:54 +0000
716@@ -50,12 +50,3 @@
717 add_test_by_name(test-notify)
718 add_test(NAME dear-reader-the-next-test-takes-80-seconds COMMAND true)
719 add_test_by_name(test-device)
720-
721-###
722-###
723-
724-set (APP_NAME indicator-power-service-cmdline-battery)
725-add_executable (${APP_NAME} ${APP_NAME}.cc device-provider-mock.c)
726-add_dependencies (${APP_NAME} libindicatorpowerservice)
727-target_link_libraries (${APP_NAME} indicatorpowerservice ${SERVICE_DEPS_LIBRARIES})
728-
729
730=== removed file 'tests/indicator-power-service-cmdline-battery.cc'
731--- tests/indicator-power-service-cmdline-battery.cc 2014-09-09 04:22:39 +0000
732+++ tests/indicator-power-service-cmdline-battery.cc 1970-01-01 00:00:00 +0000
733@@ -1,127 +0,0 @@
734-/*
735- * Copyright 2014 Canonical Ltd.
736- *
737- * This program is free software: you can redistribute it and/or modify it
738- * under the terms of the GNU General Public License version 3, as published
739- * by the Free Software Foundation.
740- *
741- * This program is distributed in the hope that it will be useful, but
742- * WITHOUT ANY WARRANTY; without even the implied warranties of
743- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
744- * PURPOSE. See the GNU General Public License for more details.
745- *
746- * You should have received a copy of the GNU General Public License along
747- * with this program. If not, see <http://www.gnu.org/licenses/>.
748- *
749- * Authors:
750- * Charles Kerr <charles.kerr@canonical.com>
751- */
752-
753-#include <cstdlib>
754-
755-#include <locale.h> // setlocale()
756-#include <libintl.h> // bindtextdomain()
757-#include <unistd.h> // STDIN_FILENO
758-
759-#include <gio/gio.h>
760-
761-#include "device-provider-mock.h"
762-
763-#include "service.h"
764-
765-/***
766-****
767-***/
768-
769-static void
770-on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop)
771-{
772- g_message ("exiting: service couldn't acquire or lost ownership of busname");
773- g_main_loop_quit (static_cast<GMainLoop*>(loop));
774-}
775-
776-static IndicatorPowerDevice * battery = nullptr;
777-
778-static GMainLoop * loop = nullptr;
779-
780-static gboolean on_command_stream_available (GIOChannel *source,
781- GIOCondition /*condition*/,
782- gpointer /*user_data*/)
783-{
784- gchar * str = nullptr;
785- GError * error = nullptr;
786- auto status = g_io_channel_read_line (source, &str, nullptr, nullptr, &error);
787- g_assert_no_error (error);
788-
789- if (status == G_IO_STATUS_NORMAL)
790- {
791- g_strstrip (str);
792-
793- if (!g_strcmp0 (str, "charging"))
794- {
795- g_object_set (battery, INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_CHARGING, nullptr);
796- }
797- else if (!g_strcmp0 (str, "discharging"))
798- {
799- g_object_set (battery, INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_DISCHARGING, nullptr);
800- }
801- else
802- {
803- g_object_set (battery, INDICATOR_POWER_DEVICE_PERCENTAGE, atof(str), nullptr);
804- }
805- }
806- else if (status == G_IO_STATUS_EOF)
807- {
808- g_main_loop_quit (loop);
809- }
810-
811- g_free (str);
812- return G_SOURCE_CONTINUE;
813-}
814-
815-/* this is basically indicator-power-service with a custom provider */
816-int
817-main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED)
818-{
819- g_print("This test app has the same code as indicator-power-service\n"
820- "except instead of listening to UPower, it has a fake battery\n"
821- "which you can edit with keyboard inputs. Supported commands:\n"
822- "1. A number in [0..100] to set battery level\n"
823- "2. 'charging'\n"
824- "3. 'discharging'\n"
825- "4. ctrl-c to exit\n");
826-
827- IndicatorPowerDeviceProvider * device_provider;
828- IndicatorPowerService * service;
829-
830- g_assert(g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, true));
831- g_assert(g_setenv("GSETTINGS_BACKEND", "memory", true));
832-
833- /* boilerplate i18n */
834- setlocale (LC_ALL, "");
835- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
836- textdomain (GETTEXT_PACKAGE);
837-
838- /* read lines from the command line */
839- auto channel = g_io_channel_unix_new (STDIN_FILENO);
840- auto watch_tag = g_io_add_watch (channel, G_IO_IN, on_command_stream_available, nullptr);
841-
842- /* run */
843- battery = indicator_power_device_new ("/some/path", UP_DEVICE_KIND_BATTERY, 50.0, UP_DEVICE_STATE_DISCHARGING, 30*60);
844- device_provider = indicator_power_device_provider_mock_new ();
845- indicator_power_device_provider_add_device (INDICATOR_POWER_DEVICE_PROVIDER_MOCK(device_provider), battery);
846- service = indicator_power_service_new (device_provider);
847- loop = g_main_loop_new (NULL, FALSE);
848- g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST,
849- G_CALLBACK(on_name_lost), loop);
850- g_main_loop_run (loop);
851-
852- /* cleanup */
853- g_main_loop_unref (loop);
854- g_source_remove (watch_tag);
855- g_io_channel_unref (channel);
856- g_clear_object (&service);
857- g_clear_object (&device_provider);
858- g_clear_object (&battery);
859- return 0;
860-}
861
862=== modified file 'tests/manual'
863--- tests/manual 2014-09-11 20:02:31 +0000
864+++ tests/manual 2014-10-15 01:58:54 +0000
865@@ -1,21 +1,37 @@
866
867 Notes on Battery Testing
868
869-When building from source, an executable 'indicator-power-service-cmdline-battery' will be built in the tests/ directory. This has the same code as indicator-power-service, except instead of listening to UPower it has a single fake battery that can be set from the command line to set its charge level and whether it's charging or discharging.
870-
871-You'll need to stop the current indicator-power-service before starting the test one. After that, you enter in a number, or 'charging', or 'discharging', to set the fake battery. ctrl-c exits.
872-
873-Example:
874-
875-$ stop indicator-power # stop the real indicator-power service
876-$ build/tests/indicator-power-service-cmdline-battery # start the test service
877-50 # sets the fake battery level to 50%
878-30 # sets the fake battery level to 30%
879-charging # sets the fake battery to charging
880-discharging # sets the fake battery to discharging
881-ctrl-c # exits the test service
882-$ start indicator-power # restart the real service
883-
884+Mock battery propreties are available for testing purposes.
885+
886+The testing properties are DBus properties published on busname "com.canonical.indicator.power", object path "/com/canonical/indicator/power/Testing", and interface "com.canonical.indicator.power.Testing". The four properties are "MockBatteryEnabled" (boolean, default false), "MockBatteryLevel" (uint32 [0-100], default 50), "MockBatteryState" (string, default 'discharging'), "MockBatteryMinutesLeft" (minutes remaining to charge/discharge, uint32, default 30).
887+
888+Example use:
889+
890+Show the testing properties:
891+
892+$ gdbus call --session --dest "com.canonical.indicator.power" \
893+ --object-path /com/canonical/indicator/power/Testing \
894+ --method org.freedesktop.DBus.Properties.GetAll \
895+ com.canonical.indicator.power.Testing
896+({'MockBatteryEnabled': <false>, 'MockBatteryLevel': <uint32 50>, 'MockBatteryState': <'discharging'>, 'MockBatteryMinutesLeft': <uint32 30>},)
897+
898+Enable the mock battery:
899+
900+$ gdbus call --session --dest "com.canonical.indicator.power" \
901+ --object-path /com/canonical/indicator/power/Testing \
902+ --method org.freedesktop.DBus.Properties.Set \
903+ com.canonical.indicator.power.Testing \
904+ MockBatteryEnabled \
905+ "<true>"
906+
907+Set the mock battery's charge to 10%
908+
909+$ gdbus call --session --dest "com.canonical.indicator.power" \
910+ --object-path /com/canonical/indicator/power/Testing \
911+ --method org.freedesktop.DBus.Properties.Set \
912+ com.canonical.indicator.power.Testing \
913+ MockBatteryLevel \
914+ "<uint32 10>"
915
916
917 Test-case indicator-power/unity7-items-check

Subscribers

People subscribed via source and target branches