From 43e0fb826aa3a5acfd8937438989231804b4c400 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 31 Jul 2014 16:25:26 -0500 Subject: in haptic.cpp, better support for vibration patterns --- src/haptic.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'src/haptic.cpp') diff --git a/src/haptic.cpp b/src/haptic.cpp index 2b1ee21..a27c334 100644 --- a/src/haptic.cpp +++ b/src/haptic.cpp @@ -22,6 +22,8 @@ #include +#include + namespace unity { namespace indicator { namespace notifications { @@ -81,38 +83,65 @@ private: void start_vibrating() { - /* We only support one vibrate mode for now: an on/off pulse at - one-second intervals. So set a looping 2-second timer that asks - the phone to vibrate for one second. */ - m_tag = g_timeout_add_seconds (2, on_timeout, this); + g_return_if_fail (m_tag == 0); + + switch (m_mode) + { + case MODE_PULSE: // the only mode currently supported... :) + // one second on, one second off. + m_vibrate_pattern_msec = std::vector({1000, 1000}); + break; + } + + // Set up a loop so that the pattern keeps repeating. + // NB: VibratePattern takes a repeat arg, but we avoid it because + // there's no way to cancel a pattern once it's started... + // The phone would keep vibrating long after the alarm was dismissed! + // So we stick to a short pattern and handle the repeat loop manually. + guint interval_msec = 0; + for (const auto& msec : m_vibrate_pattern_msec) + interval_msec += msec; + m_tag = g_timeout_add (interval_msec, on_timeout, this); on_timeout (this); } static gboolean on_timeout (gpointer gself) { - static_cast(gself)->vibrate_now(); - return G_SOURCE_CONTINUE; - } - - void vibrate_now() - { - g_dbus_connection_call (m_bus, + auto self = static_cast(gself); + + // build the pattern array of uint32s + GVariantBuilder builder; + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + for (const auto& msec : self->m_vibrate_pattern_msec) + g_variant_builder_add_value (&builder, g_variant_new_uint32(msec)); + auto pattern_array = g_variant_builder_end (&builder); + + // build the argument list + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&builder, pattern_array); + g_variant_builder_add_value (&builder, g_variant_new_uint32(1u)); + auto args = g_variant_builder_end (&builder); + + g_dbus_connection_call (self->m_bus, BUS_HAPTIC_NAME, BUS_HAPTIC_PATH, BUS_HAPTIC_INTERFACE, - "Vibrate", - g_variant_new("(u)", 1000u), + "VibratePattern", + args, nullptr, G_DBUS_CALL_FLAGS_NONE, -1, - m_cancellable, + self->m_cancellable, nullptr, nullptr); + + return G_SOURCE_CONTINUE; } const Mode m_mode; GCancellable * m_cancellable = nullptr; GDBusConnection * m_bus = nullptr; + std::vector m_vibrate_pattern_msec; guint m_tag = 0; }; -- cgit v1.2.3