Merge lp:~azzar1/unity/clear-color-buffer-before-suspending into lp:unity

Proposed by Andrea Azzarone
Status: Superseded
Proposed branch: lp:~azzar1/unity/clear-color-buffer-before-suspending
Merge into: lp:unity
Diff against target: 707 lines (+205/-87)
15 files modified
lockscreen/KylinUserPromptView.cpp (+15/-15)
lockscreen/KylinUserPromptView.h (+2/-3)
lockscreen/LockScreenAbstractPromptView.h (+5/-3)
lockscreen/LockScreenController.cpp (+42/-2)
lockscreen/LockScreenController.h (+9/-0)
lockscreen/LockScreenPromptFactory.cpp (+4/-3)
lockscreen/LockScreenPromptFactory.h (+3/-1)
lockscreen/SuspendInhibitorManager.cpp (+2/-0)
lockscreen/SuspendInhibitorManager.h (+1/-0)
lockscreen/UserAuthenticator.h (+2/-0)
lockscreen/UserAuthenticatorPam.cpp (+41/-33)
lockscreen/UserAuthenticatorPam.h (+9/-8)
lockscreen/UserPromptView.cpp (+51/-15)
lockscreen/UserPromptView.h (+7/-4)
plugins/unityshell/src/unityshell.cpp (+12/-0)
To merge this branch: bzr merge lp:~azzar1/unity/clear-color-buffer-before-suspending
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+331002@code.launchpad.net

Commit message

