Merge lp:~afrantzis/unity-system-compositor/proximity into lp:unity-system-compositor

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: 231
Merged at revision: 237
Proposed branch: lp:~afrantzis/unity-system-compositor/proximity
Merge into: lp:unity-system-compositor
Prerequisite: lp:~afrantzis/unity-system-compositor/notification-timeouts
Diff against target: 724 lines (+413/-35)
7 files modified
src/mir_screen.cpp (+71/-23)
src/mir_screen.h (+4/-1)
src/powerd_mediator.cpp (+26/-0)
src/powerd_mediator.h (+5/-0)
src/screen_hardware.h (+2/-0)
tests/integration-tests/test_powerd_mediator.cpp (+81/-0)
tests/unit-tests/test_mir_screen.cpp (+224/-11)
To merge this branch: bzr merge lp:~afrantzis/unity-system-compositor/proximity
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+265120@code.launchpad.net

Commit message

Enable and handle proximity events properly

Description of the change

Enable and handle proximity events properly

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

240 +void usc::PowerdMediator::enable_proximity_l
I think this would be a bit more understandable if a force_proximity_l() function was split out, but other than that lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/mir_screen.cpp'
--- src/mir_screen.cpp 2015-07-17 12:45:10 +0000
+++ src/mir_screen.cpp 2015-07-17 12:45:10 +0000
@@ -55,7 +55,8 @@
55 notification_timeouts(notification_timeouts),55 notification_timeouts(notification_timeouts),
56 current_power_mode{MirPowerMode::mir_power_mode_on},56 current_power_mode{MirPowerMode::mir_power_mode_on},
57 restart_timers{true},57 restart_timers{true},
58 power_state_change_handler{[](MirPowerMode,PowerStateChangeReason){}}58 power_state_change_handler{[](MirPowerMode,PowerStateChangeReason){}},
59 allow_proximity_to_turn_on_screen{false}
59{60{
60 /*61 /*
61 * Make sure the compositor is running as certain conditions can62 * Make sure the compositor is running as certain conditions can
@@ -73,7 +74,10 @@
73 std::lock_guard<std::mutex> lock{guard};74 std::lock_guard<std::mutex> lock{guard};
74 reset_timers_l(PowerStateChangeReason::inactivity);75 reset_timers_l(PowerStateChangeReason::inactivity);
75 if (current_power_mode == MirPowerMode::mir_power_mode_on)76 if (current_power_mode == MirPowerMode::mir_power_mode_on)
77 {
76 screen_hardware->set_normal_backlight();78 screen_hardware->set_normal_backlight();
79 screen_hardware->enable_proximity(false);
80 }
77}81}
7882
79void usc::MirScreen::enable_inactivity_timers(bool enable)83void usc::MirScreen::enable_inactivity_timers(bool enable)
@@ -129,12 +133,25 @@
129 if (raw_dimmer_timeout >= 0)133 if (raw_dimmer_timeout >= 0)
130 inactivity_timeouts.dimming_timeout = std::chrono::duration_cast<std::chrono::milliseconds>(the_dimming_timeout);134 inactivity_timeouts.dimming_timeout = std::chrono::duration_cast<std::chrono::milliseconds>(the_dimming_timeout);
131135
132 cancel_timers_l();136 cancel_timers_l(PowerStateChangeReason::inactivity);
133 reset_timers_l(PowerStateChangeReason::inactivity);137 reset_timers_l(PowerStateChangeReason::inactivity);
134}138}
135139
136void usc::MirScreen::set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason)140void usc::MirScreen::set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason)
137{141{
142 if (!is_screen_change_allowed(mode, reason))
143 return;
144
145 // Notifications don't turn on the screen directly, they rely on proximity events
146 if (mode == MirPowerMode::mir_power_mode_on &&
147 reason == PowerStateChangeReason::notification)
148 {
149 allow_proximity_to_turn_on_screen = true;
150 screen_hardware->enable_proximity(true);
151 reset_timers_ignoring_power_mode_l(reason);
152 return;
153 }
154
138 if (mode == MirPowerMode::mir_power_mode_on)155 if (mode == MirPowerMode::mir_power_mode_on)
139 {156 {
140 /* The screen may be dim, but on - make sure to reset backlight */157 /* The screen may be dim, but on - make sure to reset backlight */
@@ -145,16 +162,26 @@
145 }162 }
146 else163 else
147 {164 {
148 cancel_timers_l();165 cancel_timers_l(reason);
149 configure_display_l(mode, reason);166 configure_display_l(mode, reason);
150 }167 }
151}168}
152169
153void usc::MirScreen::configure_display_l(MirPowerMode mode, PowerStateChangeReason reason)170void usc::MirScreen::configure_display_l(MirPowerMode mode, PowerStateChangeReason reason)
154{171{
172 if (reason != PowerStateChangeReason::proximity)
173 {
174 screen_hardware->enable_proximity(false);
175 allow_proximity_to_turn_on_screen = false;
176 }
177
155 if (current_power_mode == mode)178 if (current_power_mode == mode)
156 return;179 return;
157180
181 allow_proximity_to_turn_on_screen =
182 mode == mir_power_mode_off &&
183 reason == PowerStateChangeReason::proximity;
184
158 std::shared_ptr<mg::DisplayConfiguration> displayConfig = display->configuration();185 std::shared_ptr<mg::DisplayConfiguration> displayConfig = display->configuration();
159186
160 displayConfig->for_each_output(187 displayConfig->for_each_output(
@@ -193,8 +220,11 @@
193 screen_hardware->allow_suspend();220 screen_hardware->allow_suspend();
194}221}
195222
196void usc::MirScreen::cancel_timers_l()223void usc::MirScreen::cancel_timers_l(PowerStateChangeReason reason)
197{224{
225 if (reason == PowerStateChangeReason::proximity)
226 return;
227
198 power_off_alarm->cancel();228 power_off_alarm->cancel();
199 dimmer_alarm->cancel();229 dimmer_alarm->cancel();
200 next_power_off = {};230 next_power_off = {};
@@ -203,29 +233,35 @@
203233
204void usc::MirScreen::reset_timers_l(PowerStateChangeReason reason)234void usc::MirScreen::reset_timers_l(PowerStateChangeReason reason)
205{235{
206 if (restart_timers && current_power_mode != MirPowerMode::mir_power_mode_off)236 if (current_power_mode != MirPowerMode::mir_power_mode_off)
237 reset_timers_ignoring_power_mode_l(reason);
238}
239
240void usc::MirScreen::reset_timers_ignoring_power_mode_l(PowerStateChangeReason reason)
241{
242 if (!restart_timers || reason == PowerStateChangeReason::proximity)
243 return;
244
245 auto const timeouts = timeouts_for(reason);
246 auto const now = clock->now();
247
248 if (timeouts.power_off_timeout.count() > 0)
207 {249 {
208 auto const timeouts = timeouts_for(reason);250 auto const new_next_power_off = now + timeouts.power_off_timeout;
209 auto const now = clock->now();251 if (new_next_power_off > next_power_off)
210
211 if (timeouts.power_off_timeout.count() > 0)
212 {252 {
213 auto const new_next_power_off = now + timeouts.power_off_timeout;253 power_off_alarm->reschedule_in(timeouts.power_off_timeout);
214 if (new_next_power_off > next_power_off)254 next_power_off = new_next_power_off;
215 {
216 power_off_alarm->reschedule_in(timeouts.power_off_timeout);
217 next_power_off = new_next_power_off;
218 }
219 }255 }
256 }
220257
221 if (timeouts.dimming_timeout.count() > 0)258 if (timeouts.dimming_timeout.count() > 0)
259 {
260 auto const new_next_dimming = now + timeouts.dimming_timeout;
261 if (new_next_dimming > next_dimming)
222 {262 {
223 auto const new_next_dimming = now + timeouts.dimming_timeout;263 dimmer_alarm->reschedule_in(timeouts.dimming_timeout);
224 if (new_next_dimming > next_dimming)264 next_dimming = new_next_dimming;
225 {
226 dimmer_alarm->reschedule_in(timeouts.dimming_timeout);
227 next_dimming = new_next_dimming;
228 }
229 }265 }
230 }266 }
231}267}
@@ -235,7 +271,7 @@
235 if (enable)271 if (enable)
236 reset_timers_l(PowerStateChangeReason::inactivity);272 reset_timers_l(PowerStateChangeReason::inactivity);
237 else273 else
238 cancel_timers_l();274 cancel_timers_l(PowerStateChangeReason::inactivity);
239}275}
240276
241usc::MirScreen::Timeouts usc::MirScreen::timeouts_for(PowerStateChangeReason reason)277usc::MirScreen::Timeouts usc::MirScreen::timeouts_for(PowerStateChangeReason reason)
@@ -246,6 +282,18 @@
246 return inactivity_timeouts;282 return inactivity_timeouts;
247}283}
248284
285bool usc::MirScreen::is_screen_change_allowed(MirPowerMode mode, PowerStateChangeReason reason)
286{
287 if (mode == MirPowerMode::mir_power_mode_on &&
288 reason == PowerStateChangeReason::proximity &&
289 !allow_proximity_to_turn_on_screen)
290 {
291 return false;
292 }
293
294 return true;
295}
296
249void usc::MirScreen::power_off_alarm_notification()297void usc::MirScreen::power_off_alarm_notification()
250{298{
251 std::lock_guard<std::mutex> lock{guard};299 std::lock_guard<std::mutex> lock{guard};
252300
=== modified file 'src/mir_screen.h'
--- src/mir_screen.h 2015-07-17 12:45:10 +0000
+++ src/mir_screen.h 2015-07-17 12:45:10 +0000
@@ -77,10 +77,12 @@
77 void set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason);77 void set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason);
78 void configure_display_l(MirPowerMode mode, PowerStateChangeReason reason);78 void configure_display_l(MirPowerMode mode, PowerStateChangeReason reason);
7979
80 void cancel_timers_l();80 void cancel_timers_l(PowerStateChangeReason reason);
81 void reset_timers_l(PowerStateChangeReason reason);81 void reset_timers_l(PowerStateChangeReason reason);
82 void reset_timers_ignoring_power_mode_l(PowerStateChangeReason reason);
82 void enable_inactivity_timers_l(bool flag);83 void enable_inactivity_timers_l(bool flag);
83 Timeouts timeouts_for(PowerStateChangeReason reason);84 Timeouts timeouts_for(PowerStateChangeReason reason);
85 bool is_screen_change_allowed(MirPowerMode mode, PowerStateChangeReason reason);
8486
85 void power_off_alarm_notification();87 void power_off_alarm_notification();
86 void dimmer_alarm_notification();88 void dimmer_alarm_notification();
@@ -103,6 +105,7 @@
103 MirPowerMode current_power_mode;105 MirPowerMode current_power_mode;
104 bool restart_timers;106 bool restart_timers;
105 PowerStateChangeHandler power_state_change_handler;107 PowerStateChangeHandler power_state_change_handler;
108 bool allow_proximity_to_turn_on_screen;
106};109};
107110
108}111}
109112
=== modified file 'src/powerd_mediator.cpp'
--- src/powerd_mediator.cpp 2015-04-24 14:40:28 +0000
+++ src/powerd_mediator.cpp 2015-07-17 12:45:10 +0000
@@ -56,6 +56,7 @@
56 backlight_state{BacklightState::normal},56 backlight_state{BacklightState::normal},
57 auto_brightness_supported_{false},57 auto_brightness_supported_{false},
58 auto_brightness_requested{false},58 auto_brightness_requested{false},
59 proximity_enabled{false},
59 sys_state{SysState::unknown}60 sys_state{SysState::unknown}
60{61{
61 connection.add_match(62 connection.add_match(
@@ -197,6 +198,13 @@
197 return max_brightness_;198 return max_brightness_;
198}199}
199200
201void usc::PowerdMediator::enable_proximity(bool enable)
202{
203 std::lock_guard<decltype(mutex)> lock{mutex};
204
205 enable_proximity_l(enable, ForceProximity::no);
206}
207
200bool usc::PowerdMediator::is_system_suspended()208bool usc::PowerdMediator::is_system_suspended()
201{209{
202 std::lock_guard<decltype(mutex)> lock{mutex};210 std::lock_guard<decltype(mutex)> lock{mutex};
@@ -290,6 +298,8 @@
290298
291 // Powerd may have restarted, re-apply backlight settings299 // Powerd may have restarted, re-apply backlight settings
292 change_backlight_state(backlight_state, ForceBacklightState::yes);300 change_backlight_state(backlight_state, ForceBacklightState::yes);
301
302 enable_proximity_l(false, ForceProximity::yes);
293}303}
294304
295void usc::PowerdMediator::init_brightness_params()305void usc::PowerdMediator::init_brightness_params()
@@ -362,6 +372,22 @@
362 }372 }
363}373}
364374
375void usc::PowerdMediator::enable_proximity_l(
376 bool enable, ForceProximity force_proximity)
377{
378 if (proximity_enabled == enable && force_proximity == ForceProximity::no)
379 return;
380
381 auto const name = "unity-system-compositor";
382 auto const request = enable ? "enableProximityHandling" :
383 "disableProximityHandling";
384 invoke_with_reply(request,
385 DBUS_TYPE_STRING, &name,
386 DBUS_TYPE_INVALID);
387
388 proximity_enabled = enable;
389}
390
365bool usc::PowerdMediator::is_valid_brightness(int brightness)391bool usc::PowerdMediator::is_valid_brightness(int brightness)
366{392{
367 return brightness >= min_brightness_ && brightness <= max_brightness_;393 return brightness >= min_brightness_ && brightness <= max_brightness_;
368394
=== modified file 'src/powerd_mediator.h'
--- src/powerd_mediator.h 2015-04-07 13:36:48 +0000
+++ src/powerd_mediator.h 2015-07-17 12:45:10 +0000
@@ -46,6 +46,8 @@
46 int min_brightness() override;46 int min_brightness() override;
47 int max_brightness() override;47 int max_brightness() override;
4848
49 void enable_proximity(bool enable) override;
50
49 bool is_system_suspended();51 bool is_system_suspended();
5052
51private:53private:
@@ -66,6 +68,7 @@
6668
67 enum class ForceDisableSuspend { no, yes };69 enum class ForceDisableSuspend { no, yes };
68 enum class ForceBacklightState { no, yes };70 enum class ForceBacklightState { no, yes };
71 enum class ForceProximity { no, yes };
6972
70 static ::DBusHandlerResult handle_dbus_message_thunk(73 static ::DBusHandlerResult handle_dbus_message_thunk(
71 ::DBusConnection* connection, ::DBusMessage* message, void* user_data);74 ::DBusConnection* connection, ::DBusMessage* message, void* user_data);
@@ -76,6 +79,7 @@
76 void init_brightness_params();79 void init_brightness_params();
77 void change_backlight_state(80 void change_backlight_state(
78 BacklightState new_state, ForceBacklightState force_backlight_state);81 BacklightState new_state, ForceBacklightState force_backlight_state);
82 void enable_proximity_l(bool enable, ForceProximity force_proximity);
79 bool is_valid_brightness(int brightness);83 bool is_valid_brightness(int brightness);
80 bool request_suspend_block();84 bool request_suspend_block();
81 void wait_for_sys_state(SysState state);85 void wait_for_sys_state(SysState state);
@@ -98,6 +102,7 @@
98 BacklightState backlight_state;102 BacklightState backlight_state;
99 bool auto_brightness_supported_;103 bool auto_brightness_supported_;
100 bool auto_brightness_requested;104 bool auto_brightness_requested;
105 bool proximity_enabled;
101 std::string suspend_block_cookie;106 std::string suspend_block_cookie;
102 std::mutex sys_state_mutex;107 std::mutex sys_state_mutex;
103 SysState sys_state;108 SysState sys_state;
104109
=== modified file 'src/screen_hardware.h'
--- src/screen_hardware.h 2015-02-18 14:40:29 +0000
+++ src/screen_hardware.h 2015-07-17 12:45:10 +0000
@@ -39,6 +39,8 @@
39 virtual int min_brightness() = 0;39 virtual int min_brightness() = 0;
40 virtual int max_brightness() = 0;40 virtual int max_brightness() = 0;
4141
42 virtual void enable_proximity(bool enable) = 0;
43
42protected:44protected:
43 ScreenHardware() = default;45 ScreenHardware() = default;
44 ScreenHardware(ScreenHardware const&) = delete;46 ScreenHardware(ScreenHardware const&) = delete;
4547
=== modified file 'tests/integration-tests/test_powerd_mediator.cpp'
--- tests/integration-tests/test_powerd_mediator.cpp 2015-04-07 13:36:48 +0000
+++ tests/integration-tests/test_powerd_mediator.cpp 2015-07-17 12:45:10 +0000
@@ -84,6 +84,8 @@
84 MOCK_METHOD1(dbus_userAutobrightnessEnable, void(dbus_bool_t enable));84 MOCK_METHOD1(dbus_userAutobrightnessEnable, void(dbus_bool_t enable));
85 MOCK_METHOD2(dbus_requestSysState, std::string(char const* name, int state));85 MOCK_METHOD2(dbus_requestSysState, std::string(char const* name, int state));
86 MOCK_METHOD1(dbus_clearSysState, void(char const* cookie));86 MOCK_METHOD1(dbus_clearSysState, void(char const* cookie));
87 MOCK_METHOD1(dbus_enableProximityHandling, void(char const* name));
88 MOCK_METHOD1(dbus_disableProximityHandling, void(char const* name));
8789
88 int32_t const dim_brightness = 13;90 int32_t const dim_brightness = 13;
89 int32_t const min_brightness = 5;91 int32_t const min_brightness = 5;
@@ -192,6 +194,32 @@
192194
193 emit_SysPowerStateChange(0);195 emit_SysPowerStateChange(0);
194 }196 }
197 else if (dbus_message_is_method_call(message, powerd_service_name, "enableProximityHandling"))
198 {
199 char const* name{nullptr};
200 dbus_message_get_args(
201 message, nullptr,
202 DBUS_TYPE_STRING, &name,
203 DBUS_TYPE_INVALID);
204
205 dbus_enableProximityHandling(name);
206
207 usc::DBusMessageHandle reply{dbus_message_new_method_return(message)};
208 dbus_connection_send(connection, reply, nullptr);
209 }
210 else if (dbus_message_is_method_call(message, powerd_service_name, "disableProximityHandling"))
211 {
212 char const* name{nullptr};
213 dbus_message_get_args(
214 message, nullptr,
215 DBUS_TYPE_STRING, &name,
216 DBUS_TYPE_INVALID);
217
218 dbus_disableProximityHandling(name);
219
220 usc::DBusMessageHandle reply{dbus_message_new_method_return(message)};
221 dbus_connection_send(connection, reply, nullptr);
222 }
195223
196 return DBUS_HANDLER_RESULT_HANDLED;224 return DBUS_HANDLER_RESULT_HANDLED;
197 }225 }
@@ -462,6 +490,41 @@
462 mediator->allow_suspend();490 mediator->allow_suspend();
463}491}
464492
493TEST_F(APowerdMediator, enables_and_disables_proximity_handling)
494{
495 using namespace testing;
496 auto const proximity_name = "unity-system-compositor";
497
498 InSequence s;
499 EXPECT_CALL(powerd_service, dbus_enableProximityHandling(StrEq(proximity_name)));
500 EXPECT_CALL(powerd_service, dbus_disableProximityHandling(StrEq(proximity_name)));
501
502 mediator->enable_proximity(true);
503 mediator->enable_proximity(false);
504}
505
506TEST_F(APowerdMediator, ignores_requests_for_redundant_proximity_handling)
507{
508 using namespace testing;
509
510 auto const proximity_name = "unity-system-compositor";
511
512 InSequence s;
513 EXPECT_CALL(powerd_service, dbus_enableProximityHandling(StrEq(proximity_name)));
514 EXPECT_CALL(powerd_service, dbus_disableProximityHandling(StrEq(proximity_name)));
515
516 // Should be ignore, proximity already disabled
517 mediator->enable_proximity(false);
518
519 // Should be handled only once
520 mediator->enable_proximity(true);
521 mediator->enable_proximity(true);
522
523 // Should be handled only once
524 mediator->enable_proximity(false);
525 mediator->enable_proximity(false);
526}
527
465namespace528namespace
466{529{
467530
@@ -637,6 +700,24 @@
637 EXPECT_CALL(powerd_service, dbus_setUserBrightness(0)).Times(AtMost(1));700 EXPECT_CALL(powerd_service, dbus_setUserBrightness(0)).Times(AtMost(1));
638}701}
639702
703TEST(APowerdMediatorAtStartup, disables_proximity_handling)
704{
705 using namespace testing;
706
707 dbus_bool_t const auto_brightness_supported{TRUE};
708
709 ut::DBusBus bus;
710 NiceMock<PowerdService> powerd_service{
711 bus.address(), auto_brightness_supported, PowerdService::StartNow::yes};
712
713 EXPECT_CALL(powerd_service, dbus_disableProximityHandling(_));
714
715 usc::PowerdMediator mediator{bus.address()};
716 powerd_service.wait_for_initial_setup();
717
718 Mock::VerifyAndClearExpectations(&powerd_service);
719}
720
640TEST(APowerdMediatorAtShutdown, turns_off_backlight)721TEST(APowerdMediatorAtShutdown, turns_off_backlight)
641{722{
642 using namespace testing;723 using namespace testing;
643724
=== modified file 'tests/unit-tests/test_mir_screen.cpp'
--- tests/unit-tests/test_mir_screen.cpp 2015-07-17 12:45:10 +0000
+++ tests/unit-tests/test_mir_screen.cpp 2015-07-17 12:45:10 +0000
@@ -116,6 +116,25 @@
116 MOCK_METHOD1(set_brightness, void(int));116 MOCK_METHOD1(set_brightness, void(int));
117 int min_brightness() override { return 100; }117 int min_brightness() override { return 100; }
118 int max_brightness() override { return 0; }118 int max_brightness() override { return 0; }
119
120 enum class Proximity {near, far};
121
122 void enable_proximity(bool enable) override
123 {
124 proximity_enabled = enable;
125 set_proximity(current_proximity);
126 }
127
128 void set_proximity(Proximity proximity)
129 {
130 current_proximity = proximity;
131 if (proximity_enabled)
132 on_proximity_changed(current_proximity);
133 }
134
135 std::function<void(Proximity)> on_proximity_changed = [](Proximity){};
136 Proximity current_proximity{Proximity::far};
137 bool proximity_enabled{false};
119};138};
120139
121struct MockTouchVisualizer : mir::input::TouchVisualizer140struct MockTouchVisualizer : mir::input::TouchVisualizer
@@ -129,6 +148,36 @@
129148
130struct AMirScreen : testing::Test149struct AMirScreen : testing::Test
131{150{
151 AMirScreen()
152 {
153 using namespace testing;
154
155 screen_hardware->on_proximity_changed =
156 [this] (MockScreenHardware::Proximity p) { defer_proximity_event(p); };
157 }
158
159 void defer_proximity_event(MockScreenHardware::Proximity proximity)
160 {
161 deferred_actions.push_back(
162 [this, proximity]
163 {
164 mir_screen.set_screen_power_mode(
165 proximity == MockScreenHardware::Proximity::far ?
166 MirPowerMode::mir_power_mode_on :
167 MirPowerMode::mir_power_mode_off,
168 PowerStateChangeReason::proximity);
169 });
170 }
171
172 void process_deferred_actions()
173 {
174 for (auto const& a : deferred_actions)
175 a();
176 deferred_actions.clear();
177 }
178
179 std::vector<std::function<void(void)>> deferred_actions;
180
132 std::chrono::seconds const power_off_timeout{60};181 std::chrono::seconds const power_off_timeout{60};
133 std::chrono::seconds const dimmer_timeout{50};182 std::chrono::seconds const dimmer_timeout{50};
134 std::chrono::seconds const notification_power_off_timeout{15};183 std::chrono::seconds const notification_power_off_timeout{15};
@@ -185,6 +234,26 @@
185 verify_and_clear_expectations();234 verify_and_clear_expectations();
186 }235 }
187236
237 void receive_notification()
238 {
239 mir_screen.set_screen_power_mode(
240 MirPowerMode::mir_power_mode_on,
241 PowerStateChangeReason::notification);
242 process_deferred_actions();
243 }
244
245 void cover_screen()
246 {
247 screen_hardware->set_proximity(MockScreenHardware::Proximity::near);
248 process_deferred_actions();
249 }
250
251 void uncover_screen()
252 {
253 screen_hardware->set_proximity(MockScreenHardware::Proximity::far);
254 process_deferred_actions();
255 }
256
188 void verify_and_clear_expectations()257 void verify_and_clear_expectations()
189 {258 {
190 using namespace testing;259 using namespace testing;
@@ -378,13 +447,12 @@
378 EXPECT_THAT(handler_mode, Eq(MirPowerMode::mir_power_mode_off));447 EXPECT_THAT(handler_mode, Eq(MirPowerMode::mir_power_mode_off));
379}448}
380449
381TEST_F(AMirScreen, turns_screen_off_after_15s_for_notification)450TEST_F(AMirScreen, turns_screen_off_after_notification_timeout)
382{451{
383 turn_screen_off();452 turn_screen_off();
384453
385 expect_screen_is_turned_on();454 expect_screen_is_turned_on();
386 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,455 receive_notification();
387 PowerStateChangeReason::notification);
388 verify_and_clear_expectations();456 verify_and_clear_expectations();
389457
390 expect_screen_is_turned_off();458 expect_screen_is_turned_off();
@@ -396,8 +464,7 @@
396 turn_screen_off();464 turn_screen_off();
397465
398 expect_screen_is_turned_on();466 expect_screen_is_turned_on();
399 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,467 receive_notification();
400 PowerStateChangeReason::notification);
401 verify_and_clear_expectations();468 verify_and_clear_expectations();
402469
403 // At T=10 we request a temporary keep display on (e.g. user has touched470 // At T=10 we request a temporary keep display on (e.g. user has touched
@@ -426,8 +493,7 @@
426493
427 // At T=50 we get a notification494 // At T=50 we get a notification
428 timer->advance_by(fifty_seconds);495 timer->advance_by(fifty_seconds);
429 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,496 receive_notification();
430 PowerStateChangeReason::notification);
431 verify_and_clear_expectations();497 verify_and_clear_expectations();
432498
433 // At T=60 the screen should still be active because the notification499 // At T=60 the screen should still be active because the notification
@@ -452,8 +518,7 @@
452518
453 // At T=30 we get a notification519 // At T=30 we get a notification
454 timer->advance_by(thirty_seconds);520 timer->advance_by(thirty_seconds);
455 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,521 receive_notification();
456 PowerStateChangeReason::notification);
457 verify_and_clear_expectations();522 verify_and_clear_expectations();
458523
459 // At T=45 the screen should still be active because the notification524 // At T=45 the screen should still be active because the notification
@@ -485,8 +550,7 @@
485550
486 // At T=40 we get a notification551 // At T=40 we get a notification
487 timer->advance_by(fourty_seconds);552 timer->advance_by(fourty_seconds);
488 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,553 receive_notification();
489 PowerStateChangeReason::notification);
490 verify_and_clear_expectations();554 verify_and_clear_expectations();
491555
492 // At T=50 nothing should happen since the notification has556 // At T=50 nothing should happen since the notification has
@@ -506,3 +570,152 @@
506 expect_screen_is_turned_off();570 expect_screen_is_turned_off();
507 timer->advance_by(eight_seconds);571 timer->advance_by(eight_seconds);
508}572}
573
574TEST_F(AMirScreen, proximity_requests_affect_screen_state)
575{
576 expect_screen_is_turned_off();
577 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_off,
578 PowerStateChangeReason::proximity);
579 verify_and_clear_expectations();
580
581 expect_screen_is_turned_on();
582 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,
583 PowerStateChangeReason::proximity);
584 verify_and_clear_expectations();
585}
586
587TEST_F(AMirScreen, proximity_requests_do_not_reset_timeouts)
588{
589 // At T=0 we turn the screen on, and normal inactivity timeouts
590 // are reset
591 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,
592 PowerStateChangeReason::power_key);
593
594 // At T=30 we get a screen off request due to proximity
595 timer->advance_by(thirty_seconds);
596 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_off,
597 PowerStateChangeReason::proximity);
598
599 // At T=40 we get a screen on request due to proximity
600 timer->advance_by(ten_seconds);
601 mir_screen.set_screen_power_mode(MirPowerMode::mir_power_mode_on,
602 PowerStateChangeReason::proximity);
603
604 verify_and_clear_expectations();
605
606 // At T=50 screen should be dimmed due to the inactivity
607 // dimming timeout
608 expect_screen_is_turned_dim();
609 timer->advance_by(ten_seconds);
610 verify_and_clear_expectations();
611
612 // At T=60 the screen should turn off due to the normal
613 // inactivity timeout
614 expect_screen_is_turned_off();
615 timer->advance_by(ten_seconds);
616}
617
618TEST_F(AMirScreen, does_not_turn_on_screen_when_notification_arrives_with_phone_covered)
619{
620 turn_screen_off();
621 cover_screen();
622
623 expect_no_reconfiguration();
624 receive_notification();
625}
626
627TEST_F(AMirScreen, turns_screen_on_when_phone_is_uncovered_after_notification_arrives)
628{
629 turn_screen_off();
630 cover_screen();
631
632 expect_no_reconfiguration();
633 receive_notification();
634 verify_and_clear_expectations();
635
636 expect_screen_is_turned_on();
637 uncover_screen();
638}
639
640TEST_F(AMirScreen, cancels_proximity_handling_when_phone_is_turned_off_after_notification)
641{
642 turn_screen_off();
643 cover_screen();
644
645 receive_notification();
646 timer->advance_by(notification_power_off_timeout);
647 verify_and_clear_expectations();
648
649 expect_no_reconfiguration();
650 uncover_screen();
651 cover_screen();
652}
653
654TEST_F(AMirScreen, cancels_proximity_handling_when_screen_is_touched_after_notification)
655{
656 turn_screen_off();
657
658 receive_notification();
659 mir_screen.keep_display_on_temporarily();
660 verify_and_clear_expectations();
661
662 expect_no_reconfiguration();
663 cover_screen();
664 uncover_screen();
665}
666
667TEST_F(AMirScreen, does_not_allow_proximity_to_turn_on_screen_not_turned_off_by_proximity)
668{
669 turn_screen_off();
670
671 expect_no_reconfiguration();
672 mir_screen.set_screen_power_mode(
673 MirPowerMode::mir_power_mode_on,
674 PowerStateChangeReason::proximity);
675 verify_and_clear_expectations();
676
677 expect_no_reconfiguration();
678 mir_screen.set_screen_power_mode(
679 MirPowerMode::mir_power_mode_off,
680 PowerStateChangeReason::proximity);
681 verify_and_clear_expectations();
682
683 expect_no_reconfiguration();
684 mir_screen.set_screen_power_mode(
685 MirPowerMode::mir_power_mode_on,
686 PowerStateChangeReason::proximity);
687}
688
689TEST_F(AMirScreen, does_not_allow_proximity_to_turn_on_screen_not_turned_off_by_proximity_2)
690{
691 mir_screen.set_screen_power_mode(
692 MirPowerMode::mir_power_mode_off,
693 PowerStateChangeReason::proximity);
694
695 mir_screen.set_screen_power_mode(
696 MirPowerMode::mir_power_mode_off,
697 PowerStateChangeReason::power_key);
698
699 verify_and_clear_expectations();
700
701 expect_no_reconfiguration();
702 mir_screen.set_screen_power_mode(
703 MirPowerMode::mir_power_mode_on,
704 PowerStateChangeReason::proximity);
705}
706
707TEST_F(AMirScreen, proximity_can_affect_screen_after_keep_display_on)
708{
709 mir_screen.keep_display_on(true);
710
711 expect_screen_is_turned_off();
712 mir_screen.set_screen_power_mode(
713 MirPowerMode::mir_power_mode_off,
714 PowerStateChangeReason::proximity);
715 verify_and_clear_expectations();
716
717 expect_screen_is_turned_on();
718 mir_screen.set_screen_power_mode(
719 MirPowerMode::mir_power_mode_on,
720 PowerStateChangeReason::proximity);
721}

Subscribers

People subscribed via source and target branches