diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2014-07-01 09:36:57 +0000 |
---|---|---|
committer | CI bot <ps-jenkins@lists.canonical.com> | 2014-07-01 09:36:57 +0000 |
commit | 6ad9b8d2449c745953a1692b27e8d2b993a722d6 (patch) | |
tree | d0ce34b82460f52322d3bc9215fc7d989e642731 /src | |
parent | 6880613bbc6535242e95e7f5c65d9a9140eaa28b (diff) | |
parent | 194e79302027047ae36146f6ec4e7c0e9c1d2fc2 (diff) | |
download | ayatana-indicator-datetime-6ad9b8d2449c745953a1692b27e8d2b993a722d6.tar.gz ayatana-indicator-datetime-6ad9b8d2449c745953a1692b27e8d2b993a722d6.tar.bz2 ayatana-indicator-datetime-6ad9b8d2449c745953a1692b27e8d2b993a722d6.zip |
Expose the new alarm settings as DBus properties. Fixes: 1318997
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 31 | ||||
-rw-r--r-- | src/engine-eds.cpp | 6 | ||||
-rw-r--r-- | src/exporter.cpp | 249 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/settings-live.cpp | 12 | ||||
-rw-r--r-- | src/snap.cpp | 37 |
6 files changed, 234 insertions, 105 deletions
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/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<ESource*> m_sources; std::map<ESource*,ECalClient*> m_clients; @@ -508,7 +506,7 @@ private: ***/ EdsEngine::EdsEngine(): - p(new Impl(*this)) + p(new Impl()) { } diff --git a/src/exporter.cpp b/src/exporter.cpp index ccd6e5c..e2b60f2 100644 --- a/src/exporter.cpp +++ b/src/exporter.cpp @@ -20,6 +20,8 @@ #include <datetime/dbus-shared.h> #include <datetime/exporter.h> +#include "dbus-alarm-properties.h" + #include <glib/gi18n.h> #include <gio/gio.h> @@ -31,108 +33,223 @@ namespace datetime { **** ***/ -Exporter::~Exporter() +class Exporter::Impl { - if (m_dbus_connection != nullptr) +public: + + Impl(const std::shared_ptr<Settings>& settings): + m_settings(settings), + m_alarm_props(datetime_alarm_properties_skeleton_new()) + { + alarm_properties_init(); + } + + ~Impl() { - for(auto& id : m_exported_menu_ids) - g_dbus_connection_unexport_menu_model(m_dbus_connection, id); + if (m_bus != nullptr) + { + for(auto& id : m_exported_menu_ids) + g_dbus_connection_unexport_menu_model(m_bus, id); - if (m_exported_actions_id) - g_dbus_connection_unexport_action_group(m_dbus_connection, m_exported_actions_id); + if (m_exported_actions_id) + 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); + + g_clear_object(&m_bus); } - if (m_own_id) - g_bus_unown_name(m_own_id); + core::Signal<> name_lost; - g_clear_object(&m_dbus_connection); -} + void publish(const std::shared_ptr<Actions>& actions, + const std::vector<std::shared_ptr<Menu>>& 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); + } -/*** -**** -***/ +private: -void -Exporter::on_bus_acquired(GDBusConnection* connection, const gchar* name, gpointer gthis) -{ - g_debug("bus acquired: %s", name); - static_cast<Exporter*>(gthis)->on_bus_acquired(connection, name); -} + /*** + **** + ***/ -void -Exporter::on_bus_acquired(GDBusConnection* connection, const gchar* /*name*/) -{ - m_dbus_connection = static_cast<GDBusConnection*>(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) + 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<core::Property<std::string>*>(p)->set(val); + g_free(val); + } + void bind_string_property(gpointer o, const char* propname, + core::Property<std::string>& 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& val){ + g_object_set(o, propname, val.c_str(), nullptr); + }); + } + + + static void + on_gobject_notify_uint(GObject* o, GParamSpec* pspec, gpointer p) + { + uint val = 0; + g_object_get (o, pspec->name, &val, nullptr); + static_cast<core::Property<unsigned int>*>(p)->set(val); + } + void bind_uint_property(gpointer o, + const char* propname, + core::Property<unsigned int>& p) { - m_exported_actions_id = id; + // 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_uint), &p); + + // when the Settings changes, update the GObject + p.changed().connect([o, propname](unsigned int val){ + g_object_set(o, propname, val, nullptr); + }); } - else + + + void alarm_properties_init() { - g_warning("cannot export action group: %s", error->message); - g_clear_error(&error); + 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); } - // export the menus - for(auto& menu : m_menus) + /*** + **** + ***/ + + static void on_bus_acquired(GDBusConnection* connection, + const gchar* name, + gpointer gthis) { - 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); + g_debug("bus acquired: %s", name); + static_cast<Impl*>(gthis)->on_bus_acquired(connection, name); + } + + void on_bus_acquired(GDBusConnection* bus, const gchar* /*name*/) + { + m_bus = static_cast<GDBusConnection*>(g_object_ref(G_OBJECT(bus))); + + // 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(), + &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<Impl*>(gthis)->name_lost(); + } + + /*** + **** + ***/ + + std::shared_ptr<Settings> m_settings; + std::set<guint> m_exported_menu_ids; + guint m_own_id = 0; + guint m_exported_actions_id = 0; + GDBusConnection* m_bus = nullptr; + std::shared_ptr<Actions> m_actions; + std::vector<std::shared_ptr<Menu>> m_menus; + DatetimeAlarmProperties* m_alarm_props = nullptr; +}; + /*** **** ***/ -void -Exporter::on_name_lost(GDBusConnection* connection, const gchar* name, gpointer gthis) +Exporter::Exporter(const std::shared_ptr<Settings>& settings): + p(new Impl(settings)) { - g_debug("name lost: %s", name); - static_cast<Exporter*>(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>& actions, - const std::vector<std::shared_ptr<Menu>>& menus) +void Exporter::publish(const std::shared_ptr<Actions>& actions, + const std::vector<std::shared_ptr<Menu>>& 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..cc81cd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -163,8 +163,8 @@ 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 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/src/settings-live.cpp b/src/settings-live.cpp index e34ace1..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](AlarmVolume value){ - g_settings_set_enum(m_settings, SETTINGS_ALARM_VOLUME_S, gint(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((AlarmVolume)g_settings_get_enum(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 25632e9..eab7001 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -54,13 +54,12 @@ public: Sound(const std::shared_ptr<Clock>& clock, const std::string& filename, - AlarmVolume volume, - int duration_minutes, + unsigned int volume, + unsigned int duration_minutes, bool loop): 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)) @@ -133,18 +132,17 @@ private: g_clear_pointer(&props, ca_proplist_destroy); } - static float get_gain_level(const AlarmVolume volume) + static float get_gain_level(unsigned 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 unsigned 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) @@ -183,8 +181,7 @@ private: const std::shared_ptr<Clock> m_clock; const std::string m_filename; - const AlarmVolume m_volume; - const int m_duration_minutes; + const unsigned int m_volume; const bool m_loop; const int32_t m_canberra_id; const DateTime m_loop_end_time; @@ -197,8 +194,8 @@ class SoundBuilder public: void set_clock(const std::shared_ptr<Clock>& 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_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()() { @@ -212,8 +209,8 @@ public: private: std::shared_ptr<Clock> m_clock; std::string m_filename; - AlarmVolume m_volume = ALARM_VOLUME_NORMAL; - int m_duration_minutes = 30; + unsigned int m_volume = 50; + unsigned int m_duration_minutes = 30; bool m_looping = true; }; |