diff options
-rw-r--r-- | data/com.canonical.indicator.power.Testing.xml | 39 | ||||
-rw-r--r-- | src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/device-provider-mock.c (renamed from tests/device-provider-mock.c) | 2 | ||||
-rw-r--r-- | src/device-provider-mock.h (renamed from tests/device-provider-mock.h) | 0 | ||||
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/notifier.c | 58 | ||||
-rw-r--r-- | src/service.c | 13 | ||||
-rw-r--r-- | src/testing.c | 351 | ||||
-rw-r--r-- | src/testing.h | 66 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 9 | ||||
-rw-r--r-- | tests/indicator-power-service-cmdline-battery.cc | 127 | ||||
-rw-r--r-- | tests/manual | 38 |
12 files changed, 543 insertions, 179 deletions
diff --git a/data/com.canonical.indicator.power.Testing.xml b/data/com.canonical.indicator.power.Testing.xml new file mode 100644 index 0000000..25cd059 --- /dev/null +++ b/data/com.canonical.indicator.power.Testing.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> + <interface name="com.canonical.indicator.power.Testing"> + + <property name="MockBatteryEnabled" type="b" access="readwrite"> + <doc:doc> + <doc:description> + <doc:para>Whether or not the mock battery is enabled. (Default: false)</doc:para> + </doc:description> + </doc:doc> + </property> + + <property name="MockBatteryLevel" type="u" access="readwrite"> + <doc:doc> + <doc:description> + <doc:para>The charge level of the mock battery (0-100%, Default: 50%)</doc:para> + </doc:description> + </doc:doc> + </property> + + <property name="MockBatteryState" type="s" access="readwrite"> + <doc:doc> + <doc:description> + <doc:para>The mock battery's state. Possible values: 'charging', 'discharging' (Defualt: 'discharging')</doc:para> + </doc:description> + </doc:doc> + </property> + + <property name="MockBatteryMinutesLeft" type="u" access="readwrite"> + <doc:doc> + <doc:description> + <doc:para>Muntes left until the mock battery finishes charging/dischargin (Default: 30)</doc:para> + </doc:description> + </doc:doc> + </property> + + </interface> +</node> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f7efb80..6f4bfaf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,10 +6,12 @@ add_definitions(-DG_LOG_DOMAIN="Indicator-Power") # handwritten sources set(SERVICE_MANUAL_SOURCES brightness.c + device-provider-mock.c device-provider-upower.c device-provider.c device.c notifier.c + testing.c service.c) # generated sources @@ -19,6 +21,10 @@ add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-battery com.canonical.indicator.power Dbus ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Battery.xml) +add_gdbus_codegen_with_namespace(SERVICE_GENERATED_SOURCES dbus-testing + com.canonical.indicator.power + Dbus + ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.power.Testing.xml) # add the bin dir to our include path so the code can find the generated header files include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/device-provider-mock.c b/src/device-provider-mock.c index afca178..ccb80f0 100644 --- a/tests/device-provider-mock.c +++ b/src/device-provider-mock.c @@ -81,7 +81,7 @@ indicator_power_device_provider_interface_init (IndicatorPowerDeviceProviderInte } static void -indicator_power_device_provider_mock_init (IndicatorPowerDeviceProviderMock * self) +indicator_power_device_provider_mock_init (IndicatorPowerDeviceProviderMock * self G_GNUC_UNUSED) { } diff --git a/tests/device-provider-mock.h b/src/device-provider-mock.h index 4d06924..4d06924 100644 --- a/tests/device-provider-mock.h +++ b/src/device-provider-mock.h @@ -18,14 +18,13 @@ */ #include <locale.h> -#include <stdlib.h> /* exit() */ +#include <glib.h> #include <glib/gi18n.h> -#include <gio/gio.h> #include "device.h" -#include "device-provider-upower.h" #include "service.h" +#include "testing.h" /*** **** @@ -41,8 +40,8 @@ on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) int main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) { - IndicatorPowerDeviceProvider * device_provider; IndicatorPowerService * service; + IndicatorPowerTesting * testing; GMainLoop * loop; /* boilerplate i18n */ @@ -51,8 +50,8 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) textdomain (GETTEXT_PACKAGE); /* run */ - device_provider = indicator_power_device_provider_upower_new (); - service = indicator_power_service_new (device_provider); + service = indicator_power_service_new (NULL); + testing = indicator_power_testing_new (service); loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, G_CALLBACK(on_name_lost), loop); @@ -61,6 +60,6 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) /* cleanup */ g_main_loop_unref (loop); g_clear_object (&service); - g_clear_object (&device_provider); + g_clear_object (&testing); return 0; } diff --git a/src/notifier.c b/src/notifier.c index 993e332..4888610 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -55,8 +55,6 @@ static GParamSpec * properties[LAST_PROP]; static int instance_count = 0; -static gboolean actions_supported = FALSE; - /** *** **/ @@ -76,6 +74,9 @@ typedef struct GDBusConnection * bus; DbusBattery * dbus_battery; /* com.canonical.indicator.power.Battery skeleton */ + + gboolean caps_queried; + gboolean actions_supported; } IndicatorPowerNotifierPrivate; @@ -182,6 +183,33 @@ on_dismiss_clicked(NotifyNotification * nn G_GNUC_UNUSED, /* no-op; libnotify warns if we have a NULL action callback */ } +static gboolean +are_actions_supported(IndicatorPowerNotifier * self) +{ + priv_t * const p = get_priv(self); + + if (!p->caps_queried) + { + gboolean actions_supported; + GList * caps; + GList * l; + + /* see if actions are supported */ + actions_supported = FALSE; + caps = notify_get_server_caps(); + for (l=caps; l!=NULL && !actions_supported; l=l->next) + if (!g_strcmp0(l->data, "actions")) + actions_supported = TRUE; + + p->actions_supported = actions_supported; + p->caps_queried = TRUE; + + g_list_free_full(caps, g_free); + } + + return p->actions_supported; +} + static void notification_show(IndicatorPowerNotifier * self) { @@ -214,7 +242,7 @@ notification_show(IndicatorPowerNotifier * self) g_strfreev (icon_names); g_free (body); - if (actions_supported) + if (are_actions_supported(self)) { notify_notification_set_hint(nn, "x-canonical-snap-decisions", g_variant_new_string("true")); notify_notification_set_hint(nn, "x-canonical-non-shaped-icon", g_variant_new_string("true")); @@ -354,6 +382,7 @@ my_finalize (GObject * o G_GNUC_UNUSED) **** Instantiation ***/ + static void indicator_power_notifier_init (IndicatorPowerNotifier * self) { @@ -365,27 +394,8 @@ indicator_power_notifier_init (IndicatorPowerNotifier * self) p->power_level = POWER_LEVEL_OK; - if (!instance_count++) - { - actions_supported = FALSE; - - if (!notify_init("indicator-power-service")) - { - g_critical("Unable to initialize libnotify! Notifications might not be shown."); - } - else - { - GList * caps; - GList * l; - - /* see if actions are supported */ - caps = notify_get_server_caps(); - for (l=caps; l!=NULL && !actions_supported; l=l->next) - if (!g_strcmp0(l->data, "actions")) - actions_supported = TRUE; - g_list_free_full(caps, g_free); - } - } + if (!instance_count++ && !notify_init("indicator-power-service")) + g_critical("Unable to initialize libnotify! Notifications might not be shown."); } static void diff --git a/src/service.c b/src/service.c index 32cec38..6bae06e 100644 --- a/src/service.c +++ b/src/service.c @@ -51,6 +51,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, + PROP_BUS, PROP_DEVICE_PROVIDER, LAST_PROP }; @@ -839,6 +840,7 @@ on_bus_acquired (GDBusConnection * connection, g_debug ("bus acquired: %s", name); p->conn = g_object_ref (G_OBJECT (connection)); + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_BUS]); /* export the battery properties */ indicator_power_notifier_set_bus (p->notifier, connection); @@ -977,6 +979,10 @@ my_get_property (GObject * o, switch (property_id) { + case PROP_BUS: + g_value_set_object (value, p->conn); + break; + case PROP_DEVICE_PROVIDER: g_value_set_object (value, p->device_provider); break; @@ -1113,6 +1119,13 @@ indicator_power_service_class_init (IndicatorPowerServiceClass * klass) properties[PROP_0] = NULL; + properties[PROP_BUS] = g_param_spec_object ( + "bus", + "Bus", + "GDBusConnection for exporting menus/actions", + G_TYPE_OBJECT, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + properties[PROP_DEVICE_PROVIDER] = g_param_spec_object ( "device-provider", "Device Provider", diff --git a/src/testing.c b/src/testing.c new file mode 100644 index 0000000..2822b7e --- /dev/null +++ b/src/testing.c @@ -0,0 +1,351 @@ +/* + * Copyright 2014 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#include "dbus-shared.h" +#include "device-provider-mock.h" +#include "device-provider-upower.h" +#include "dbus-testing.h" +#include "service.h" +#include "testing.h" + +#include <glib-object.h> + +/** +*** GObject Properties +**/ + +enum +{ + PROP_0, + PROP_SERVICE, + LAST_PROP +}; + +static GParamSpec * properties[LAST_PROP]; + +/** +*** +**/ + +typedef struct +{ + GDBusConnection * bus; + DbusTesting * skeleton; + IndicatorPowerService * service; + IndicatorPowerDevice * battery_mock; + gpointer provider_mock; + gpointer provider_upower; +} +IndicatorPowerTestingPrivate; + +typedef IndicatorPowerTestingPrivate priv_t; + +G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPowerTesting, + indicator_power_testing, + G_TYPE_OBJECT) + +#define get_priv(o) ((priv_t*)indicator_power_testing_get_instance_private(o)) + +/*** +**** +***/ + +static void +update_device_provider (IndicatorPowerTesting * self) +{ + priv_t * const p = get_priv(self); + IndicatorPowerDeviceProvider * device_provider; + + device_provider = dbus_testing_get_mock_battery_enabled(p->skeleton) + ? p->provider_mock + : p->provider_upower; + indicator_power_service_set_device_provider(p->service, device_provider); +} + +static void +set_bus(IndicatorPowerTesting * self, GDBusConnection * bus) +{ + priv_t * p; + GDBusInterfaceSkeleton * skel; + + g_return_if_fail(INDICATOR_IS_POWER_TESTING(self)); + g_return_if_fail((bus == NULL) || G_IS_DBUS_CONNECTION(bus)); + + p = get_priv (self); + + if (p->bus == bus) + return; + + skel = G_DBUS_INTERFACE_SKELETON(p->skeleton); + + if (p->bus != NULL) + { + if (skel != NULL) + g_dbus_interface_skeleton_unexport (skel); + + g_clear_object (&p->bus); + } + + if (bus != NULL) + { + GError * error; + + p->bus = g_object_ref (bus); + + error = NULL; + if (!g_dbus_interface_skeleton_export(skel, + bus, + BUS_PATH"/Testing", + &error)) + { + g_warning ("Unable to export Testing properties: %s", error->message); + g_error_free (error); + } + } +} + +/*** +**** +***/ + +static void +on_mock_battery_enabled_changed(DbusTesting * skeleton G_GNUC_UNUSED, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorPowerTesting * self) +{ + update_device_provider (self); +} + +static void +on_mock_battery_level_changed(DbusTesting * skeleton, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorPowerTesting * self) +{ + g_object_set(get_priv(self)->battery_mock, + INDICATOR_POWER_DEVICE_PERCENTAGE, (gdouble)dbus_testing_get_mock_battery_level(skeleton), + NULL); +} + +static void +on_mock_battery_state_changed(DbusTesting * skeleton, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorPowerTesting * self) +{ + const gchar* state_str = dbus_testing_get_mock_battery_state(skeleton); + UpDeviceState state; + + if (!g_strcmp0(state_str, "charging")) + { + state = UP_DEVICE_STATE_CHARGING; + } + else if (!g_strcmp0(state_str, "discharging")) + { + state = UP_DEVICE_STATE_DISCHARGING; + } + else + { + g_warning("%s unsupported state: '%s'", G_STRLOC, state_str); + state = UP_DEVICE_STATE_UNKNOWN; + } + + g_object_set(get_priv(self)->battery_mock, + INDICATOR_POWER_DEVICE_STATE, (gint)state, + NULL); +} + +static void +on_mock_battery_minutes_left_changed(DbusTesting * skeleton, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorPowerTesting * self) +{ + g_object_set(get_priv(self)->battery_mock, + INDICATOR_POWER_DEVICE_TIME, (guint64)dbus_testing_get_mock_battery_minutes_left(skeleton), + NULL); +} + +static void +on_bus_changed(IndicatorPowerService * service, + GParamSpec * spec G_GNUC_UNUSED, + IndicatorPowerTesting * self) +{ + GObject * bus = NULL; + g_object_get(service, "bus", &bus, NULL); + set_bus(self, G_DBUS_CONNECTION(bus)); + g_clear_object(&bus); +} + +/*** +**** GObject virtual functions +***/ + +static void +my_get_property(GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING (o); + priv_t * const p = get_priv(self); + + switch (property_id) + { + case PROP_SERVICE: + g_value_set_object(value, p->service); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec); + } +} + +static void +my_set_property(GObject * o, + guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING (o); + priv_t * const p = get_priv(self); + + switch (property_id) + { + case PROP_SERVICE: + g_assert(p->service == NULL); /* G_PARAM_CONSTRUCT_ONLY */ + p->service = g_value_dup_object(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(o, property_id, pspec); + } +} + +static void +my_dispose(GObject * o) +{ + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING(o); + priv_t * const p = get_priv (self); + + set_bus(self, NULL); + g_clear_object(&p->skeleton); + g_clear_object(&p->provider_upower); + g_clear_object(&p->provider_mock); + g_clear_object(&p->battery_mock); + g_clear_object(&p->service); + + G_OBJECT_CLASS (indicator_power_testing_parent_class)->dispose(o); +} + +static void +my_finalize (GObject * o G_GNUC_UNUSED) +{ +} + +static void +my_constructed (GObject * o) +{ + IndicatorPowerTesting * const self = INDICATOR_POWER_TESTING(o); + priv_t * const p = get_priv (self); + + g_assert(p->service != NULL); /* G_PARAM_CONSTRUCT_ONLY */ + g_signal_connect(p->service, "notify::bus", G_CALLBACK(on_bus_changed), o); + on_bus_changed(p->service, NULL, self); + update_device_provider(self); +} + + +/*** +**** Instantiation +***/ + +static void +indicator_power_testing_init (IndicatorPowerTesting * self) +{ + priv_t * const p = get_priv (self); + + /* DBus Skeleton */ + + p->skeleton = dbus_testing_skeleton_new(); + dbus_testing_set_mock_battery_level(p->skeleton, 50u); + dbus_testing_set_mock_battery_state(p->skeleton, "discharging"); + dbus_testing_set_mock_battery_enabled(p->skeleton, FALSE); + dbus_testing_set_mock_battery_minutes_left(p->skeleton, 30); + + g_signal_connect(p->skeleton, "notify::mock-battery-enabled", + G_CALLBACK(on_mock_battery_enabled_changed), self); + g_signal_connect(p->skeleton, "notify::mock-battery-level", + G_CALLBACK(on_mock_battery_level_changed), self); + g_signal_connect(p->skeleton, "notify::mock-battery-state", + G_CALLBACK(on_mock_battery_state_changed), self); + g_signal_connect(p->skeleton, "notify::mock-battery-minutes-left", + G_CALLBACK(on_mock_battery_minutes_left_changed), self); + + /* Mock Battery */ + + p->battery_mock = indicator_power_device_new("/some/path", + UP_DEVICE_KIND_BATTERY, + 50.0, + UP_DEVICE_STATE_DISCHARGING, + 60*30); + + + /* Mock Provider */ + + p->provider_mock = indicator_power_device_provider_mock_new(); + + indicator_power_device_provider_add_device(INDICATOR_POWER_DEVICE_PROVIDER_MOCK(p->provider_mock), + p->battery_mock); + + /* UPower Provider */ + + p->provider_upower = indicator_power_device_provider_upower_new(); +} + +static void +indicator_power_testing_class_init (IndicatorPowerTestingClass * klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + object_class->constructed = my_constructed; + object_class->get_property = my_get_property; + object_class->set_property = my_set_property; + + properties[PROP_SERVICE] = g_param_spec_object ( + "service", + "Servie", + "The IndicatorPower Service", + G_TYPE_OBJECT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +/*** +**** Public API +***/ + +IndicatorPowerTesting * +indicator_power_testing_new (IndicatorPowerService * service) +{ + GObject * o = g_object_new (INDICATOR_TYPE_POWER_TESTING, "service", service, NULL); + + return INDICATOR_POWER_TESTING (o); +} + diff --git a/src/testing.h b/src/testing.h new file mode 100644 index 0000000..1370170 --- /dev/null +++ b/src/testing.h @@ -0,0 +1,66 @@ +/* + * Copyright 2014 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#ifndef __INDICATOR_POWER_TESTING_H__ +#define __INDICATOR_POWER_TESTING_H__ + +#include <gio/gio.h> + +#include "service.h" + +G_BEGIN_DECLS + +/* standard GObject macros */ +#define INDICATOR_POWER_TESTING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_POWER_TESTING, IndicatorPowerTesting)) +#define INDICATOR_TYPE_POWER_TESTING (indicator_power_testing_get_type()) +#define INDICATOR_IS_POWER_TESTING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_POWER_TESTING)) +#define INDICATOR_POWER_TESTING_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_POWER_TESTING, IndicatorPowerTestingClass)) + +typedef struct _IndicatorPowerTesting IndicatorPowerTesting; +typedef struct _IndicatorPowerTestingClass IndicatorPowerTestingClass; + +/** + * The Indicator Power Testing. + */ +struct _IndicatorPowerTesting +{ + /*< private >*/ + GObject parent; +}; + +struct _IndicatorPowerTestingClass +{ + GObjectClass parent_class; +}; + +/*** +**** +***/ + +GType indicator_power_testing_get_type (void); + +IndicatorPowerTesting * indicator_power_testing_new (IndicatorPowerService * service); + +void indicator_power_testing_set_bus (IndicatorPowerTesting * self, + GDBusConnection * connection); + + +G_END_DECLS + +#endif /* __INDICATOR_POWER_TESTING_H__ */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a0d24af..02ecb1b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -50,12 +50,3 @@ endfunction() add_test_by_name(test-notify) add_test(NAME dear-reader-the-next-test-takes-80-seconds COMMAND true) add_test_by_name(test-device) - -### -### - -set (APP_NAME indicator-power-service-cmdline-battery) -add_executable (${APP_NAME} ${APP_NAME}.cc device-provider-mock.c) -add_dependencies (${APP_NAME} libindicatorpowerservice) -target_link_libraries (${APP_NAME} indicatorpowerservice ${SERVICE_DEPS_LIBRARIES}) - diff --git a/tests/indicator-power-service-cmdline-battery.cc b/tests/indicator-power-service-cmdline-battery.cc deleted file mode 100644 index 50ed2bb..0000000 --- a/tests/indicator-power-service-cmdline-battery.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2014 Canonical Ltd. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3, as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Authors: - * Charles Kerr <charles.kerr@canonical.com> - */ - -#include <cstdlib> - -#include <locale.h> // setlocale() -#include <libintl.h> // bindtextdomain() -#include <unistd.h> // STDIN_FILENO - -#include <gio/gio.h> - -#include "device-provider-mock.h" - -#include "service.h" - -/*** -**** -***/ - -static void -on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) -{ - g_message ("exiting: service couldn't acquire or lost ownership of busname"); - g_main_loop_quit (static_cast<GMainLoop*>(loop)); -} - -static IndicatorPowerDevice * battery = nullptr; - -static GMainLoop * loop = nullptr; - -static gboolean on_command_stream_available (GIOChannel *source, - GIOCondition /*condition*/, - gpointer /*user_data*/) -{ - gchar * str = nullptr; - GError * error = nullptr; - auto status = g_io_channel_read_line (source, &str, nullptr, nullptr, &error); - g_assert_no_error (error); - - if (status == G_IO_STATUS_NORMAL) - { - g_strstrip (str); - - if (!g_strcmp0 (str, "charging")) - { - g_object_set (battery, INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_CHARGING, nullptr); - } - else if (!g_strcmp0 (str, "discharging")) - { - g_object_set (battery, INDICATOR_POWER_DEVICE_STATE, UP_DEVICE_STATE_DISCHARGING, nullptr); - } - else - { - g_object_set (battery, INDICATOR_POWER_DEVICE_PERCENTAGE, atof(str), nullptr); - } - } - else if (status == G_IO_STATUS_EOF) - { - g_main_loop_quit (loop); - } - - g_free (str); - return G_SOURCE_CONTINUE; -} - -/* this is basically indicator-power-service with a custom provider */ -int -main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) -{ - g_print("This test app has the same code as indicator-power-service\n" - "except instead of listening to UPower, it has a fake battery\n" - "which you can edit with keyboard inputs. Supported commands:\n" - "1. A number in [0..100] to set battery level\n" - "2. 'charging'\n" - "3. 'discharging'\n" - "4. ctrl-c to exit\n"); - - IndicatorPowerDeviceProvider * device_provider; - IndicatorPowerService * service; - - g_assert(g_setenv("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, true)); - g_assert(g_setenv("GSETTINGS_BACKEND", "memory", true)); - - /* boilerplate i18n */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - - /* read lines from the command line */ - auto channel = g_io_channel_unix_new (STDIN_FILENO); - auto watch_tag = g_io_add_watch (channel, G_IO_IN, on_command_stream_available, nullptr); - - /* run */ - battery = indicator_power_device_new ("/some/path", UP_DEVICE_KIND_BATTERY, 50.0, UP_DEVICE_STATE_DISCHARGING, 30*60); - device_provider = indicator_power_device_provider_mock_new (); - indicator_power_device_provider_add_device (INDICATOR_POWER_DEVICE_PROVIDER_MOCK(device_provider), battery); - service = indicator_power_service_new (device_provider); - loop = g_main_loop_new (NULL, FALSE); - g_signal_connect (service, INDICATOR_POWER_SERVICE_SIGNAL_NAME_LOST, - G_CALLBACK(on_name_lost), loop); - g_main_loop_run (loop); - - /* cleanup */ - g_main_loop_unref (loop); - g_source_remove (watch_tag); - g_io_channel_unref (channel); - g_clear_object (&service); - g_clear_object (&device_provider); - g_clear_object (&battery); - return 0; -} diff --git a/tests/manual b/tests/manual index 1ec1524..1e6febd 100644 --- a/tests/manual +++ b/tests/manual @@ -1,21 +1,37 @@ Notes on Battery Testing -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. +Mock battery propreties are available for testing purposes. -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. +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). -Example: +Example use: -$ stop indicator-power # stop the real indicator-power service -$ build/tests/indicator-power-service-cmdline-battery # start the test service -50 # sets the fake battery level to 50% -30 # sets the fake battery level to 30% -charging # sets the fake battery to charging -discharging # sets the fake battery to discharging -ctrl-c # exits the test service -$ start indicator-power # restart the real service +Show the testing properties: +$ gdbus call --session --dest "com.canonical.indicator.power" \ + --object-path /com/canonical/indicator/power/Testing \ + --method org.freedesktop.DBus.Properties.GetAll \ + com.canonical.indicator.power.Testing +({'MockBatteryEnabled': <false>, 'MockBatteryLevel': <uint32 50>, 'MockBatteryState': <'discharging'>, 'MockBatteryMinutesLeft': <uint32 30>},) + +Enable the mock battery: + +$ gdbus call --session --dest "com.canonical.indicator.power" \ + --object-path /com/canonical/indicator/power/Testing \ + --method org.freedesktop.DBus.Properties.Set \ + com.canonical.indicator.power.Testing \ + MockBatteryEnabled \ + "<true>" + +Set the mock battery's charge to 10% + +$ gdbus call --session --dest "com.canonical.indicator.power" \ + --object-path /com/canonical/indicator/power/Testing \ + --method org.freedesktop.DBus.Properties.Set \ + com.canonical.indicator.power.Testing \ + MockBatteryLevel \ + "<uint32 10>" Test-case indicator-power/unity7-items-check |