diff options
-rw-r--r-- | src/haptic.cpp | 57 | ||||
-rw-r--r-- | tests/test-snap.cpp | 8 |
2 files changed, 47 insertions, 18 deletions
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 <gio/gio.h> +#include <vector> + 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<uint32_t>({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<Impl*>(gself)->vibrate_now(); - return G_SOURCE_CONTINUE; - } - - void vibrate_now() - { - g_dbus_connection_call (m_bus, + auto self = static_cast<Impl*>(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<uint32_t> m_vibrate_pattern_msec; guint m_tag = 0; }; diff --git a/tests/test-snap.cpp b/tests/test-snap.cpp index 018d6f9..06e0a80 100644 --- a/tests/test-snap.cpp +++ b/tests/test-snap.cpp @@ -56,7 +56,7 @@ private: protected: - static constexpr char const * HAPTIC_METHOD_VIBRATE {"Vibrate"}; + static constexpr char const * HAPTIC_METHOD_VIBRATE_PATTERN {"VibratePattern"}; static constexpr int SCREEN_COOKIE {8675309}; static constexpr char const * SCREEN_METHOD_KEEP_DISPLAY_ON {"keepDisplayOn"}; @@ -253,8 +253,8 @@ protected: dbus_test_dbus_mock_object_add_method(haptic_mock, haptic_obj, - HAPTIC_METHOD_VIBRATE, - G_VARIANT_TYPE("(u)"), + HAPTIC_METHOD_VIBRATE_PATTERN, + G_VARIANT_TYPE("(auu)"), nullptr, "", &error); @@ -419,7 +419,7 @@ TEST_F(SnapFixture, InhibitSleep) // confirm that haptic feedback got called EXPECT_TRUE (dbus_test_dbus_mock_object_check_method_call (haptic_mock, haptic_obj, - HAPTIC_METHOD_VIBRATE, + HAPTIC_METHOD_VIBRATE_PATTERN, nullptr, &error)); |