Merge lp:~charlesk/indicator-datetime/lp-1588526-remember-system-bus into lp:indicator-datetime
- lp-1588526-remember-system-bus
- Merge into trunk.16.10
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 | ||||
Related bugs: |
|
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:/
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.
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:465
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 466. By Charles Kerr
-
break test-notification into two separate test units
- 467. By Charles Kerr
-
remove unnecessary test in Awake::
Impl::~ Impl()
unity-api-1-bot (unity-api-1-bot) wrote : | # |
PASSED: Continuous integration, rev:467
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
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 | -} |
Looks ok to me.