Wait until the color buffer is cleared before suspending.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lockscreen/KylinUserPromptView.cpp'
2--- lockscreen/KylinUserPromptView.cpp 2016-03-31 05:57:11 +0000
3+++ lockscreen/KylinUserPromptView.cpp 2017-09-19 17:57:43 +0000
4@@ -79,9 +79,9 @@
5
6 }
7
8-KylinUserPromptView::KylinUserPromptView(session::Manager::Ptr const& session_manager)
9- : AbstractUserPromptView(session_manager)
10- , session_manager_(session_manager)
11+KylinUserPromptView::KylinUserPromptView(session::Manager::Ptr const& session_manager,
12+ UserAuthenticator::Ptr const& user_authenticator)
13+ : AbstractUserPromptView(session_manager, user_authenticator)
14 , username_(nullptr)
15 , msg_layout_(nullptr)
16 , prompt_layout_(nullptr)
17@@ -90,25 +90,25 @@
18 , avatar_(nullptr)
19 , avatar_icon_file("")
20 {
21- user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
22+ user_authenticator_->echo_on_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
23 AddPrompt(message, true, promise);
24- });
25+ }, *this));
26
27- user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
28+ user_authenticator_->echo_off_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
29 AddPrompt(message, false, promise);
30- });
31+ }, *this));
32
33- user_authenticator_.message_requested.connect([this](std::string const& message){
34+ user_authenticator_->message_requested.connect(sigc::track_obj([this](std::string const& message){
35 AddMessage(message, nux::color::White);
36- });
37+ }, *this));
38
39- user_authenticator_.error_requested.connect([this](std::string const& message){
40+ user_authenticator_->error_requested.connect(sigc::track_obj([this](std::string const& message){
41 AddMessage(message, nux::color::Red);
42- });
43+ }, *this));
44
45- user_authenticator_.clear_prompts.connect([this](){
46+ user_authenticator_->clear_prompts.connect(sigc::track_obj([this](){
47 ResetLayout();
48- });
49+ }, *this));
50
51 scale.changed.connect(sigc::hide(sigc::mem_fun(this, &KylinUserPromptView::UpdateSize)));
52
53@@ -121,7 +121,7 @@
54 ResetLayout();
55
56 TextureCache::GetDefault().themed_invalidated.connect(sigc::mem_fun(this, &KylinUserPromptView::ResetLayout));
57- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
58+ user_authenticator_->AuthenticateStart(session_manager_->UserName(),
59 sigc::mem_fun(this, &KylinUserPromptView::AuthenticationCb));
60 }
61
62@@ -244,7 +244,7 @@
63 {
64 AddMessage(_("Invalid password, please try again"), nux::color::Red);
65
66- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
67+ user_authenticator_->AuthenticateStart(session_manager_->UserName(),
68 sigc::mem_fun(this, &KylinUserPromptView::AuthenticationCb));
69 }
70 }
71
72=== modified file 'lockscreen/KylinUserPromptView.h'
73--- lockscreen/KylinUserPromptView.h 2016-03-16 10:47:16 +0000
74+++ lockscreen/KylinUserPromptView.h 2017-09-19 17:57:43 +0000
75@@ -44,7 +44,8 @@
76 class KylinUserPromptView : public AbstractUserPromptView
77 {
78 public:
79- KylinUserPromptView(session::Manager::Ptr const& session_manager);
80+ KylinUserPromptView(session::Manager::Ptr const& session_manager,
81+ UserAuthenticator::Ptr const& user_authenticator);
82
83 nux::View* focus_view();
84
85@@ -62,8 +63,6 @@
86 nux::ObjectPtr<nux::BaseTexture> LoadUserIcon(std::string const& icon_file, int icon_size);
87
88 private:
89- session::Manager::Ptr session_manager_;
90- UserAuthenticatorPam user_authenticator_;
91 StaticCairoText* username_;
92 nux::VLayout* msg_layout_;
93 nux::VLayout* prompt_layout_;
94
95=== modified file 'lockscreen/LockScreenAbstractPromptView.h'
96--- lockscreen/LockScreenAbstractPromptView.h 2016-03-31 09:51:33 +0000
97+++ lockscreen/LockScreenAbstractPromptView.h 2017-09-19 17:57:43 +0000
98@@ -29,7 +29,7 @@
99 #include <Nux/VLayout.h>
100 #include "UnityCore/SessionManager.h"
101
102-#include "UserAuthenticatorPam.h"
103+#include "UserAuthenticator.h"
104 #include "unity-shared/IMTextEntry.h"
105
106 namespace nux
107@@ -48,10 +48,12 @@
108 class AbstractUserPromptView : public nux::View
109 {
110 public:
111- AbstractUserPromptView(session::Manager::Ptr const& session_manager)
112+ AbstractUserPromptView(session::Manager::Ptr const& session_manager,
113+ UserAuthenticator::Ptr const& user_authenticator)
114 : nux::View(NUX_TRACKER_LOCATION)
115 , scale(1.0)
116 , session_manager_(session_manager)
117+ , user_authenticator_(user_authenticator)
118 {}
119
120 nux::Property<double> scale;
121@@ -64,7 +66,7 @@
122
123 protected:
124 session::Manager::Ptr session_manager_;
125- UserAuthenticatorPam user_authenticator_;
126+ UserAuthenticator::Ptr user_authenticator_;
127 std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
128 StaticCairoText* username_;
129 nux::VLayout* msg_layout_;
130
131=== modified file 'lockscreen/LockScreenController.cpp'
132--- lockscreen/LockScreenController.cpp 2016-11-11 16:00:53 +0000
133+++ lockscreen/LockScreenController.cpp 2017-09-19 17:57:43 +0000
134@@ -27,6 +27,7 @@
135 #include "LockScreenPromptFactory.h"
136 #include "LockScreenShield.h"
137 #include "LockScreenSettings.h"
138+#include "UserAuthenticatorPam.h"
139 #include "unity-shared/AnimationUtils.h"
140 #include "unity-shared/InputMonitor.h"
141 #include "unity-shared/UnitySettings.h"
142@@ -70,10 +71,13 @@
143 , upstart_wrapper_(upstart_wrapper)
144 , shield_factory_(shield_factory)
145 , suspend_inhibitor_manager_(std::make_shared<SuspendInhibitorManager>())
146+ , user_authenticator_(std::make_shared<UserAuthenticatorPam>())
147 , fade_animator_(unity::Settings::Instance().low_gfx() ? 0 : LOCK_FADE_DURATION)
148 , blank_window_animator_(IDLE_FADE_DURATION)
149 , test_mode_(test_mode)
150 , prompt_activation_(false)
151+ , is_paint_inhibited_(false)
152+ , buffer_cleared_(true)
153 {
154 auto* uscreen = UScreen::GetDefault();
155 uscreen_connection_ = uscreen->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
156@@ -91,7 +95,13 @@
157 suspend_inhibitor_manager_->connected.connect(sigc::mem_fun(this, &Controller::SyncInhibitor));
158 suspend_inhibitor_manager_->about_to_suspend.connect([this] () {
159 if (Settings::Instance().lock_on_suspend())
160+ {
161+ InhibitPaint();
162 session_manager_->PromptLockScreen();
163+ }
164+ });
165+ suspend_inhibitor_manager_->resumed.connect([this] () {
166+ UninhibitPaint();
167 });
168
169 Settings::Instance().lock_on_suspend.changed.connect(sigc::hide(sigc::mem_fun(this, &Controller::SyncInhibitor)));
170@@ -259,7 +269,7 @@
171
172 if (!prompt_view)
173 {
174- prompt_view = test_mode_ ? nux::ObjectPtr<AbstractUserPromptView>() : PromptFactory::CreatePrompt(session_manager_);
175+ prompt_view = test_mode_ ? nux::ObjectPtr<AbstractUserPromptView>() : PromptFactory::CreatePrompt(session_manager_, user_authenticator_);
176 prompt_view_ = prompt_view.GetPointer();
177 }
178
179@@ -554,6 +564,36 @@
180 return primary_shield_.IsValid() ? primary_shield_->IsIndicatorOpen() : false;
181 }
182
183+void Controller::InhibitPaint()
184+{
185+ buffer_cleared_ = false;
186+ is_paint_inhibited_ = true;
187+}
188+
189+void Controller::UninhibitPaint()
190+{
191+ if (!is_paint_inhibited_)
192+ return;
193+
194+ buffer_cleared_ = true;
195+ is_paint_inhibited_ = false;
196+ SyncInhibitor();
197+}
198+
199+bool Controller::IsPaintInhibited() const
200+{
201+ return is_paint_inhibited_;
202+}
203+
204+void Controller::MarkBufferHasCleared()
205+{
206+ if (buffer_cleared_)
207+ return;
208+
209+ buffer_cleared_ = true;
210+ SyncInhibitor();
211+}
212+
213 void Controller::SyncInhibitor()
214 {
215 bool locked = IsLocked() && primary_shield_.IsValid() && primary_shield_->GetOpacity() == 1.0f;
216@@ -564,7 +604,7 @@
217
218 if (inhibit)
219 suspend_inhibitor_manager_->Inhibit("Unity needs to lock the screen");
220- else
221+ else if (buffer_cleared_)
222 suspend_inhibitor_manager_->Uninhibit();
223 }
224
225
226=== modified file 'lockscreen/LockScreenController.h'
227--- lockscreen/LockScreenController.h 2016-11-11 16:00:53 +0000
228+++ lockscreen/LockScreenController.h 2017-09-19 17:57:43 +0000
229@@ -29,6 +29,7 @@
230 #include "LockScreenAcceleratorController.h"
231 #include "SuspendInhibitorManager.h"
232 #include "ScreenSaverDBusManager.h"
233+#include "UserAuthenticator.h"
234 #include "unity-shared/BackgroundEffectHelper.h"
235 #include "unity-shared/SystemdWrapper.h"
236 #include "unity-shared/UpstartWrapper.h"
237@@ -55,6 +56,8 @@
238
239 bool IsLocked() const;
240 bool HasOpenMenu() const;
241+ bool IsPaintInhibited() const;
242+ void MarkBufferHasCleared();
243
244 private:
245 friend class TestLockScreenController;
246@@ -81,6 +84,9 @@
247 void OnLockScreenInputEvent(XEvent const&);
248 void OnBlankWindowInputEvent(XEvent const&);
249
250+ void InhibitPaint();
251+ void UninhibitPaint();
252+
253 std::vector<nux::ObjectPtr<BaseShield>> shields_;
254 nux::ObjectWeakPtr<BaseShield> primary_shield_;
255 nux::ObjectWeakPtr<AbstractUserPromptView> prompt_view_;
256@@ -95,6 +101,7 @@
257 UpstartWrapper::Ptr upstart_wrapper_;
258 ShieldFactoryInterface::Ptr shield_factory_;
259 SuspendInhibitorManager::Ptr suspend_inhibitor_manager_;
260+ UserAuthenticator::Ptr user_authenticator_;
261
262 nux::animation::AnimateValue<double> fade_animator_;
263 nux::animation::AnimateValue<double> blank_window_animator_;
264@@ -102,6 +109,8 @@
265 bool test_mode_;
266 bool prompt_activation_;
267 BlurType old_blur_type_;
268+ bool is_paint_inhibited_;
269+ bool buffer_cleared_;
270
271 connection::Wrapper uscreen_connection_;
272 connection::Wrapper hidden_window_connection_;
273
274=== modified file 'lockscreen/LockScreenPromptFactory.cpp'
275--- lockscreen/LockScreenPromptFactory.cpp 2015-12-04 08:17:46 +0000
276+++ lockscreen/LockScreenPromptFactory.cpp 2017-09-19 17:57:43 +0000
277@@ -26,14 +26,15 @@
278 {
279 namespace lockscreen
280 {
281-nux::ObjectPtr<AbstractUserPromptView> PromptFactory::CreatePrompt(session::Manager::Ptr const& sm)
282+nux::ObjectPtr<AbstractUserPromptView> PromptFactory::CreatePrompt(session::Manager::Ptr const& sm,
283+ UserAuthenticator::Ptr const& ua)
284 {
285 nux::ObjectPtr<AbstractUserPromptView> prompt;
286
287 if (unity::Settings::Instance().desktop_type() == DesktopType::UBUNTUKYLIN)
288- prompt = new KylinUserPromptView(sm);
289+ prompt = new KylinUserPromptView(sm, ua);
290 else
291- prompt = new UserPromptView(sm);
292+ prompt = new UserPromptView(sm, ua);
293
294 return prompt;
295 }
296
297=== modified file 'lockscreen/LockScreenPromptFactory.h'
298--- lockscreen/LockScreenPromptFactory.h 2016-03-31 09:51:33 +0000
299+++ lockscreen/LockScreenPromptFactory.h 2017-09-19 17:57:43 +0000
300@@ -22,6 +22,7 @@
301
302 #include <NuxCore/NuxCore.h>
303 #include "UnityCore/SessionManager.h"
304+#include "UserAuthenticator.h"
305
306 namespace unity
307 {
308@@ -33,7 +34,8 @@
309
310 struct PromptFactory
311 {
312- static nux::ObjectPtr<AbstractUserPromptView> CreatePrompt(session::Manager::Ptr const&);
313+ static nux::ObjectPtr<AbstractUserPromptView> CreatePrompt(session::Manager::Ptr const&,
314+ UserAuthenticator::Ptr const&);
315 };
316
317 }
318
319=== modified file 'lockscreen/SuspendInhibitorManager.cpp'
320--- lockscreen/SuspendInhibitorManager.cpp 2016-03-31 09:59:30 +0000
321+++ lockscreen/SuspendInhibitorManager.cpp 2017-09-19 17:57:43 +0000
322@@ -60,6 +60,8 @@
323 lm_proxy_->Connect("PrepareForSleep", [this] (GVariant* variant) {
324 if (glib::Variant(variant).GetBool())
325 parent_->about_to_suspend.emit();
326+ else
327+ parent_->resumed.emit();
328 });
329
330 lm_proxy_->connected.connect(sigc::mem_fun(&parent->connected, &decltype(parent->connected)::emit));
331
332=== modified file 'lockscreen/SuspendInhibitorManager.h'
333--- lockscreen/SuspendInhibitorManager.h 2016-03-31 09:59:30 +0000
334+++ lockscreen/SuspendInhibitorManager.h 2017-09-19 17:57:43 +0000
335@@ -42,6 +42,7 @@
336
337 sigc::signal<void> connected;
338 sigc::signal<void> about_to_suspend;
339+ sigc::signal<void> resumed;
340
341 private:
342 class Impl;
343
344=== modified file 'lockscreen/UserAuthenticator.h'
345--- lockscreen/UserAuthenticator.h 2014-03-05 04:09:13 +0000
346+++ lockscreen/UserAuthenticator.h 2017-09-19 17:57:43 +0000
347@@ -36,6 +36,7 @@
348 class UserAuthenticator
349 {
350 public:
351+ typedef std::shared_ptr<UserAuthenticator> Ptr;
352 typedef std::function<void(bool)> AuthenticateEndCallback;
353
354 virtual ~UserAuthenticator() = default;
355@@ -43,6 +44,7 @@
356 // Authenticate the user in a background thread.
357 virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;
358
359+ sigc::signal<void> start_failed;
360 sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;
361 sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_off_requested;
362 sigc::signal<void, std::string> message_requested;
363
364=== modified file 'lockscreen/UserAuthenticatorPam.cpp'
365--- lockscreen/UserAuthenticatorPam.cpp 2016-08-10 08:56:27 +0000
366+++ lockscreen/UserAuthenticatorPam.cpp 2017-09-19 17:57:43 +0000
367@@ -23,6 +23,7 @@
368
369 #include "UserAuthenticatorPam.h"
370 #include "unity-shared/UnitySettings.h"
371+#include "UnityCore/GLibWrapper.h"
372
373 #include <cstring>
374 #include <security/pam_appl.h>
375@@ -36,42 +37,49 @@
376 bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
377 AuthenticateEndCallback const& authenticate_cb)
378 {
379+ if (pam_handle_)
380+ return false;
381+
382 first_prompt_ = true;
383 username_ = username;
384 authenticate_cb_ = authenticate_cb;
385- pam_handle_ = nullptr;
386-
387- if (!InitPam() || !pam_handle_)
388- return false;
389-
390- glib::Object<GTask> task(g_task_new(nullptr, cancellable_, [] (GObject*, GAsyncResult*, gpointer data) {
391- auto self = static_cast<UserAuthenticatorPam*>(data);
392- pam_end(self->pam_handle_, self->status_);
393- self->authenticate_cb_(self->status_ == PAM_SUCCESS);
394- }, this));
395-
396- g_task_set_task_data(task, this, nullptr);
397-
398- g_task_run_in_thread(task, [] (GTask* task, gpointer, gpointer data, GCancellable*) {
399- auto self = static_cast<UserAuthenticatorPam*>(data);
400-
401- self->status_ = pam_authenticate(self->pam_handle_, 0);
402-
403- if (self->status_ == PAM_SUCCESS)
404- {
405- int status2 = pam_acct_mgmt(self->pam_handle_, 0);
406-
407- if (status2 == PAM_NEW_AUTHTOK_REQD)
408- status2 = pam_chauthtok(self->pam_handle_, PAM_CHANGE_EXPIRED_AUTHTOK);
409-
410- if (unity::Settings::Instance().pam_check_account_type())
411- self->status_ = status2;
412-
413- pam_setcred(self->pam_handle_, PAM_REINITIALIZE_CRED);
414- }
415- });
416-
417- return true;
418+
419+ glib::Error error;
420+ g_thread_try_new(nullptr, AuthenticationThreadFunc, this, &error);
421+
422+ return !error;
423+}
424+
425+gpointer UserAuthenticatorPam::AuthenticationThreadFunc(gpointer data)
426+{
427+ auto self = static_cast<UserAuthenticatorPam*>(data);
428+
429+ if (!self->InitPam() || !self->pam_handle_)
430+ {
431+ self->pam_handle_ = nullptr;
432+ self->source_manager_.AddTimeout(0, [self] { self->start_failed.emit(); return false; });
433+ return nullptr;
434+ }
435+
436+ self->status_ = pam_authenticate(self->pam_handle_, 0);
437+
438+ if (self->status_ == PAM_SUCCESS)
439+ {
440+ int status2 = pam_acct_mgmt(self->pam_handle_, 0);
441+
442+ if (status2 == PAM_NEW_AUTHTOK_REQD)
443+ status2 = pam_chauthtok(self->pam_handle_, PAM_CHANGE_EXPIRED_AUTHTOK);
444+
445+ if (unity::Settings::Instance().pam_check_account_type())
446+ self->status_ = status2;
447+
448+ pam_setcred(self->pam_handle_, PAM_REINITIALIZE_CRED);
449+ }
450+
451+ pam_end(self->pam_handle_, self->status_);
452+ self->pam_handle_ = nullptr;
453+ self->source_manager_.AddTimeout(0, [self] { self->authenticate_cb_(self->status_ == PAM_SUCCESS); return false; });
454+ return nullptr;
455 }
456
457 bool UserAuthenticatorPam::InitPam()
458
459=== modified file 'lockscreen/UserAuthenticatorPam.h'
460--- lockscreen/UserAuthenticatorPam.h 2014-03-05 04:09:13 +0000
461+++ lockscreen/UserAuthenticatorPam.h 2017-09-19 17:57:43 +0000
462@@ -20,8 +20,6 @@
463 #ifndef UNITY_USER_AUTHENTICATOR_PAM_H
464 #define UNITY_USER_AUTHENTICATOR_PAM_H
465
466-#include <boost/noncopyable.hpp>
467-#include <UnityCore/GLibWrapper.h>
468 #include <UnityCore/GLibSource.h>
469
470 #include "UserAuthenticator.h"
471@@ -36,13 +34,17 @@
472 namespace lockscreen
473 {
474
475-class UserAuthenticatorPam : public UserAuthenticator, private boost::noncopyable
476+class UserAuthenticatorPam : public UserAuthenticator
477 {
478 public:
479+ UserAuthenticatorPam() = default;
480 bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;
481
482 private:
483- // TODO (andy) move to pimpl
484+ UserAuthenticatorPam(UserAuthenticatorPam const&) = delete;
485+ UserAuthenticatorPam& operator=(UserAuthenticatorPam const&) = delete;
486+
487+ static gpointer AuthenticationThreadFunc(gpointer);
488 bool InitPam();
489
490 static int ConversationFunction(int num_msg,
491@@ -53,10 +55,9 @@
492 std::string username_;
493 AuthenticateEndCallback authenticate_cb_;
494
495- int status_;
496- bool first_prompt_;
497- pam_handle* pam_handle_;
498- glib::Cancellable cancellable_;
499+ int status_ = 0;
500+ bool first_prompt_ = true;
501+ pam_handle* pam_handle_ = nullptr;
502 glib::SourceManager source_manager_;
503 };
504
505
506=== modified file 'lockscreen/UserPromptView.cpp'
507--- lockscreen/UserPromptView.cpp 2016-06-23 14:51:42 +0000
508+++ lockscreen/UserPromptView.cpp 2017-09-19 17:57:43 +0000
509@@ -23,6 +23,7 @@
510 #include <glib/gi18n-lib.h>
511
512 #include <boost/algorithm/string/trim.hpp>
513+#include <NuxCore/Logger.h>
514 #include <Nux/VLayout.h>
515
516 #include "LockScreenSettings.h"
517@@ -38,6 +39,9 @@
518 {
519 namespace
520 {
521+
522+DECLARE_LOGGER(logger, "unity.lockscreen");
523+
524 const RawPixel PADDING = 10_em;
525 const RawPixel LAYOUT_MARGIN = 10_em;
526 const RawPixel MSG_LAYOUT_MARGIN = 15_em;
527@@ -101,41 +105,46 @@
528
529 }
530
531-UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
532- : AbstractUserPromptView(session_manager)
533- , session_manager_(session_manager)
534+UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager,
535+ UserAuthenticator::Ptr const& user_authenticator)
536+ : AbstractUserPromptView(session_manager, user_authenticator)
537 , username_(nullptr)
538 , msg_layout_(nullptr)
539 , prompt_layout_(nullptr)
540 , button_layout_(nullptr)
541 , prompted_(false)
542 , unacknowledged_messages_(false)
543+ , num_retry_auth_(0)
544 {
545- user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
546+ user_authenticator_->start_failed.connect(sigc::track_obj([this](){
547+ HandleAuthenticationStartFailure();
548+ }, *this));
549+
550+ user_authenticator_->echo_on_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
551 prompted_ = true;
552 unacknowledged_messages_ = false;
553 AddPrompt(message, /* visible */ true, promise);
554- });
555+ }, *this));
556
557- user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
558+ user_authenticator_->echo_off_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
559 prompted_ = true;
560 unacknowledged_messages_ = false;
561 AddPrompt(message, /* visible */ false, promise);
562- });
563+ }, *this));
564
565- user_authenticator_.message_requested.connect([this](std::string const& message){
566+ user_authenticator_->message_requested.connect(sigc::track_obj([this](std::string const& message){
567 unacknowledged_messages_ = true;
568 AddMessage(message, nux::color::White);
569- });
570+ }, *this));
571
572- user_authenticator_.error_requested.connect([this](std::string const& message){
573+ user_authenticator_->error_requested.connect(sigc::track_obj([this](std::string const& message){
574 unacknowledged_messages_ = true;
575 AddMessage(message, nux::color::Red);
576- });
577+ }, *this));
578
579- user_authenticator_.clear_prompts.connect([this](){
580+ user_authenticator_->clear_prompts.connect(sigc::track_obj([this](){
581 ResetLayout();
582- });
583+ }, *this));
584
585 scale.changed.connect(sigc::hide(sigc::mem_fun(this, &UserPromptView::UpdateSize)));
586
587@@ -469,8 +478,11 @@
588 prompted_ = false;
589 unacknowledged_messages_ = false;
590
591- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
592- sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
593+ if(!user_authenticator_->AuthenticateStart(session_manager_->UserName(),
594+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb)))
595+ {
596+ HandleAuthenticationStartFailure();
597+ }
598 }
599
600 void UserPromptView::DoUnlock()
601@@ -478,5 +490,29 @@
602 session_manager_->unlock_requested.emit();
603 }
604
605+void UserPromptView::HandleAuthenticationStartFailure()
606+{
607+ ++num_retry_auth_;
608+
609+ if (num_retry_auth_ <= 5)
610+ {
611+ LOG_WARNING(logger) << "Failed to start the authentication process. Retrying for " << num_retry_auth_ << " time.";
612+ source_manager_.AddTimeout(100, [this] {
613+ StartAuthentication();
614+ return false;
615+ });
616+ }
617+ else
618+ {
619+ num_retry_auth_ = 0;
620+
621+ AddMessage(_("Authentication failure"), nux::color::Red);
622+ AddButton(_("Switch to greeter…"), [this] {
623+ session_manager_->SwitchToGreeter();
624+ });
625+ GetLayout()->AddLayout(button_layout_);
626+ }
627+}
628+
629 }
630 }
631
632=== modified file 'lockscreen/UserPromptView.h'
633--- lockscreen/UserPromptView.h 2016-06-23 14:51:42 +0000
634+++ lockscreen/UserPromptView.h 2017-09-19 17:57:43 +0000
635@@ -25,10 +25,10 @@
636
637 #include <Nux/Nux.h>
638 #include <Nux/View.h>
639+#include "UnityCore/GLibSource.h"
640 #include "UnityCore/SessionManager.h"
641
642 #include "LockScreenAbstractPromptView.h"
643-#include "UserAuthenticatorPam.h"
644 #include "unity-shared/IMTextEntry.h"
645
646 namespace nux
647@@ -48,7 +48,8 @@
648 class UserPromptView : public AbstractUserPromptView
649 {
650 public:
651- UserPromptView(session::Manager::Ptr const& session_manager);
652+ UserPromptView(session::Manager::Ptr const& session_manager,
653+ UserAuthenticator::Ptr const& user_authenticator);
654
655 nux::View* focus_view();
656
657@@ -70,9 +71,8 @@
658 void ShowAuthenticated(bool successful);
659 void StartAuthentication();
660 void DoUnlock();
661+ void HandleAuthenticationStartFailure();
662
663- session::Manager::Ptr session_manager_;
664- UserAuthenticatorPam user_authenticator_;
665 std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
666 StaticCairoText* username_;
667 nux::VLayout* msg_layout_;
668@@ -84,6 +84,9 @@
669
670 bool prompted_;
671 bool unacknowledged_messages_;
672+ int num_retry_auth_ = 0;
673+
674+ glib::SourceManager source_manager_;
675 };
676
677 }
678
679=== modified file 'plugins/unityshell/src/unityshell.cpp'
680--- plugins/unityshell/src/unityshell.cpp 2017-07-17 10:53:40 +0000
681+++ plugins/unityshell/src/unityshell.cpp 2017-09-19 17:57:43 +0000
682@@ -1496,6 +1496,13 @@
683 CompOutput* output,
684 unsigned int mask)
685 {
686+ if (G_UNLIKELY(lockscreen_controller_->IsPaintInhibited()))
687+ {
688+ CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
689+ CHECKGL(glClear(GL_COLOR_BUFFER_BIT));
690+ return true;
691+ }
692+
693 bool ret;
694
695 /*
696@@ -1692,6 +1699,11 @@
697
698 void UnityScreen::donePaint()
699 {
700+ if (G_UNLIKELY(lockscreen_controller_->IsPaintInhibited()))
701+ {
702+ lockscreen_controller_->MarkBufferHasCleared();
703+ }
704+
705 /*
706 * It's only safe to clear the draw list if drawing actually occurred
707 * (i.e. the shell was not obscured behind a fullscreen window).