From da980e33f340734c91950d244b980c7d8b5eef95 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 26 Jun 2014 15:55:17 -0500 Subject: Add Exporter's implementation to an Impl file because I'm about to shovel more methods and fields in there. --- include/datetime/exporter.h | 26 ++----- src/exporter.cpp | 170 +++++++++++++++++++++++++++----------------- src/main.cpp | 2 +- tests/test-exporter.cpp | 2 +- 4 files changed, 112 insertions(+), 88 deletions(-) diff --git a/include/datetime/exporter.h b/include/datetime/exporter.h index c228cc1..8ae70b1 100644 --- a/include/datetime/exporter.h +++ b/include/datetime/exporter.h @@ -25,8 +25,6 @@ #include -#include // GActionGroup - #include // std::shared_ptr #include @@ -40,31 +38,21 @@ namespace datetime { class Exporter { public: - Exporter() =default; + Exporter(); ~Exporter(); - core::Signal<> name_lost; + core::Signal<>& name_lost(); void publish(const std::shared_ptr& actions, const std::vector>& menus); private: - static void on_bus_acquired(GDBusConnection*, const gchar *name, gpointer gthis); - void on_bus_acquired(GDBusConnection*, const gchar *name); - - static void on_name_lost(GDBusConnection*, const gchar *name, gpointer gthis); - void on_name_lost(GDBusConnection*, const gchar *name); - - std::set m_exported_menu_ids; - guint m_own_id = 0; - guint m_exported_actions_id = 0; - GDBusConnection * m_dbus_connection = nullptr; - std::shared_ptr m_actions; - std::vector> m_menus; + class Impl; + std::unique_ptr p; - // we've got raw pointers and gsignal tags in here, so disable copying - Exporter(const Exporter&) =delete; - Exporter& operator=(const Exporter&) =delete; + // disable copying + Exporter(const Exporter&) =delete; + Exporter& operator=(const Exporter&) =delete; }; } // namespace datetime diff --git a/src/exporter.cpp b/src/exporter.cpp index ccd6e5c..a4919e9 100644 --- a/src/exporter.cpp +++ b/src/exporter.cpp @@ -31,108 +31,144 @@ namespace datetime { **** ***/ -Exporter::~Exporter() +class Exporter::Impl { - if (m_dbus_connection != nullptr) - { - for(auto& id : m_exported_menu_ids) - g_dbus_connection_unexport_menu_model(m_dbus_connection, id); +public: - if (m_exported_actions_id) - g_dbus_connection_unexport_action_group(m_dbus_connection, m_exported_actions_id); + Impl (Exporter* owner): + m_owner(owner) + { } - if (m_own_id) - g_bus_unown_name(m_own_id); + ~Impl() + { + if (m_bus != nullptr) + { + for(auto& id : m_exported_menu_ids) + g_dbus_connection_unexport_menu_model(m_bus, id); - g_clear_object(&m_dbus_connection); -} + if (m_exported_actions_id) + g_dbus_connection_unexport_action_group(m_bus, m_exported_actions_id); + } -/*** -**** -***/ + if (m_own_id) + g_bus_unown_name(m_own_id); -void -Exporter::on_bus_acquired(GDBusConnection* connection, const gchar* name, gpointer gthis) -{ - g_debug("bus acquired: %s", name); - static_cast(gthis)->on_bus_acquired(connection, name); -} + g_clear_object(&m_bus); + } -void -Exporter::on_bus_acquired(GDBusConnection* connection, const gchar* /*name*/) -{ - m_dbus_connection = static_cast(g_object_ref(G_OBJECT(connection))); - - // export the actions - GError * error = nullptr; - const auto id = g_dbus_connection_export_action_group(m_dbus_connection, - BUS_PATH, - m_actions->action_group(), - &error); - if (id) + core::Signal<> name_lost; + + void publish(const std::shared_ptr& actions, + const std::vector>& menus) { - m_exported_actions_id = id; + m_actions = actions; + m_menus = menus; + m_own_id = g_bus_own_name(G_BUS_TYPE_SESSION, + BUS_NAME, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + on_bus_acquired, + nullptr, + on_name_lost, + this, + nullptr); } - else + +private: + + static void on_bus_acquired(GDBusConnection* connection, + const gchar* name, + gpointer gthis) { - g_warning("cannot export action group: %s", error->message); - g_clear_error(&error); + g_debug("bus acquired: %s", name); + static_cast(gthis)->on_bus_acquired(connection, name); } - // export the menus - for(auto& menu : m_menus) + void on_bus_acquired(GDBusConnection* bus, const gchar* /*name*/) { - const auto path = std::string(BUS_PATH) + "/" + menu->name(); - const auto id = g_dbus_connection_export_menu_model(m_dbus_connection, path.c_str(), menu->menu_model(), &error); + m_bus = static_cast(g_object_ref(G_OBJECT(bus))); + + // export the actions + GError * error = nullptr; + const auto id = g_dbus_connection_export_action_group(m_bus, + BUS_PATH, + m_actions->action_group(), + &error); if (id) { - m_exported_menu_ids.insert(id); + m_exported_actions_id = id; } else { - if (error != nullptr) - g_warning("cannot export %s menu: %s", menu->name().c_str(), error->message); + g_warning("cannot export action group: %s", error->message); g_clear_error(&error); } + + // export the menus + for(auto& menu : m_menus) + { + const auto path = std::string(BUS_PATH) + "/" + menu->name(); + const auto id = g_dbus_connection_export_menu_model(m_bus, path.c_str(), menu->menu_model(), &error); + if (id) + { + m_exported_menu_ids.insert(id); + } + else + { + if (error != nullptr) + g_warning("cannot export %s menu: %s", menu->name().c_str(), error->message); + g_clear_error(&error); + } + } } -} + + /*** + **** + ***/ + + static void on_name_lost(GDBusConnection*, const gchar* name, gpointer gthis) + { + g_debug("name lost: %s", name); + static_cast(gthis)->name_lost(); + } + + /*** + **** + ***/ + + Exporter const * m_owner; + std::set m_exported_menu_ids; + guint m_own_id = 0; + guint m_exported_actions_id = 0; + GDBusConnection* m_bus = nullptr; + std::shared_ptr m_actions; + std::vector> m_menus; +}; + /*** **** ***/ -void -Exporter::on_name_lost(GDBusConnection* connection, const gchar* name, gpointer gthis) +Exporter::Exporter(): + p(new Impl(this)) { - g_debug("name lost: %s", name); - static_cast(gthis)->on_name_lost(connection, name); } -void -Exporter::on_name_lost(GDBusConnection* /*connection*/, const gchar* /*name*/) + +Exporter::~Exporter() { - name_lost(); } -/*** -**** -***/ +core::Signal<>& Exporter::name_lost() +{ + return p->name_lost; +} -void -Exporter::publish(const std::shared_ptr& actions, - const std::vector>& menus) +void Exporter::publish(const std::shared_ptr& actions, + const std::vector>& menus) { - m_actions = actions; - m_menus = menus; - m_own_id = g_bus_own_name(G_BUS_TYPE_SESSION, - BUS_NAME, - G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, - on_bus_acquired, - nullptr, - on_name_lost, - this, - nullptr); + p->publish(actions, menus); } /*** diff --git a/src/main.cpp b/src/main.cpp index 1940eb6..04845ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -164,7 +164,7 @@ main(int /*argc*/, char** /*argv*/) // export them & run until we lose the busname auto loop = g_main_loop_new(nullptr, false); Exporter exporter; - exporter.name_lost.connect([loop](){ + exporter.name_lost().connect([loop](){ g_message("%s exiting; failed/lost bus ownership", GETTEXT_PACKAGE); g_main_loop_quit(loop); }); diff --git a/tests/test-exporter.cpp b/tests/test-exporter.cpp index a255ef9..4fb2c54 100644 --- a/tests/test-exporter.cpp +++ b/tests/test-exporter.cpp @@ -122,7 +122,7 @@ TEST_F(ExporterFixture, Publish) // try closing the connection prematurely // to test Exporter's name-lost signal bool name_lost = false; - exporter.name_lost.connect([this,&name_lost](){ + exporter.name_lost().connect([this,&name_lost](){ name_lost = true; g_main_loop_quit(loop); }); -- cgit v1.2.3 From 90debef5ca85c6a51cf85d6f6b9d402ff5077b0b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 26 Jun 2014 20:46:06 -0500 Subject: fix clang++ warning about an unused private field in EdsEngine --- src/engine-eds.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/engine-eds.cpp b/src/engine-eds.cpp index 80a47da..58be0c4 100644 --- a/src/engine-eds.cpp +++ b/src/engine-eds.cpp @@ -41,8 +41,7 @@ class EdsEngine::Impl { public: - Impl(EdsEngine& owner): - m_owner(owner), + Impl(): m_cancellable(g_cancellable_new()) { e_source_registry_new(m_cancellable, on_source_registry_ready, this); @@ -492,7 +491,6 @@ private: return G_SOURCE_CONTINUE; } - EdsEngine& m_owner; core::Signal<> m_changed; std::set m_sources; std::map m_clients; @@ -508,7 +506,7 @@ private: ***/ EdsEngine::EdsEngine(): - p(new Impl(*this)) + p(new Impl()) { } -- cgit v1.2.3 From dda9044eb9740ca995139711cd8318815bf88e2a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 26 Jun 2014 20:47:52 -0500 Subject: fix clang++ warning about unused private field in snap.cpp's Sound class --- src/snap.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/snap.cpp b/src/snap.cpp index 25632e9..4a19d6e 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -60,7 +60,6 @@ public: m_clock(clock), m_filename(filename), m_volume(volume), - m_duration_minutes(duration_minutes), m_loop(loop), m_canberra_id(get_next_canberra_id()), m_loop_end_time(clock->localtime().add_full(0, 0, 0, 0, duration_minutes, 0.0)) @@ -184,7 +183,6 @@ private: const std::shared_ptr m_clock; const std::string m_filename; const AlarmVolume m_volume; - const int m_duration_minutes; const bool m_loop; const int32_t m_canberra_id; const DateTime m_loop_end_time; -- cgit v1.2.3 From ff5881ace7f91ca998b9722bc17a00fec3166461 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 26 Jun 2014 20:52:36 -0500 Subject: fix test-menus.cpp build failure in clang++ --- tests/test-menus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-menus.cpp b/tests/test-menus.cpp index b485037..f5f8df2 100644 --- a/tests/test-menus.cpp +++ b/tests/test-menus.cpp @@ -484,7 +484,7 @@ TEST_F(MenuFixture, HelloWorld) EXPECT_EQ(Menu::NUM_PROFILES, m_menus.size()); for (int i=0; imenu_model() != nullptr); EXPECT_EQ(i, m_menus[i]->profile()); } -- cgit v1.2.3 From c5081444f4f493dc386012bcb99d2430fe26dc5a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 26 Jun 2014 21:36:42 -0500 Subject: Expose the alarm settings via dbus properties. --- ...anonical.indicator.datetime.AlarmProperties.xml | 31 ++++++ include/datetime/exporter.h | 3 +- src/CMakeLists.txt | 31 ++++-- src/exporter.cpp | 115 +++++++++++++++++++-- src/main.cpp | 2 +- tests/CMakeLists.txt | 2 + tests/test-exporter.cpp | 93 ++++++++++++++++- 7 files changed, 261 insertions(+), 16 deletions(-) create mode 100644 data/com.canonical.indicator.datetime.AlarmProperties.xml diff --git a/data/com.canonical.indicator.datetime.AlarmProperties.xml b/data/com.canonical.indicator.datetime.AlarmProperties.xml new file mode 100644 index 0000000..d25fa82 --- /dev/null +++ b/data/com.canonical.indicator.datetime.AlarmProperties.xml @@ -0,0 +1,31 @@ + + + + + + + + + The default alarm sound's filename. + + + + + + + + How loudly to play alarm sounds. [Range: 1-100] + + + + + + + + How long an alarm's sound should be looped. + + + + + + diff --git a/include/datetime/exporter.h b/include/datetime/exporter.h index 8ae70b1..dd57263 100644 --- a/include/datetime/exporter.h +++ b/include/datetime/exporter.h @@ -22,6 +22,7 @@ #include #include +#include #include @@ -38,7 +39,7 @@ namespace datetime { class Exporter { public: - Exporter(); + Exporter(const std::shared_ptr&); ~Exporter(); core::Signal<>& name_lost(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ffa1523..af09c71 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,13 @@ set (SERVICE_LIB "indicatordatetimeservice") set (SERVICE_EXEC "indicator-datetime-service") -SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g ${CXX_WARNING_ARGS} ${GCOV_FLAGS}") -SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g ${CXX_WARNING_ARGS} ${GCOV_FLAGS}") - add_definitions (-DTIMEZONE_FILE="/etc/timezone" -DG_LOG_DOMAIN="Indicator-Datetime") -set (SERVICE_SOURCES +# handwritten sources +set (SERVICE_C_SOURCES + utils.c) +set (SERVICE_CXX_SOURCES actions.cpp actions-live.cpp alarm-queue-simple.cpp @@ -32,16 +32,33 @@ set (SERVICE_SOURCES timezones-live.cpp utils.c wakeup-timer-mainloop.cpp) - if (HAVE_UBUNTU_HW_ALARM_H) - set (SERVICE_SOURCES ${SERVICE_SOURCES} wakeup-timer-uha.cpp) + set (SERVICE_CXX_SOURCES ${SERVICE_CXX_SOURCES} wakeup-timer-uha.cpp) endif () -add_library (${SERVICE_LIB} STATIC ${SERVICE_SOURCES}) +# generated sources +include (GdbusCodegen) +set(SERVICE_GENERATED_SOURCES) +add_gdbus_codegen(SERVICE_GENERATED_SOURCES dbus-alarm-properties + com.canonical.indicator + ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.datetime.AlarmProperties.xml) + +# add warnings/coverage info on handwritten files +# but not the autogenerated ones... +set_source_files_properties(${SERVICE_CXX_SOURCES} + PROPERTIES COMPILE_FLAGS "${CXX_WARNING_ARGS} ${GCOV_FLAGS} -g -std=c++11") +set_source_files_properties(${SERVICE_C_SOURCES} + PROPERTIES COMPILE_FLAGS "${CXX_WARNING_ARGS} ${GCOV_FLAGS} -g -std=c99") + +# add the bin dir to our include path so our code can find the generated header files +include_directories (${CMAKE_CURRENT_BINARY_DIR}) + +add_library (${SERVICE_LIB} STATIC ${SERVICE_C_SOURCES} ${SERVICE_CXX_SOURCES} ${SERVICE_GENERATED_SOURCES}) include_directories (${CMAKE_SOURCE_DIR}) link_directories (${SERVICE_DEPS_LIBRARY_DIRS}) add_executable (${SERVICE_EXEC} main.cpp) +set_source_files_properties(${SERVICE_SOURCES} main.cpp PROPERTIES COMPILE_FLAGS "${CXX_WARNING_ARGS} -g -std=c++11") target_link_libraries (${SERVICE_EXEC} ${SERVICE_LIB} ${SERVICE_DEPS_LIBRARIES} ${GCOV_LIBS}) install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) diff --git a/src/exporter.cpp b/src/exporter.cpp index a4919e9..3ba95bf 100644 --- a/src/exporter.cpp +++ b/src/exporter.cpp @@ -20,6 +20,8 @@ #include #include +#include "dbus-alarm-properties.h" + #include #include @@ -35,9 +37,11 @@ class Exporter::Impl { public: - Impl (Exporter* owner): - m_owner(owner) + Impl(const std::shared_ptr& settings): + m_settings(settings), + m_alarm_props(datetime_alarm_properties_skeleton_new()) { + alarm_properties_init(); } ~Impl() @@ -51,6 +55,9 @@ public: g_dbus_connection_unexport_action_group(m_bus, m_exported_actions_id); } + g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(m_alarm_props)); + g_clear_object(&m_alarm_props); + if (m_own_id) g_bus_unown_name(m_own_id); @@ -76,6 +83,95 @@ public: private: + /*** + **** + ***/ + + static void + on_gobject_notify_string(GObject* o, GParamSpec* pspec, gpointer p) + { + gchar* val = nullptr; + g_object_get (o, pspec->name, &val, nullptr); + static_cast*>(p)->set(val); + g_free(val); + } + void bind_string_property(gpointer o, const char* propname, + core::Property& p) + { + // initialize the GObject property from the Settings + g_object_set(o, propname, p.get().c_str(), nullptr); + + // when the GObject changes, update the Settings + const std::string notify_propname = std::string("notify::") + propname; + g_signal_connect(o, notify_propname.c_str(), + G_CALLBACK(on_gobject_notify_string), &p); + + // when the Settings changes, update the GObject + p.changed().connect([o, propname](const std::string& s){ + g_object_set(o, propname, s.c_str(), nullptr); + }); + } + + + static void + on_gobject_notify_int(GObject* o, GParamSpec* pspec, gpointer p) + { + int val = 0; + g_object_get (o, pspec->name, &val, nullptr); + static_cast*>(p)->set(val); + } + void bind_int_property(gpointer o, const char* propname, core::Property& p) + { + // initialize the GObject property from the Settings + g_object_set(o, propname, p.get(), nullptr); + + // when the GObject changes, update the Settings + const std::string notify_propname = std::string("notify::") + propname; + g_signal_connect(o, notify_propname.c_str(), + G_CALLBACK(on_gobject_notify_int), &p); + + // when the Settings changes, update the GObject + p.changed().connect([o, propname](int i){ + g_object_set(o, propname, i, nullptr); + }); + } + + + static void + on_gobject_notify_volume(GObject* o, GParamSpec* pspec, gpointer p) + { + int val = 0; + g_object_get (o, pspec->name, &val, nullptr); + static_cast*>(p)->set(AlarmVolume(val)); + } + void bind_volume_property(gpointer o, const char* propname, core::Property& p) + { + // initialize the GObject property from the Settings + g_object_set(o, propname, (int)p.get(), nullptr); + + // when the GObject changes, update the Settings + const std::string notify_propname = std::string("notify::") + propname; + g_signal_connect(o, notify_propname.c_str(), + G_CALLBACK(on_gobject_notify_volume), &p); + + // when the Settings changes, update the GObject + p.changed().connect([o, propname](AlarmVolume i){ + g_object_set(o, propname, (int)i, nullptr); + }); + } + + + void alarm_properties_init() + { + bind_int_property(m_alarm_props, "duration", m_settings->alarm_duration); + bind_volume_property(m_alarm_props, "default-volume", m_settings->alarm_volume); + bind_string_property(m_alarm_props, "default-sound", m_settings->alarm_sound); + } + + /*** + **** + ***/ + static void on_bus_acquired(GDBusConnection* connection, const gchar* name, gpointer gthis) @@ -88,8 +184,14 @@ private: { m_bus = static_cast(g_object_ref(G_OBJECT(bus))); - // export the actions + // export the alarm properties GError * error = nullptr; + g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(m_alarm_props), + m_bus, + BUS_PATH"/AlarmProperties", + &error); + + // export the actions const auto id = g_dbus_connection_export_action_group(m_bus, BUS_PATH, m_actions->action_group(), @@ -136,13 +238,14 @@ private: **** ***/ - Exporter const * m_owner; + std::shared_ptr m_settings; std::set m_exported_menu_ids; guint m_own_id = 0; guint m_exported_actions_id = 0; GDBusConnection* m_bus = nullptr; std::shared_ptr m_actions; std::vector> m_menus; + DatetimeAlarmProperties* m_alarm_props = nullptr; }; @@ -150,8 +253,8 @@ private: **** ***/ -Exporter::Exporter(): - p(new Impl(this)) +Exporter::Exporter(const std::shared_ptr& settings): + p(new Impl(settings)) { } diff --git a/src/main.cpp b/src/main.cpp index 04845ce..cc81cd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -163,7 +163,7 @@ main(int /*argc*/, char** /*argv*/) // export them & run until we lose the busname auto loop = g_main_loop_new(nullptr, false); - Exporter exporter; + Exporter exporter(state->settings); exporter.name_lost().connect([loop](){ g_message("%s exiting; failed/lost bus ownership", GETTEXT_PACKAGE); g_main_loop_quit(loop); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fe6d7eb..26b326d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,9 +27,11 @@ add_custom_command (OUTPUT gschemas.compiled # look for headers in our src dir, and also in the directories where we autogenerate files... include_directories (${CMAKE_SOURCE_DIR}/src) +include_directories (${CMAKE_BINARY_DIR}/src) include_directories (${CMAKE_CURRENT_BINARY_DIR}) include_directories (${DBUSTEST_INCLUDE_DIRS}) + add_definitions (-DSANDBOX="${CMAKE_CURRENT_BINARY_DIR}") diff --git a/tests/test-exporter.cpp b/tests/test-exporter.cpp index 4fb2c54..3f502cf 100644 --- a/tests/test-exporter.cpp +++ b/tests/test-exporter.cpp @@ -21,6 +21,8 @@ #include "state-mock.h" #include "glib-fixture.h" +#include "dbus-alarm-properties.h" + #include #include #include @@ -76,13 +78,14 @@ TEST_F(ExporterFixture, Publish) { std::shared_ptr state(new MockState); std::shared_ptr actions(new MockActions(state)); + std::shared_ptr settings(new Settings); std::vector> menus; MenuFactory menu_factory (actions, state); for(int i=0; i state(new MockState); + std::shared_ptr actions(new MockActions(state)); + std::shared_ptr settings(new Settings); + std::vector> menus; + + MenuFactory menu_factory (actions, state); + for(int i=0; i(gproxy) = datetime_alarm_properties_proxy_new_for_bus_finish(res, &error); + EXPECT_TRUE(error == nullptr); + }; + + DatetimeAlarmProperties* proxy = nullptr; + datetime_alarm_properties_proxy_new_for_bus(G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + BUS_NAME, + BUS_PATH"/AlarmProperties", + nullptr, + on_proxy_ready, + &proxy); + wait_msec(100); + ASSERT_TRUE(proxy != nullptr); + + /*** + **** Try changing the Settings -- do the DBus properties change to match it? + ***/ + + auto expected_volume = ALARM_VOLUME_VERY_LOUD; + int expected_duration = 60; + const char * expected_sound = "/tmp/foo.wav"; + settings->alarm_volume.set(expected_volume); + settings->alarm_duration.set(expected_duration); + settings->alarm_sound.set(expected_sound); + wait_msec(); + + static constexpr const char* const SOUND_PROP {"default-sound"}; + static constexpr const char* const VOLUME_PROP {"default-volume"}; + static constexpr const char* const DURATION_PROP {"duration"}; + + char* sound = nullptr; + int volume = -1; + int duration = -1; + g_object_get(proxy, SOUND_PROP, &sound, + VOLUME_PROP, &volume, + DURATION_PROP, &duration, + nullptr); + EXPECT_STREQ(expected_sound, sound); + EXPECT_EQ(expected_volume, volume); + EXPECT_EQ(expected_duration, duration); + + /*** + **** Try chaning the DBus properties -- do the Settings change to match it? + ***/ + + expected_volume = ALARM_VOLUME_VERY_QUIET; + expected_duration = 30; + expected_sound = "/tmp/bar.wav"; + g_object_set(proxy, SOUND_PROP, expected_sound, + VOLUME_PROP, expected_volume, + DURATION_PROP, expected_duration, + nullptr); + wait_msec(); + + EXPECT_STREQ(expected_sound, settings->alarm_sound.get().c_str()); + EXPECT_EQ(expected_volume, settings->alarm_volume.get()); + EXPECT_EQ(expected_duration, settings->alarm_duration.get()); + + // cleanup + g_clear_object(&proxy); +} -- cgit v1.2.3 From 8bb09ca0225886c18e351d3c6156521ed479edd1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 26 Jun 2014 22:13:13 -0500 Subject: Design prefers to have a volume slider instead of presets, so remove the AlarmVolume enum and replace it with an int range. --- data/com.canonical.indicator.datetime.gschema.xml | 12 +++------- include/datetime/settings-shared.h | 10 -------- include/datetime/settings.h | 2 +- src/exporter.cpp | 26 +------------------- src/settings-live.cpp | 6 ++--- src/snap.cpp | 29 +++++++++++------------ tests/manual-test-snap.cpp | 22 ++++++++++++++++- tests/test-exporter.cpp | 4 ++-- tests/test-settings.cpp | 26 +------------------- 9 files changed, 46 insertions(+), 91 deletions(-) diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml index 3e0082d..17a38ed 100644 --- a/data/com.canonical.indicator.datetime.gschema.xml +++ b/data/com.canonical.indicator.datetime.gschema.xml @@ -5,13 +5,6 @@ - - - - - - - true @@ -137,8 +130,9 @@ If an alarm doesn't specify its own sound file, this file will be used as the fallback sound. - - 'normal' + + + 50 The alarm's default volume level. The volume at which alarms will be played. diff --git a/include/datetime/settings-shared.h b/include/datetime/settings-shared.h index bfddd88..23d2e1c 100644 --- a/include/datetime/settings-shared.h +++ b/include/datetime/settings-shared.h @@ -30,16 +30,6 @@ typedef enum } TimeFormatMode; -typedef enum -{ - ALARM_VOLUME_VERY_QUIET, - ALARM_VOLUME_QUIET, - ALARM_VOLUME_NORMAL, - ALARM_VOLUME_LOUD, - ALARM_VOLUME_VERY_LOUD -} -AlarmVolume; - #define SETTINGS_INTERFACE "com.canonical.indicator.datetime" #define SETTINGS_SHOW_CLOCK_S "show-clock" #define SETTINGS_TIME_FORMAT_S "time-format" diff --git a/include/datetime/settings.h b/include/datetime/settings.h index a941f05..26d4ed0 100644 --- a/include/datetime/settings.h +++ b/include/datetime/settings.h @@ -57,7 +57,7 @@ public: core::Property time_format_mode; core::Property timezone_name; core::Property alarm_sound; - core::Property alarm_volume; + core::Property alarm_volume; core::Property alarm_duration; }; diff --git a/src/exporter.cpp b/src/exporter.cpp index 3ba95bf..a5a059d 100644 --- a/src/exporter.cpp +++ b/src/exporter.cpp @@ -137,34 +137,10 @@ private: } - static void - on_gobject_notify_volume(GObject* o, GParamSpec* pspec, gpointer p) - { - int val = 0; - g_object_get (o, pspec->name, &val, nullptr); - static_cast*>(p)->set(AlarmVolume(val)); - } - void bind_volume_property(gpointer o, const char* propname, core::Property& p) - { - // initialize the GObject property from the Settings - g_object_set(o, propname, (int)p.get(), nullptr); - - // when the GObject changes, update the Settings - const std::string notify_propname = std::string("notify::") + propname; - g_signal_connect(o, notify_propname.c_str(), - G_CALLBACK(on_gobject_notify_volume), &p); - - // when the Settings changes, update the GObject - p.changed().connect([o, propname](AlarmVolume i){ - g_object_set(o, propname, (int)i, nullptr); - }); - } - - void alarm_properties_init() { bind_int_property(m_alarm_props, "duration", m_settings->alarm_duration); - bind_volume_property(m_alarm_props, "default-volume", m_settings->alarm_volume); + bind_int_property(m_alarm_props, "default-volume", m_settings->alarm_volume); bind_string_property(m_alarm_props, "default-sound", m_settings->alarm_sound); } diff --git a/src/settings-live.cpp b/src/settings-live.cpp index e34ace1..369d2d6 100644 --- a/src/settings-live.cpp +++ b/src/settings-live.cpp @@ -123,8 +123,8 @@ LiveSettings::LiveSettings(): g_settings_set_string(m_settings, SETTINGS_ALARM_SOUND_S, value.c_str()); }); - alarm_volume.changed().connect([this](AlarmVolume value){ - g_settings_set_enum(m_settings, SETTINGS_ALARM_VOLUME_S, gint(value)); + alarm_volume.changed().connect([this](int value){ + g_settings_set_int(m_settings, SETTINGS_ALARM_VOLUME_S, value); }); alarm_duration.changed().connect([this](int value){ @@ -229,7 +229,7 @@ void LiveSettings::update_alarm_sound() void LiveSettings::update_alarm_volume() { - alarm_volume.set((AlarmVolume)g_settings_get_enum(m_settings, SETTINGS_ALARM_VOLUME_S)); + alarm_volume.set(g_settings_get_int(m_settings, SETTINGS_ALARM_VOLUME_S)); } void LiveSettings::update_alarm_duration() diff --git a/src/snap.cpp b/src/snap.cpp index 4a19d6e..40fd541 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -54,7 +54,7 @@ public: Sound(const std::shared_ptr& clock, const std::string& filename, - AlarmVolume volume, + int volume, int duration_minutes, bool loop): m_clock(clock), @@ -132,18 +132,17 @@ private: g_clear_pointer(&props, ca_proplist_destroy); } - static float get_gain_level(const AlarmVolume volume) + static float get_gain_level(int volume) { - /* These values aren't set in stone -- - arrived at from from manual tests on Nexus 4 */ - switch (volume) - { - case ALARM_VOLUME_VERY_QUIET: return -8; - case ALARM_VOLUME_QUIET: return -4; - case ALARM_VOLUME_LOUD: return 4; - case ALARM_VOLUME_VERY_LOUD: return 8; - default: return 0; - } + const int clamped_volume = CLAMP(volume, 1, 100); + + /* This range isn't set in stone -- + arrived at from manual tests on Nextus 4 */ + constexpr float gain_low = -10; + constexpr float gain_high = 10; + + constexpr float gain_range = gain_high - gain_low; + return gain_low + (gain_range * (clamped_volume / 100.0f)); } static void on_done_playing(ca_context*, uint32_t, int rv, void* gself) @@ -182,7 +181,7 @@ private: const std::shared_ptr m_clock; const std::string m_filename; - const AlarmVolume m_volume; + const int m_volume; const bool m_loop; const int32_t m_canberra_id; const DateTime m_loop_end_time; @@ -195,7 +194,7 @@ class SoundBuilder public: void set_clock(const std::shared_ptr& c) {m_clock = c;} void set_filename(const std::string& s) {m_filename = s;} - void set_volume(const AlarmVolume v) {m_volume = v;} + void set_volume(const int v) {m_volume = v;} void set_duration_minutes(int i) {m_duration_minutes=i;} void set_looping(bool b) {m_looping=b;} @@ -210,7 +209,7 @@ public: private: std::shared_ptr m_clock; std::string m_filename; - AlarmVolume m_volume = ALARM_VOLUME_NORMAL; + int m_volume = 50; int m_duration_minutes = 30; bool m_looping = true; }; diff --git a/tests/manual-test-snap.cpp b/tests/manual-test-snap.cpp index 90dbe08..cc24a67 100644 --- a/tests/manual-test-snap.cpp +++ b/tests/manual-test-snap.cpp @@ -41,10 +41,29 @@ namespace g_main_loop_quit(static_cast(gloop)); return G_SOURCE_REMOVE; }; + + int volume = 50; + + GOptionEntry entries[] = + { + { "volume", 'v', 0, G_OPTION_ARG_INT, &volume, "Volume level [1..100]", "volume" }, + { NULL } + }; } -int main() +int main(int argc, const char* argv[]) { + GError* error = nullptr; + GOptionContext* context = g_option_context_new(nullptr); + g_option_context_add_main_entries(context, entries, nullptr); + if (!g_option_context_parse(context, &argc, (gchar***)&argv, &error)) + { + g_print("option parsing failed: %s\n", error->message); + exit(1); + } + g_option_context_free(context); + volume = CLAMP(volume, 1, 100); + Appointment a; a.color = "green"; a.summary = "Alarm"; @@ -74,6 +93,7 @@ int main() g_debug("SCHEMA_DIR is %s", SCHEMA_DIR); auto settings = std::make_shared(); + settings->alarm_volume.set(volume); auto timezones = std::make_shared(settings, TIMEZONE_FILE); auto clock = std::make_shared(timezones); Snap snap (clock, settings); diff --git a/tests/test-exporter.cpp b/tests/test-exporter.cpp index 3f502cf..e947740 100644 --- a/tests/test-exporter.cpp +++ b/tests/test-exporter.cpp @@ -183,7 +183,7 @@ TEST_F(ExporterFixture, AlarmProperties) **** Try changing the Settings -- do the DBus properties change to match it? ***/ - auto expected_volume = ALARM_VOLUME_VERY_LOUD; + auto expected_volume = 1; int expected_duration = 60; const char * expected_sound = "/tmp/foo.wav"; settings->alarm_volume.set(expected_volume); @@ -210,7 +210,7 @@ TEST_F(ExporterFixture, AlarmProperties) **** Try chaning the DBus properties -- do the Settings change to match it? ***/ - expected_volume = ALARM_VOLUME_VERY_QUIET; + expected_volume = 100; expected_duration = 30; expected_sound = "/tmp/bar.wav"; g_object_set(proxy, SOUND_PROP, expected_sound, diff --git a/tests/test-settings.cpp b/tests/test-settings.cpp index 2b500b2..e4aeef7 100644 --- a/tests/test-settings.cpp +++ b/tests/test-settings.cpp @@ -151,6 +151,7 @@ TEST_F(SettingsFixture, BoolProperties) TEST_F(SettingsFixture, IntProperties) { TestIntProperty(m_settings->alarm_duration, SETTINGS_ALARM_DURATION_S); + TestIntProperty(m_settings->alarm_volume, SETTINGS_ALARM_VOLUME_S); } TEST_F(SettingsFixture, StringProperties) @@ -181,31 +182,6 @@ TEST_F(SettingsFixture, TimeFormatMode) } } -TEST_F(SettingsFixture, AlarmVolume) -{ - const auto key = SETTINGS_ALARM_VOLUME_S; - const AlarmVolume volumes[] = { ALARM_VOLUME_VERY_QUIET, - ALARM_VOLUME_QUIET, - ALARM_VOLUME_NORMAL, - ALARM_VOLUME_LOUD, - ALARM_VOLUME_VERY_LOUD }; - - for(const auto& val : volumes) - { - g_settings_set_enum(m_gsettings, key, val); - EXPECT_EQ(val, m_settings->alarm_volume.get()); - EXPECT_EQ(val, g_settings_get_enum(m_gsettings, key)); - } - - for(const auto& val : volumes) - { - m_settings->alarm_volume.set(val); - EXPECT_EQ(val, m_settings->alarm_volume.get()); - EXPECT_EQ(val, g_settings_get_enum(m_gsettings, key)); - } -} - - namespace { std::vector strv_to_vector(const gchar** strv) -- cgit v1.2.3 From a872431f78e5518419c6af5e365db972f362ba9a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 27 Jun 2014 08:53:13 -0500 Subject: use intltool-merge to generate com.canonical.indicator.datetime.gschema.xml --- data/CMakeLists.txt | 10 +- data/com.canonical.indicator.datetime.gschema.xml | 150 --------------------- ...com.canonical.indicator.datetime.gschema.xml.in | 150 +++++++++++++++++++++ 3 files changed, 158 insertions(+), 152 deletions(-) delete mode 100644 data/com.canonical.indicator.datetime.gschema.xml create mode 100644 data/com.canonical.indicator.datetime.gschema.xml.in diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 5d9e545..d66c865 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -4,9 +4,15 @@ include (UseGSettings) set (SCHEMA_NAME "com.canonical.indicator.datetime.gschema.xml") -set (SCHEMA_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME}") -add_schema (${SCHEMA_FILE}) +set (SCHEMA_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_NAME}") +set (SCHEMA_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME}.in") + +# generate the .xml file using intltool +set (ENV{LC_ALL} "C") +execute_process (COMMAND intltool-merge -quiet --xml-style --utf8 --no-translations "${SCHEMA_FILE_IN}" "${SCHEMA_FILE}") +# let UseGSettings do the rest +add_schema (${SCHEMA_FILE}) ## ## Upstart Job File diff --git a/data/com.canonical.indicator.datetime.gschema.xml b/data/com.canonical.indicator.datetime.gschema.xml deleted file mode 100644 index 17a38ed..0000000 --- a/data/com.canonical.indicator.datetime.gschema.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - true - Show the clock in the panel - - Controls whether the clock indicator appears in the panel or not. - - - - 'locale-default' - What the time format should be - - Controls the time format that is displayed in the indicator. For almost - all users this should be the default for their locale. If you think the - setting is wrong for your locale please join or talk to the translation - team for your language. If you just want something different you can - adjust this to be either 12 or 24 time. Or, you can use a custom format - string and set the custom-time-format setting. - - - - "%l:%M %p" - The format string passed to strftime - - The format of the time and/or date that is visible on the panel when using - the indicator. For most users this will be a set of predefined values as - determined by the configuration utility, but advanced users can change it - to anything strftime can accept. Look at the man page on strftime for - more information. - - - - false - Show the number of seconds in the indicator - - Makes the datetime indicator show the number of seconds in the indicator. - It's important to note that this will cause additional battery drain as - the time will update 60 times as often, so it is not recommended. Also, - this setting will be ignored if the time-format value is set to custom. - - - - false - Show the day of the week in the indicator - - Puts the day of the week on the panel along with the time and/or date - depending on settings. This setting will be ignored if the time-format - value is set to custom. - - - - false - Show the month and date in the indicator - - Puts the month and the date in the panel along with the time and/or day - of the week depending on settings. This setting will be ignored if the - time-format value is set to custom. - - - - false - Show the year in the indicator - - Puts the year in the panel along with the month and the date. - This setting will be ignored if either the time-format value is set to custom - or if show-date is set to false. - - - - true - Show the monthly calendar in the indicator - - Puts the monthly calendar in indicator-datetime's menu. - - - - false - Show week numbers in calendar - - Shows the week numbers in the monthly calendar in indicator-datetime's menu. - - - - true - Show events in the indicator - - Shows events from Evolution in indicator-datetime's menu. - - - - false - Show the auto-detected location in the indicator - - Shows your current location (determined from geoclue and /etc/timezone) in indicator-datetime's menu. - - - - false - Show locations in the indicator - - Shows custom defined locations in indicator-datetime's menu. - - - - ['UTC'] - A List of locations - - Adds the list of locations the user has configured to display in the - indicator-datetime menu. - - - - '' - The name of the current timezone - - Some timezones can be known by many different cities or names. This setting describes how the current zone prefers to be named. Format is "TIMEZONE NAME" (e.g. "America/New_York Boston" to name the New_York zone Boston). - - - - '/usr/share/sounds/ubuntu/ringtones/Suru arpeggio.ogg' - The alarm's default sound file. - - If an alarm doesn't specify its own sound file, this file will be used as the fallback sound. - - - - - 50 - The alarm's default volume level. - - The volume at which alarms will be played. - - - - - 30 - The alarm's duration. - - How long the alarm's sound will be looped if its snap decision is not dismissed by the user. - - - - diff --git a/data/com.canonical.indicator.datetime.gschema.xml.in b/data/com.canonical.indicator.datetime.gschema.xml.in new file mode 100644 index 0000000..776f6c7 --- /dev/null +++ b/data/com.canonical.indicator.datetime.gschema.xml.in @@ -0,0 +1,150 @@ + + + + + + + + + + true + <_summary>Show the clock in the panel + <_description> + Controls whether the clock indicator appears in the panel or not. + + + + 'locale-default' + <_summary>What the time format should be + <_description> + Controls the time format that is displayed in the indicator. For almost + all users this should be the default for their locale. If you think the + setting is wrong for your locale please join or talk to the translation + team for your language. If you just want something different you can + adjust this to be either 12 or 24 time. Or, you can use a custom format + string and set the custom-time-format setting. + + + + "%l:%M %p" + <_summary>The format string passed to strftime + <_description> + The format of the time and/or date that is visible on the panel when using + the indicator. For most users this will be a set of predefined values as + determined by the configuration utility, but advanced users can change it + to anything strftime can accept. Look at the man page on strftime for + more information. + + + + false + <_summary>Show the number of seconds in the indicator + <_description> + Makes the datetime indicator show the number of seconds in the indicator. + It's important to note that this will cause additional battery drain as + the time will update 60 times as often, so it is not recommended. Also, + this setting will be ignored if the time-format value is set to custom. + + + + false + <_summary>Show the day of the week in the indicator + <_description> + Puts the day of the week on the panel along with the time and/or date + depending on settings. This setting will be ignored if the time-format + value is set to custom. + + + + false + <_summary>Show the month and date in the indicator + <_description> + Puts the month and the date in the panel along with the time and/or day + of the week depending on settings. This setting will be ignored if the + time-format value is set to custom. + + + + false + <_summary>Show the year in the indicator + <_description> + Puts the year in the panel along with the month and the date. + This setting will be ignored if either the time-format value is set to custom + or if show-date is set to false. + + + + true + <_summary>Show the monthly calendar in the indicator + <_description> + Puts the monthly calendar in indicator-datetime's menu. + + + + false + <_summary>Show week numbers in calendar + <_description> + Shows the week numbers in the monthly calendar in indicator-datetime's menu. + + + + true + <_summary>Show events in the indicator + <_description> + Shows events from Evolution in indicator-datetime's menu. + + + + false + <_summary>Show the auto-detected location in the indicator + <_description> + Shows your current location (determined from geoclue and /etc/timezone) in indicator-datetime's menu. + + + + false + <_summary>Show locations in the indicator + <_description> + Shows custom defined locations in indicator-datetime's menu. + + + + ['UTC'] + <_summary>A List of locations + <_description> + Adds the list of locations the user has configured to display in the + indicator-datetime menu. + + + + '' + <_summary>The name of the current timezone + <_description> + Some timezones can be known by many different cities or names. This setting describes how the current zone prefers to be named. Format is "TIMEZONE NAME" (e.g. "America/New_York Boston" to name the New_York zone Boston). + + + + '/usr/share/sounds/ubuntu/ringtones/Suru arpeggio.ogg' + <_summary>The alarm's default sound file. + <_description> + If an alarm doesn't specify its own sound file, this file will be used as the fallback sound. + + + + + 50 + <_summary>The alarm's default volume level. + <_description> + The volume at which alarms will be played. + + + + + 30 + <_summary>The alarm's duration. + <_description> + How long the alarm's sound will be looped if its snap decision is not dismissed by the user. + + + + -- cgit v1.2.3 From eebf8f911cedf5124ada2f91576f821da6f421b0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 27 Jun 2014 09:46:21 -0500 Subject: use unsigned ints for the alarm volume, duration properties --- ...com.canonical.indicator.datetime.gschema.xml.in | 4 ++-- include/datetime/settings.h | 4 ++-- src/exporter.cpp | 24 ++++++++++++---------- src/settings-live.cpp | 12 +++++------ src/snap.cpp | 18 ++++++++-------- tests/CMakeLists.txt | 4 ++-- tests/test-settings.cpp | 22 ++++++++++---------- 7 files changed, 45 insertions(+), 43 deletions(-) diff --git a/data/com.canonical.indicator.datetime.gschema.xml.in b/data/com.canonical.indicator.datetime.gschema.xml.in index 776f6c7..62b42c1 100644 --- a/data/com.canonical.indicator.datetime.gschema.xml.in +++ b/data/com.canonical.indicator.datetime.gschema.xml.in @@ -130,7 +130,7 @@ If an alarm doesn't specify its own sound file, this file will be used as the fallback sound. - + 50 <_summary>The alarm's default volume level. @@ -138,7 +138,7 @@ The volume at which alarms will be played. - + 30 <_summary>The alarm's duration. diff --git a/include/datetime/settings.h b/include/datetime/settings.h index 26d4ed0..e5f885e 100644 --- a/include/datetime/settings.h +++ b/include/datetime/settings.h @@ -57,8 +57,8 @@ public: core::Property time_format_mode; core::Property timezone_name; core::Property alarm_sound; - core::Property alarm_volume; - core::Property alarm_duration; + core::Property alarm_volume; + core::Property alarm_duration; }; } // namespace datetime diff --git a/src/exporter.cpp b/src/exporter.cpp index a5a059d..e2b60f2 100644 --- a/src/exporter.cpp +++ b/src/exporter.cpp @@ -107,20 +107,22 @@ private: G_CALLBACK(on_gobject_notify_string), &p); // when the Settings changes, update the GObject - p.changed().connect([o, propname](const std::string& s){ - g_object_set(o, propname, s.c_str(), nullptr); + p.changed().connect([o, propname](const std::string& val){ + g_object_set(o, propname, val.c_str(), nullptr); }); } static void - on_gobject_notify_int(GObject* o, GParamSpec* pspec, gpointer p) + on_gobject_notify_uint(GObject* o, GParamSpec* pspec, gpointer p) { - int val = 0; + uint val = 0; g_object_get (o, pspec->name, &val, nullptr); - static_cast*>(p)->set(val); + static_cast*>(p)->set(val); } - void bind_int_property(gpointer o, const char* propname, core::Property& p) + void bind_uint_property(gpointer o, + const char* propname, + core::Property& p) { // initialize the GObject property from the Settings g_object_set(o, propname, p.get(), nullptr); @@ -128,19 +130,19 @@ private: // when the GObject changes, update the Settings const std::string notify_propname = std::string("notify::") + propname; g_signal_connect(o, notify_propname.c_str(), - G_CALLBACK(on_gobject_notify_int), &p); + G_CALLBACK(on_gobject_notify_uint), &p); // when the Settings changes, update the GObject - p.changed().connect([o, propname](int i){ - g_object_set(o, propname, i, nullptr); + p.changed().connect([o, propname](unsigned int val){ + g_object_set(o, propname, val, nullptr); }); } void alarm_properties_init() { - bind_int_property(m_alarm_props, "duration", m_settings->alarm_duration); - bind_int_property(m_alarm_props, "default-volume", m_settings->alarm_volume); + bind_uint_property(m_alarm_props, "duration", m_settings->alarm_duration); + bind_uint_property(m_alarm_props, "default-volume", m_settings->alarm_volume); bind_string_property(m_alarm_props, "default-sound", m_settings->alarm_sound); } diff --git a/src/settings-live.cpp b/src/settings-live.cpp index 369d2d6..71bbd96 100644 --- a/src/settings-live.cpp +++ b/src/settings-live.cpp @@ -123,12 +123,12 @@ LiveSettings::LiveSettings(): g_settings_set_string(m_settings, SETTINGS_ALARM_SOUND_S, value.c_str()); }); - alarm_volume.changed().connect([this](int value){ - g_settings_set_int(m_settings, SETTINGS_ALARM_VOLUME_S, value); + alarm_volume.changed().connect([this](unsigned int value){ + g_settings_set_uint(m_settings, SETTINGS_ALARM_VOLUME_S, value); }); - alarm_duration.changed().connect([this](int value){ - g_settings_set_int(m_settings, SETTINGS_ALARM_DURATION_S, value); + alarm_duration.changed().connect([this](unsigned int value){ + g_settings_set_uint(m_settings, SETTINGS_ALARM_DURATION_S, value); }); } @@ -229,12 +229,12 @@ void LiveSettings::update_alarm_sound() void LiveSettings::update_alarm_volume() { - alarm_volume.set(g_settings_get_int(m_settings, SETTINGS_ALARM_VOLUME_S)); + alarm_volume.set(g_settings_get_uint(m_settings, SETTINGS_ALARM_VOLUME_S)); } void LiveSettings::update_alarm_duration() { - alarm_duration.set(g_settings_get_int(m_settings, SETTINGS_ALARM_DURATION_S)); + alarm_duration.set(g_settings_get_uint(m_settings, SETTINGS_ALARM_DURATION_S)); } /*** diff --git a/src/snap.cpp b/src/snap.cpp index 40fd541..eab7001 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -54,8 +54,8 @@ public: Sound(const std::shared_ptr& clock, const std::string& filename, - int volume, - int duration_minutes, + unsigned int volume, + unsigned int duration_minutes, bool loop): m_clock(clock), m_filename(filename), @@ -132,9 +132,9 @@ private: g_clear_pointer(&props, ca_proplist_destroy); } - static float get_gain_level(int volume) + static float get_gain_level(unsigned int volume) { - const int clamped_volume = CLAMP(volume, 1, 100); + const unsigned int clamped_volume = CLAMP(volume, 1, 100); /* This range isn't set in stone -- arrived at from manual tests on Nextus 4 */ @@ -181,7 +181,7 @@ private: const std::shared_ptr m_clock; const std::string m_filename; - const int m_volume; + const unsigned int m_volume; const bool m_loop; const int32_t m_canberra_id; const DateTime m_loop_end_time; @@ -194,8 +194,8 @@ class SoundBuilder public: void set_clock(const std::shared_ptr& c) {m_clock = c;} void set_filename(const std::string& s) {m_filename = s;} - void set_volume(const int v) {m_volume = v;} - void set_duration_minutes(int i) {m_duration_minutes=i;} + void set_volume(const unsigned int v) {m_volume = v;} + void set_duration_minutes(int unsigned i) {m_duration_minutes=i;} void set_looping(bool b) {m_looping=b;} Sound* operator()() { @@ -209,8 +209,8 @@ public: private: std::shared_ptr m_clock; std::string m_filename; - int m_volume = 50; - int m_duration_minutes = 30; + unsigned int m_volume = 50; + unsigned int m_duration_minutes = 30; bool m_looping = true; }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 26b326d..958e1cc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,8 +21,8 @@ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compil OUTPUT_VARIABLE COMPILE_SCHEMA_EXECUTABLE OUTPUT_STRIP_TRAILING_WHITESPACE) add_custom_command (OUTPUT gschemas.compiled - DEPENDS ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.datetime.gschema.xml - COMMAND cp -f ${CMAKE_SOURCE_DIR}/data/*gschema.xml ${SCHEMA_DIR} + DEPENDS ${CMAKE_BINARY_DIR}/data/com.canonical.indicator.datetime.gschema.xml + COMMAND cp -f ${CMAKE_BINARY_DIR}/data/*gschema.xml ${SCHEMA_DIR} COMMAND ${COMPILE_SCHEMA_EXECUTABLE} ${SCHEMA_DIR}) # look for headers in our src dir, and also in the directories where we autogenerate files... diff --git a/tests/test-settings.cpp b/tests/test-settings.cpp index e4aeef7..44a0252 100644 --- a/tests/test-settings.cpp +++ b/tests/test-settings.cpp @@ -101,26 +101,26 @@ protected: g_clear_pointer(&tmp, g_free); } - void TestIntProperty(core::Property& property, const gchar* key) + void TestUIntProperty(core::Property& property, const gchar* key) { - EXPECT_EQ(g_settings_get_int(m_gsettings, key), property.get()); + EXPECT_EQ(g_settings_get_uint(m_gsettings, key), property.get()); - int expected_values[] = { 1, 2, 3 }; + unsigned int expected_values[] = { 1, 2, 3 }; // modify GSettings and confirm that the new value is propagated - for(const int& expected_value : expected_values) + for(const auto& expected_value : expected_values) { - g_settings_set_int(m_gsettings, key, expected_value); + g_settings_set_uint(m_gsettings, key, expected_value); EXPECT_EQ(expected_value, property.get()); - EXPECT_EQ(expected_value, g_settings_get_int(m_gsettings, key)); + EXPECT_EQ(expected_value, g_settings_get_uint(m_gsettings, key)); } // modify the property and confirm that the new value is propagated - for(const int& expected_value : expected_values) + for(const auto& expected_value : expected_values) { property.set(expected_value); EXPECT_EQ(expected_value, property.get()); - EXPECT_EQ(expected_value, g_settings_get_int(m_gsettings, key)); + EXPECT_EQ(expected_value, g_settings_get_uint(m_gsettings, key)); } } }; @@ -148,10 +148,10 @@ TEST_F(SettingsFixture, BoolProperties) TestBoolProperty(m_settings->show_year, SETTINGS_SHOW_YEAR_S); } -TEST_F(SettingsFixture, IntProperties) +TEST_F(SettingsFixture, UIntProperties) { - TestIntProperty(m_settings->alarm_duration, SETTINGS_ALARM_DURATION_S); - TestIntProperty(m_settings->alarm_volume, SETTINGS_ALARM_VOLUME_S); + TestUIntProperty(m_settings->alarm_duration, SETTINGS_ALARM_DURATION_S); + TestUIntProperty(m_settings->alarm_volume, SETTINGS_ALARM_VOLUME_S); } TEST_F(SettingsFixture, StringProperties) -- cgit v1.2.3 From 194e79302027047ae36146f6ec4e7c0e9c1d2fc2 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 30 Jun 2014 09:54:34 -0500 Subject: Format the manual tests properly. Update the submitter/reviewer checklist. --- MERGE-REVIEW | 53 ++++++++++++++++++++++------------------------------- tests/manual | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/MERGE-REVIEW b/MERGE-REVIEW index 1a5815c..88f25f6 100644 --- a/MERGE-REVIEW +++ b/MERGE-REVIEW @@ -1,44 +1,35 @@ +* '''Checklist for component''': indicator-datetime + * '''Component Test Plan''': https://wiki.ubuntu.com/Process/Merges/TestPlan/indicator-datetime + * '''Trunk URL''': lp:indicator-datetime + * '''Ubuntu Package URL (LP)''': http://launchpad.net/ubuntu/+source/indicator-datetime This documents the expections that the project has on what both submitters and reviewers should ensure that they've done for a merge into the project. -== Submitter Responsibilities == +== MP Submission Checklist Template == - * Ensure the project compiles and the test suite executes without error - * Ensure that non-obvious code has comments explaining it - * If the change affects specific features, please reference the appropriate - tags in the merge description so reviewers can test appropriately: - [phone profile], [desktop profile], [alarms] +'''Note: Please ensure you include the following form filled out and submitted along side your code to the MP ticket.''' -== Reviewer Responsibilities == + * Are there any related MPs required for this MP to build/function as expected? Please list. + * Is your branch in sync with latest trunk? (e.g. bzr pull lp:trunk -> no changes) + * Did the code build without warnings? + * Did the tests run successfully? + * Did you perform an exploratory manual test run of your code change and any related functionality? + * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP? + * Has your component test plan been executed successfully on emulator, N4? + * Please list which manual tests are germane for the reviewer in this MR. - * Did the Jenkins build compile? Pass? Run unit tests successfully? - * Are there appropriate tests to cover any new functionality? - * Do the tag-specific tests pass? +== MP Review Checklist Template == -== Phone Profile Tests == +'''Note: Please ensure you include the following form filled out and submitted along side your code to the MP ticket.''' - * Run tests indicator-datetime/unity8* + * Have you checked that the submitter has accurately filled out the submitter checklist and has taken no shortcuts? + * Did you run the manual tests listed by the submitter? + * Did you do exploratory testing related to the component you own with the MP changeset included? + * If new features have been added, are the manual tests sufficient to cover them? -== Desktop Profile Tests == +== MP Landing Checklist Template == - * Run tests indicator-datetime/unity7* + * Ensure that the checklists have been properly filled out by submitter and all reviewers -== Alarm Tests == - - * Hardware wakeups for new alarms: - 1. Create and save an upcoming alarm in ubuntu-clock-app. - 2. Unplug the phone from any USB connection and put it to sleep. - 3. Confirm that the alarm sounds on time even if the phone is asleep. - (Note: if in doubt about sleep you can see in the syslog whether the - device actually suspended or whether the suspend was aborted) - - * Hardware wakeups for edited alarms: - 1. Edit an alarm that's already passed. (see previous test) - 2. Unplug the phone from any USB connection and put it to sleep. - 3. Confirm that the alarm sounds on time even if the phone is asleep. - (Note: if in doubt about sleep you can see in the syslog whether the - device actually suspended or whether the suspend was aborted.) - - diff --git a/tests/manual b/tests/manual index 17b4778..ecbcebb 100644 --- a/tests/manual +++ b/tests/manual @@ -22,3 +22,25 @@ Test-case indicator-datetime/unity8-items-check
The menu is populated with items
+Test-case indicator-datetime/new-alarm-wakeup +
+
Create and save an upcoming alarm in ubuntu-clock-app
+
Unplug the phone from any USB connection and put it to sleep
+
Confirm that the alarm sounds on time even if the phone is asleep. + (Note: if in doubt about sleep you can see in the syslog whether the + device actually suspended or whether the suspend was aborted)
+
+ +Test-case indicator-datetime/edited-alarm-wakeup +
+
Edit an alarm that's already passed. (see previous test)
+
Unplug the phone from any USB connection and put it to sleep
+
Confirm that the alarm sounds on time even if the phone is asleep. + (Note: if in doubt about sleep you can see in the syslog whether the + device actually suspended or whether the suspend was aborted)
+
+ + + If all actions produce the expected results listed, please submit a 'passed' result. + If an action fails, or produces an unexpected result, please submit a 'failed' result and file a bug. Please be sure to include the bug number when you submit your result. + -- cgit v1.2.3