Merge lp:~charlesk/indicator-datetime/lp-1588526-remember-system-bus into lp:indicator-datetime

Proposed by Charles Kerr
Status: Merged
Approved by: Charles Kerr
Approved revision: 467
Merged at revision: 467
Proposed branch: lp:~charlesk/indicator-datetime/lp-1588526-remember-system-bus
Merge into: lp:indicator-datetime
Diff against target: 582 lines (+201/-180)
11 files modified
include/datetime/snap.h (+4/-1)
include/notifications/awake.h (+3/-1)
src/awake.cpp (+23/-54)
src/main.cpp (+1/-1)
src/snap.cpp (+20/-13)
tests/CMakeLists.txt (+1/-0)
tests/libdbusmock-fixture.h (+1/-8)
tests/manual-test-snap.cpp (+3/-1)
tests/notification-fixture.h (+1/-1)
tests/test-notification-response.cpp (+144/-0)
tests/test-notification.cpp (+0/-100)
To merge this branch: bzr merge lp:~charlesk/indicator-datetime/lp-1588526-remember-system-bus
Reviewer Review Type Date Requested Status
unity-api-1-bot continuous-integration Approve
dobey (community) Approve
Review via email: mp+307871@code.launchpad.net

Commit message

Remember the system bus instead of fetching it asynchronously

Description of the change

In the Awake class, take the system_bus as a constructor argument instead of fetching it asynchronously.

The goal of this branch is to reduce the time between when indicator-datetime receives a Wakeup signal and when it calls repowerd to keep the phone awake while showing an alarm. This may ameliorate https://launchpad.net/bugs/1588526 if the problem is the phone going back to sleep too soon after a wakeup.

NB: this branch is not a silver bullet, it only makes datetime behave better. It's also worth looking at repowerd wrt ensuring the phone stays awake long enough for clients to respond to Wakeups.

To post a comment you must log in.
Revision history for this message
dobey (dobey) wrote :

Looks ok to me.

review: Approve
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :
review: Needs Fixing (continuous-integration)
466. By Charles Kerr

break test-notification into two separate test units

467. By Charles Kerr

remove unnecessary test in Awake::Impl::~Impl()

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:467
https://jenkins.canonical.com/unity-api-1/job/lp-indicator-datetime-ci/7/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1006
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1013
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/810/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/810
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/810/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-indicator-datetime-ci/7/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/datetime/snap.h'
2--- include/datetime/snap.h 2016-05-14 17:18:45 +0000
3+++ include/datetime/snap.h 2016-11-04 16:02:06 +0000
4@@ -26,6 +26,8 @@
5 #include <notifications/notifications.h>
6 #include <notifications/sound.h>
7
8+#include <gio/gio.h> // GDBusConnection
9+
10 #include <functional>
11 #include <memory>
12
13@@ -41,7 +43,8 @@
14 public:
15 Snap(const std::shared_ptr<unity::indicator::notifications::Engine>& engine,
16 const std::shared_ptr<unity::indicator::notifications::SoundBuilder>& sound_builder,
17- const std::shared_ptr<const Settings>& settings);
18+ const std::shared_ptr<const Settings>& settings,
19+ GDBusConnection* system_bus);
20 virtual ~Snap();
21
22 enum class Response { None, Snooze, ShowApp };
23
24=== modified file 'include/notifications/awake.h'
25--- include/notifications/awake.h 2015-03-31 18:54:26 +0000
26+++ include/notifications/awake.h 2016-11-04 16:02:06 +0000
27@@ -22,6 +22,8 @@
28
29 #include <memory>
30
31+#include <gio/gio.h>
32+
33 namespace unity {
34 namespace indicator {
35 namespace notifications {
36@@ -36,7 +38,7 @@
37 class Awake
38 {
39 public:
40- explicit Awake(const std::string& app_name);
41+ explicit Awake(GDBusConnection* system_bus, const std::string& app_name);
42 ~Awake();
43
44 private:
45
46=== modified file 'src/awake.cpp'
47--- src/awake.cpp 2016-07-05 19:42:21 +0000
48+++ src/awake.cpp 2016-11-04 16:02:06 +0000
49@@ -36,68 +36,38 @@
50 {
51 public:
52
53- Impl(const std::string& app_name):
54+ Impl(GDBusConnection* bus, const std::string& app_name):
55 m_app_name(app_name),
56- m_cancellable(g_cancellable_new())
57+ m_cancellable(g_cancellable_new()),
58+ m_system_bus{G_DBUS_CONNECTION(g_object_ref(bus))}
59 {
60- g_bus_get(G_BUS_TYPE_SYSTEM, m_cancellable, on_system_bus_ready, this);
61+ // ask repowerd to keep the system awake
62+ static constexpr int32_t POWERD_SYS_STATE_ACTIVE = 1;
63+ g_dbus_connection_call (m_system_bus,
64+ BUS_POWERD_NAME,
65+ BUS_POWERD_PATH,
66+ BUS_POWERD_INTERFACE,
67+ "requestSysState",
68+ g_variant_new("(si)", m_app_name.c_str(), POWERD_SYS_STATE_ACTIVE),
69+ G_VARIANT_TYPE("(s)"),
70+ G_DBUS_CALL_FLAGS_NONE,
71+ -1,
72+ m_cancellable,
73+ on_force_awake_response,
74+ this);
75+
76 }
77
78 ~Impl()
79 {
80 g_cancellable_cancel (m_cancellable);
81 g_object_unref (m_cancellable);
82-
83- if (m_system_bus != nullptr)
84- {
85- unforce_awake ();
86- g_object_unref (m_system_bus);
87- }
88+ unforce_awake ();
89+ g_clear_object (&m_system_bus);
90 }
91
92 private:
93
94- static void on_system_bus_ready (GObject *,
95- GAsyncResult *res,
96- gpointer gself)
97- {
98- GError * error;
99- GDBusConnection * system_bus;
100-
101- error = nullptr;
102- system_bus = g_bus_get_finish (res, &error);
103- if (error != nullptr)
104- {
105- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
106- g_warning ("Unable to get bus: %s", error->message);
107-
108- g_error_free (error);
109- }
110- else if (system_bus != nullptr)
111- {
112- auto self = static_cast<Impl*>(gself);
113-
114- self->m_system_bus = G_DBUS_CONNECTION (g_object_ref (system_bus));
115-
116- // ask powerd to keep the system awake
117- static constexpr int32_t POWERD_SYS_STATE_ACTIVE = 1;
118- g_dbus_connection_call (system_bus,
119- BUS_POWERD_NAME,
120- BUS_POWERD_PATH,
121- BUS_POWERD_INTERFACE,
122- "requestSysState",
123- g_variant_new("(si)", self->m_app_name.c_str(), POWERD_SYS_STATE_ACTIVE),
124- G_VARIANT_TYPE("(s)"),
125- G_DBUS_CALL_FLAGS_NONE,
126- -1,
127- self->m_cancellable,
128- on_force_awake_response,
129- self);
130-
131- g_object_unref (system_bus);
132- }
133- }
134-
135 static void on_force_awake_response (GObject * connection,
136 GAsyncResult * res,
137 gpointer gself)
138@@ -125,7 +95,6 @@
139
140 g_clear_pointer (&self->m_awake_cookie, g_free);
141 g_variant_get (args, "(s)", &self->m_awake_cookie);
142- g_debug ("m_awake_cookie is now '%s'", self->m_awake_cookie);
143
144 g_variant_unref (args);
145 }
146@@ -146,7 +115,7 @@
147 nullptr,
148 G_DBUS_CALL_FLAGS_NONE,
149 -1,
150- nullptr,
151+ m_cancellable,
152 nullptr,
153 nullptr);
154
155@@ -164,8 +133,8 @@
156 ****
157 ***/
158
159-Awake::Awake(const std::string& app_name):
160- impl(new Impl(app_name))
161+Awake::Awake(GDBusConnection* system_bus, const std::string& app_name):
162+ impl{new Impl{system_bus, app_name}}
163 {
164 }
165
166
167=== modified file 'src/main.cpp'
168--- src/main.cpp 2016-05-14 17:18:45 +0000
169+++ src/main.cpp 2016-11-04 16:02:06 +0000
170@@ -147,7 +147,7 @@
171 auto snooze_planner = std::make_shared<SnoozePlanner>(state->settings, state->clock);
172 auto notification_engine = std::make_shared<uin::Engine>("indicator-datetime-service");
173 auto sound_builder = std::make_shared<uin::DefaultSoundBuilder>();
174- std::unique_ptr<Snap> snap (new Snap(notification_engine, sound_builder, state->settings));
175+ std::unique_ptr<Snap> snap (new Snap(notification_engine, sound_builder, state->settings, system_bus));
176 auto alarm_queue = create_simple_alarm_queue(state->clock, snooze_planner, engine, timezone_);
177 auto on_response = [snooze_planner, actions](const Appointment& appointment, const Alarm& alarm, const Snap::Response& response) {
178 switch(response) {
179
180=== modified file 'src/snap.cpp'
181--- src/snap.cpp 2016-07-04 23:44:47 +0000
182+++ src/snap.cpp 2016-11-04 16:02:06 +0000
183@@ -53,20 +53,24 @@
184
185 Impl(const std::shared_ptr<unity::indicator::notifications::Engine>& engine,
186 const std::shared_ptr<unity::indicator::notifications::SoundBuilder>& sound_builder,
187- const std::shared_ptr<const Settings>& settings):
188+ const std::shared_ptr<const Settings>& settings,
189+ GDBusConnection* system_bus):
190 m_engine(engine),
191 m_sound_builder(sound_builder),
192 m_settings(settings),
193- m_cancellable(g_cancellable_new())
194+ m_cancellable(g_cancellable_new()),
195+ m_system_bus{G_DBUS_CONNECTION(g_object_ref(system_bus))}
196 {
197 auto object_path = g_strdup_printf("/org/freedesktop/Accounts/User%lu", (gulong)getuid());
198- accounts_service_sound_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
199- G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
200- "org.freedesktop.Accounts",
201- object_path,
202- m_cancellable,
203- on_sound_proxy_ready,
204- this);
205+
206+
207+ accounts_service_sound_proxy_new(m_system_bus,
208+ G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
209+ "org.freedesktop.Accounts",
210+ object_path,
211+ m_cancellable,
212+ on_sound_proxy_ready,
213+ this);
214 g_free(object_path);
215 }
216
217@@ -75,6 +79,7 @@
218 g_cancellable_cancel(m_cancellable);
219 g_clear_object(&m_cancellable);
220 g_clear_object(&m_accounts_service_sound_proxy);
221+ g_clear_object(&m_system_bus);
222
223 for (const auto& key : m_notifications)
224 m_engine->close (key);
225@@ -99,7 +104,7 @@
226 // force the system to stay awake
227 std::shared_ptr<uin::Awake> awake;
228 if (appointment.is_ubuntu_alarm() || calendar_bubbles_enabled() || calendar_list_enabled()) {
229- awake = std::make_shared<uin::Awake>(m_engine->app_name());
230+ awake = std::make_shared<uin::Awake>(m_system_bus, m_engine->app_name());
231 }
232
233 // calendar events are muted in silent mode; alarm clocks never are
234@@ -229,7 +234,7 @@
235 GError * error;
236
237 error = nullptr;
238- auto proxy = accounts_service_sound_proxy_new_for_bus_finish (res, &error);
239+ auto proxy = accounts_service_sound_proxy_new_finish (res, &error);
240 if (error != nullptr)
241 {
242 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
243@@ -296,6 +301,7 @@
244 std::set<int> m_notifications;
245 GCancellable * m_cancellable {nullptr};
246 AccountsServiceSound * m_accounts_service_sound_proxy {nullptr};
247+ GDBusConnection * m_system_bus {nullptr};
248
249 static constexpr char const * ACTION_NONE {"none"};
250 static constexpr char const * ACTION_SNOOZE {"snooze"};
251@@ -308,8 +314,9 @@
252
253 Snap::Snap(const std::shared_ptr<unity::indicator::notifications::Engine>& engine,
254 const std::shared_ptr<unity::indicator::notifications::SoundBuilder>& sound_builder,
255- const std::shared_ptr<const Settings>& settings):
256- impl(new Impl(engine, sound_builder, settings))
257+ const std::shared_ptr<const Settings>& settings,
258+ GDBusConnection* system_bus):
259+ impl(new Impl(engine, sound_builder, settings, system_bus))
260 {
261 }
262
263
264=== modified file 'tests/CMakeLists.txt'
265--- tests/CMakeLists.txt 2016-06-28 13:26:17 +0000
266+++ tests/CMakeLists.txt 2016-11-04 16:02:06 +0000
267@@ -49,6 +49,7 @@
268 add_test_by_name(test-datetime)
269 add_test_by_name(test-sound)
270 add_test_by_name(test-notification)
271+add_test_by_name(test-notification-response)
272 add_test_by_name(test-actions)
273 add_test_by_name(test-alarm-queue)
274 add_test(NAME dear-reader-the-next-test-takes-60-seconds COMMAND true)
275
276=== modified file 'tests/libdbusmock-fixture.h'
277--- tests/libdbusmock-fixture.h 2016-02-10 20:48:24 +0000
278+++ tests/libdbusmock-fixture.h 2016-11-04 16:02:06 +0000
279@@ -75,14 +75,7 @@
280
281 // wait a little while for the scaffolding to shut down,
282 // but don't block on it forever...
283- unsigned int cleartry = 0;
284- while (((system_bus != nullptr) || (session_bus != nullptr)) && (cleartry < 50))
285- {
286- g_usleep(100000);
287- while (g_main_pending())
288- g_main_iteration(true);
289- cleartry++;
290- }
291+ wait_for([this](){return system_bus==nullptr && session_bus==nullptr;}, 5000);
292
293 super::TearDown();
294 }
295
296=== modified file 'tests/manual-test-snap.cpp'
297--- tests/manual-test-snap.cpp 2016-05-14 17:20:00 +0000
298+++ tests/manual-test-snap.cpp 2016-11-04 16:02:06 +0000
299@@ -95,10 +95,12 @@
300
301 auto notification_engine = std::make_shared<uin::Engine>("indicator-datetime-service");
302 auto sound_builder = std::make_shared<uin::DefaultSoundBuilder>();
303- Snap snap (notification_engine, sound_builder, settings);
304+ auto system_bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr);
305+ Snap snap (notification_engine, sound_builder, settings, system_bus);
306 snap(a, a.alarms.front(), on_response);
307 g_main_loop_run(loop);
308
309 g_main_loop_unref(loop);
310+ g_clear_object(&system_bus);
311 return 0;
312 }
313
314=== modified file 'tests/notification-fixture.h'
315--- tests/notification-fixture.h 2016-05-14 02:07:10 +0000
316+++ tests/notification-fixture.h 2016-11-04 16:02:06 +0000
317@@ -334,7 +334,7 @@
318 const std::shared_ptr<unity::indicator::notifications::SoundBuilder>& sb,
319 const std::shared_ptr<unity::indicator::datetime::Settings>& settings)
320 {
321- auto snap = std::make_shared<unity::indicator::datetime::Snap>(ne, sb, settings);
322+ auto snap = std::make_shared<unity::indicator::datetime::Snap>(ne, sb, settings, system_bus);
323 wait_msec(100); // wait a moment for the Snap to finish its async dbus bootstrapping
324 return snap;
325 }
326
327=== added file 'tests/test-notification-response.cpp'
328--- tests/test-notification-response.cpp 1970-01-01 00:00:00 +0000
329+++ tests/test-notification-response.cpp 2016-11-04 16:02:06 +0000
330@@ -0,0 +1,144 @@
331+/*
332+ * Copyright 2014-2016 Canonical Ltd.
333+ *
334+ * This program is free software: you can redistribute it and/or modify it
335+ * under the terms of the GNU General Public License version 3, as published
336+ * by the Free Software Foundation.
337+ *
338+ * This program is distributed in the hope that it will be useful, but
339+ * WITHOUT ANY WARRANTY; without even the implied warranties of
340+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
341+ * PURPOSE. See the GNU General Public License for more details.
342+ *
343+ * You should have received a copy of the GNU General Public License along
344+ * with this program. If not, see <http://www.gnu.org/licenses/>.
345+ *
346+ * Authors:
347+ * Charles Kerr <charles.kerr@canonical.com>
348+ */
349+
350+#include <datetime/appointment.h>
351+#include <datetime/settings.h>
352+#include <datetime/snap.h>
353+
354+#include "notification-fixture.h"
355+
356+/***
357+****
358+***/
359+
360+using namespace unity::indicator::datetime;
361+
362+namespace
363+{
364+ static constexpr char const * APP_NAME {"indicator-datetime-service"};
365+
366+ gboolean quit_idle (gpointer gloop)
367+ {
368+ g_main_loop_quit(static_cast<GMainLoop*>(gloop));
369+ return G_SOURCE_REMOVE;
370+ }
371+}
372+
373+/***
374+****
375+***/
376+
377+TEST_F(NotificationFixture,Response)
378+{
379+ // create the world
380+ make_interactive();
381+ auto ne = std::make_shared<unity::indicator::notifications::Engine>(APP_NAME);
382+ auto sb = std::make_shared<unity::indicator::notifications::DefaultSoundBuilder>();
383+ auto settings = std::make_shared<Settings>();
384+ int next_notification_id {FIRST_NOTIFY_ID};
385+
386+ // set a response callback that remembers what response we got
387+ bool on_response_called {};
388+ Snap::Response response {};
389+ auto on_response = [this, &on_response_called, &response]
390+ (const Appointment&, const Alarm&, const Snap::Response& r){
391+ on_response_called = true;
392+ response = r;
393+ g_idle_add(quit_idle, loop);
394+ };
395+
396+ // our tests!
397+ const struct {
398+ Appointment appt;
399+ std::vector<std::string> expected_actions;
400+ std::string action;
401+ Snap::Response expected_response;
402+ } tests[] = {
403+ { appt, {"show-app"}, "show-app", Snap::Response::ShowApp },
404+ { ualarm, {"none", "snooze"}, "snooze", Snap::Response::Snooze },
405+ { ualarm, {"none", "snooze"}, "none", Snap::Response::None }
406+ };
407+
408+
409+ settings->cal_notification_enabled.set(true);
410+ settings->cal_notification_sounds.set(true);
411+ settings->cal_notification_vibrations.set(true);
412+ settings->cal_notification_bubbles.set(true);
413+ settings->cal_notification_list.set(true);
414+
415+ // walk through the tests
416+ for (const auto& test : tests)
417+ {
418+ // wait for previous iterations' bus noise to finish and reset the counters
419+ GError* error {};
420+ wait_msec(500);
421+ dbus_test_dbus_mock_object_clear_method_calls(notify_mock, notify_obj, &error);
422+ g_assert_no_error(error);
423+ on_response_called = false;
424+
425+ // create a snap decision
426+ auto snap = create_snap(ne, sb, settings);
427+ (*snap)(test.appt, test.appt.alarms.front(), on_response);
428+
429+ // wait for the notification to show up
430+ EXPECT_METHOD_CALLED_EVENTUALLY(notify_mock, notify_obj, METHOD_NOTIFY);
431+
432+ // test that Notify was called the right number of times
433+ static constexpr int expected_num_notify_calls {1};
434+ guint num_notify_calls {};
435+ const auto notify_calls = dbus_test_dbus_mock_object_get_method_calls(
436+ notify_mock,
437+ notify_obj,
438+ METHOD_NOTIFY,
439+ &num_notify_calls,
440+ &error);
441+ g_assert_no_error(error);
442+ EXPECT_EQ(expected_num_notify_calls, num_notify_calls);
443+
444+ // test that Notify was called with the correct list of actions
445+ if (num_notify_calls > 0) {
446+ std::vector<std::string> actions;
447+ const gchar** as {nullptr};
448+ g_variant_get_child(notify_calls[0].params, 5, "^a&s", &as);
449+ for (int i=0; as && as[i]; i+=2) // actions are in pairs of (name, i18n), skip the i18n
450+ actions.push_back(as[i]);
451+ EXPECT_EQ(test.expected_actions, actions);
452+ }
453+
454+ // make the notification mock tell the world that the user invoked an action
455+ const auto notification_id = next_notification_id++;
456+ idle_add([this, notification_id, test](){
457+ GError* err {};
458+ dbus_test_dbus_mock_object_emit_signal(notify_mock, notify_obj, "ActionInvoked",
459+ G_VARIANT_TYPE("(us)"),
460+ g_variant_new("(us)", guint(notification_id), test.action.c_str()),
461+ &err);
462+ dbus_test_dbus_mock_object_emit_signal(notify_mock, notify_obj, "NotificationClosed",
463+ G_VARIANT_TYPE("(uu)"),
464+ g_variant_new("(uu)", guint(notification_id), guint(NOTIFICATION_CLOSED_DISMISSED)),
465+ &err);
466+ g_assert_no_error(err);
467+ return G_SOURCE_REMOVE;
468+ });
469+
470+ // confirm that the response callback got the right response
471+ EXPECT_TRUE(wait_for([&on_response_called](){return on_response_called;}));
472+ EXPECT_EQ(int(test.expected_response), int(response)) << "notification_id " << notification_id;
473+ }
474+}
475
476=== modified file 'tests/test-notification.cpp'
477--- tests/test-notification.cpp 2016-06-24 12:26:06 +0000
478+++ tests/test-notification.cpp 2016-11-04 16:02:06 +0000
479@@ -196,103 +196,3 @@
480 }
481 }
482 }
483-
484-
485-TEST_F(NotificationFixture,Response)
486-{
487- // create the world
488- make_interactive();
489- auto ne = std::make_shared<unity::indicator::notifications::Engine>(APP_NAME);
490- auto sb = std::make_shared<unity::indicator::notifications::DefaultSoundBuilder>();
491- auto settings = std::make_shared<Settings>();
492- int next_notification_id {FIRST_NOTIFY_ID};
493-
494- // set a response callback that remembers what response we got
495- bool on_response_called {};
496- Snap::Response response {};
497- auto on_response = [this, &on_response_called, &response]
498- (const Appointment&, const Alarm&, const Snap::Response& r){
499- on_response_called = true;
500- response = r;
501- g_idle_add(quit_idle, loop);
502- };
503-
504- // our tests!
505- const struct {
506- Appointment appt;
507- std::vector<std::string> expected_actions;
508- std::string action;
509- Snap::Response expected_response;
510- } tests[] = {
511- { appt, {"show-app"}, "show-app", Snap::Response::ShowApp },
512- { ualarm, {"none", "snooze"}, "snooze", Snap::Response::Snooze },
513- { ualarm, {"none", "snooze"}, "none", Snap::Response::None }
514- };
515-
516-
517- settings->cal_notification_enabled.set(true);
518- settings->cal_notification_sounds.set(true);
519- settings->cal_notification_vibrations.set(true);
520- settings->cal_notification_bubbles.set(true);
521- settings->cal_notification_list.set(true);
522-
523- // walk through the tests
524- for (const auto& test : tests)
525- {
526- // wait for previous iterations' bus noise to finish and reset the counters
527- GError* error {};
528- wait_msec(500);
529- dbus_test_dbus_mock_object_clear_method_calls(notify_mock, notify_obj, &error);
530- g_assert_no_error(error);
531- on_response_called = false;
532-
533- // create a snap decision
534- auto snap = create_snap(ne, sb, settings);
535- (*snap)(test.appt, test.appt.alarms.front(), on_response);
536-
537- // wait for the notification to show up
538- EXPECT_METHOD_CALLED_EVENTUALLY(notify_mock, notify_obj, METHOD_NOTIFY);
539-
540- // test that Notify was called the right number of times
541- static constexpr int expected_num_notify_calls {1};
542- guint num_notify_calls {};
543- const auto notify_calls = dbus_test_dbus_mock_object_get_method_calls(
544- notify_mock,
545- notify_obj,
546- METHOD_NOTIFY,
547- &num_notify_calls,
548- &error);
549- g_assert_no_error(error);
550- EXPECT_EQ(expected_num_notify_calls, num_notify_calls);
551-
552- // test that Notify was called with the correct list of actions
553- if (num_notify_calls > 0) {
554- std::vector<std::string> actions;
555- const gchar** as {nullptr};
556- g_variant_get_child(notify_calls[0].params, 5, "^a&s", &as);
557- for (int i=0; as && as[i]; i+=2) // actions are in pairs of (name, i18n), skip the i18n
558- actions.push_back(as[i]);
559- EXPECT_EQ(test.expected_actions, actions);
560- }
561-
562- // make the notification mock tell the world that the user invoked an action
563- const auto notification_id = next_notification_id++;
564- idle_add([this, notification_id, test](){
565- GError* err {};
566- dbus_test_dbus_mock_object_emit_signal(notify_mock, notify_obj, "ActionInvoked",
567- G_VARIANT_TYPE("(us)"),
568- g_variant_new("(us)", guint(notification_id), test.action.c_str()),
569- &err);
570- dbus_test_dbus_mock_object_emit_signal(notify_mock, notify_obj, "NotificationClosed",
571- G_VARIANT_TYPE("(uu)"),
572- g_variant_new("(uu)", guint(notification_id), guint(NOTIFICATION_CLOSED_DISMISSED)),
573- &err);
574- g_assert_no_error(err);
575- return G_SOURCE_REMOVE;
576- });
577-
578- // confirm that the response callback got the right response
579- EXPECT_TRUE(wait_for([&on_response_called](){return on_response_called;}));
580- EXPECT_EQ(int(test.expected_response), int(response)) << "notification_id " << notification_id;
581- }
582-}

Subscribers

People subscribed via source and target branches