Merge lp:~azzar1/unity/lockscreen-warning-after-authentication into lp:unity

Proposed by Andrea Azzarone on 2016-06-23
Status: Merged
Approved by: Marco Trevisan (Treviño) on 2016-06-23
Approved revision: 4134
Merged at revision: 4134
Proposed branch: lp:~azzar1/unity/lockscreen-warning-after-authentication
Merge into: lp:unity
Prerequisite: lp:~azzar1/unity/option-lockscreen-account-checking
Diff against target: 589 lines (+385/-14)
7 files modified
lockscreen/CMakeLists.txt (+1/-0)
lockscreen/LockScreenButton.cpp (+148/-0)
lockscreen/LockScreenButton.h (+70/-0)
lockscreen/UserPromptView.cpp (+113/-13)
lockscreen/UserPromptView.h (+9/-1)
unity-shared/DashStyle.cpp (+39/-0)
unity-shared/DashStyle.h (+5/-0)
To merge this branch: bzr merge lp:~azzar1/unity/lockscreen-warning-after-authentication
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) 2016-06-23 Approve on 2016-06-23
PS Jenkins bot continuous-integration Pending
Review via email: mp+298232@code.launchpad.net

Commit message

Lockscreen: Make sure warning and errors are properly shown to the user

To post a comment you must log in.
4134. By Andrea Azzarone on 2016-06-23

Fix style.

Marco Trevisan (Treviño) (3v1n0) wrote :

Good stuff, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lockscreen/CMakeLists.txt'
2--- lockscreen/CMakeLists.txt 2016-03-31 09:59:30 +0000
3+++ lockscreen/CMakeLists.txt 2016-06-23 14:53:05 +0000
4@@ -23,6 +23,7 @@
5 KylinLockScreenShield.cpp
6 LockScreenController.cpp
7 LockScreenBaseShield.cpp
8+ LockScreenButton.cpp
9 LockScreenSettings.cpp
10 LockScreenShield.cpp
11 LockScreenShieldFactory.cpp
12
13=== added file 'lockscreen/LockScreenButton.cpp'
14--- lockscreen/LockScreenButton.cpp 1970-01-01 00:00:00 +0000
15+++ lockscreen/LockScreenButton.cpp 2016-06-23 14:53:05 +0000
16@@ -0,0 +1,148 @@
17+/*
18+ * Copyright 2016 Canonical Ltd.
19+ *
20+ * This program is free software: you can redistribute it and/or modify it
21+ * under the terms of the GNU Lesser General Public License version 3, as
22+ * published by the Free Software Foundation.
23+ *
24+ * This program is distributed in the hope that it will be useful, but
25+ * WITHOUT ANY WARRANTY; without even the implied warranties of
26+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
27+ * PURPOSE. See the applicable version of the GNU Lesser General Public
28+ * License for more details.
29+ *
30+ * You should have received a copy of both the GNU Lesser General Public
31+ * License version 3 along with this program. If not, see
32+ * <http://www.gnu.org/licenses/>
33+ *
34+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
35+ *
36+ */
37+
38+#include "LockScreenButton.h"
39+
40+#include <Nux/HLayout.h>
41+
42+#include "unity-shared/DashStyle.h"
43+#include "unity-shared/IconTexture.h"
44+#include "LockScreenSettings.h"
45+
46+namespace unity
47+{
48+namespace lockscreen
49+{
50+
51+namespace
52+{
53+const RawPixel HLAYOUT_RIGHT_PADDING = 10_em;
54+const int FONT_PX_SIZE = 17;
55+}
56+
57+NUX_IMPLEMENT_OBJECT_TYPE(LockScreenButton);
58+
59+LockScreenButton::LockScreenButton(std::string const& label, NUX_FILE_LINE_DECL)
60+ : nux::Button(NUX_FILE_LINE_PARAM)
61+ , scale(1.0)
62+ , label_(label)
63+{
64+ hlayout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
65+ hlayout_->SetLeftAndRightPadding(0, HLAYOUT_RIGHT_PADDING.CP(scale));
66+ hlayout_->SetContentDistribution(nux::MAJOR_POSITION_END);
67+ SetLayout(hlayout_);
68+
69+ activator_ = new IconTexture(dash::Style::Instance().GetLockScreenActivator(scale()));
70+ hlayout_->AddView(activator_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
71+
72+ InitTheme();
73+
74+ scale.changed.connect([this] (double scale) {
75+ activator_->SetTexture(dash::Style::Instance().GetLockScreenActivator(scale));
76+ hlayout_->SetLeftAndRightPadding(0, HLAYOUT_RIGHT_PADDING.CP(scale));
77+ InitTheme();
78+ });
79+
80+ key_down.connect([this] (unsigned long, unsigned long, unsigned long, const char*, unsigned short) {
81+ state_change.emit(this);
82+ });
83+}
84+
85+void LockScreenButton::InitTheme()
86+{
87+ SetMinimumHeight(Settings::GRID_SIZE.CP(scale));
88+ SetMaximumHeight(Settings::GRID_SIZE.CP(scale));
89+
90+ nux::Geometry const& geo = GetGeometry();
91+ normal_.reset(new nux::CairoWrapper(geo, sigc::mem_fun(this, &LockScreenButton::RedrawTheme)));
92+}
93+
94+void LockScreenButton::RedrawTheme(nux::Geometry const& geom, cairo_t* cr)
95+{
96+ cairo_surface_set_device_scale(cairo_get_target(cr), scale, scale);
97+ dash::Style::Instance().LockScreenButton(cr, label_, FONT_PX_SIZE);
98+}
99+
100+long LockScreenButton::ComputeContentSize()
101+{
102+ long ret = nux::Button::ComputeContentSize();
103+ nux::Geometry const& geo = GetGeometry();
104+
105+ if (cached_geometry_ != geo)
106+ {
107+ normal_->Invalidate(geo);
108+ cached_geometry_ = geo;
109+ }
110+
111+ return ret;
112+}
113+
114+void LockScreenButton::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
115+{
116+ if (IsFullRedraw())
117+ {
118+ GfxContext.PushClippingRectangle(GetGeometry());
119+ hlayout_->ProcessDraw(GfxContext, force_draw);
120+ GfxContext.PopClippingRectangle();
121+ }
122+}
123+
124+void LockScreenButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
125+{
126+ nux::Geometry const& geo = GetGeometry();
127+ GfxContext.PushClippingRectangle(geo);
128+ gPainter.PaintBackground(GfxContext, geo);
129+
130+ nux::TexCoordXForm texxform;
131+ texxform.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP);
132+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
133+
134+ unsigned int alpha = 0, src = 0, dest = 0;
135+ GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
136+ GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
137+ GfxContext.GetRenderStates().SetBlend(true);
138+
139+ nux::Color col(nux::color::Black);
140+ col.alpha = 0;
141+ GfxContext.QRP_Color(geo.x, geo.y,
142+ geo.width, geo.height,
143+ col);
144+
145+ nux::BaseTexture* texture = normal_->GetTexture();
146+ GfxContext.QRP_1Tex(geo.x, geo.y,
147+ texture->GetWidth(), texture->GetHeight(),
148+ texture->GetDeviceTexture(),
149+ texxform, nux::color::White);
150+
151+ GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
152+ GfxContext.PopClippingRectangle();
153+}
154+
155+bool LockScreenButton::InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character)
156+{
157+ if ((eventType == nux::NUX_KEYDOWN) && (key_sym == NUX_VK_ENTER))
158+ return true;
159+ else
160+ return false;
161+}
162+
163+} // namespace lockscreen
164+} // namespace unity
165\ No newline at end of file
166
167=== added file 'lockscreen/LockScreenButton.h'
168--- lockscreen/LockScreenButton.h 1970-01-01 00:00:00 +0000
169+++ lockscreen/LockScreenButton.h 2016-06-23 14:53:05 +0000
170@@ -0,0 +1,70 @@
171+/*
172+ * Copyright 2016 Canonical Ltd.
173+ *
174+ * This program is free software: you can redistribute it and/or modify it
175+ * under the terms of the GNU Lesser General Public License version 3, as
176+ * published by the Free Software Foundation.
177+ *
178+ * This program is distributed in the hope that it will be useful, but
179+ * WITHOUT ANY WARRANTY; without even the implied warranties of
180+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
181+ * PURPOSE. See the applicable version of the GNU Lesser General Public
182+ * License for more details.
183+ *
184+ * You should have received a copy of both the GNU Lesser General Public
185+ * License version 3 along with this program. If not, see
186+ * <http://www.gnu.org/licenses/>
187+ *
188+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
189+ *
190+ */
191+
192+#ifndef UNITY_LOCKSCREEN_BUTTON_H
193+#define UNITY_LOCKSCREEN_BUTTON_H
194+
195+#include <Nux/Nux.h>
196+#include <Nux/Button.h>
197+#include <Nux/CairoWrapper.h>
198+
199+namespace unity
200+{
201+
202+class IconTexture;
203+
204+namespace lockscreen
205+{
206+
207+class LockScreenButton : public nux::Button
208+{
209+ NUX_DECLARE_OBJECT_TYPE(LockScreenButton, nux::Button);
210+
211+public:
212+ LockScreenButton(std::string const&, NUX_FILE_LINE_PROTO);
213+
214+ nux::Property<double> scale;
215+
216+protected:
217+ long ComputeContentSize() override;
218+ void Draw(nux::GraphicsEngine&, bool) override;
219+ void DrawContent(nux::GraphicsEngine&, bool) override;
220+ bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character) override;
221+
222+private:
223+ void InitTheme();
224+ void RedrawTheme(nux::Geometry const&, cairo_t*);
225+
226+ typedef std::unique_ptr<nux::CairoWrapper> NuxCairoPtr;
227+
228+ std::string label_;
229+ nux::Geometry cached_geometry_;
230+
231+ NuxCairoPtr normal_;
232+
233+ nux::HLayout* hlayout_;
234+ IconTexture* activator_;
235+};
236+
237+} // namespace lockscreen
238+} // namespace unity
239+
240+#endif
241
242=== modified file 'lockscreen/UserPromptView.cpp'
243--- lockscreen/UserPromptView.cpp 2016-03-16 10:47:16 +0000
244+++ lockscreen/UserPromptView.cpp 2016-06-23 14:53:05 +0000
245@@ -26,6 +26,7 @@
246 #include <Nux/VLayout.h>
247
248 #include "LockScreenSettings.h"
249+#include "LockScreenButton.h"
250 #include "unity-shared/CairoTexture.h"
251 #include "unity-shared/TextInput.h"
252 #include "unity-shared/StaticCairoText.h"
253@@ -41,6 +42,7 @@
254 const RawPixel LAYOUT_MARGIN = 10_em;
255 const RawPixel MSG_LAYOUT_MARGIN = 15_em;
256 const RawPixel PROMPT_LAYOUT_MARGIN = 5_em;
257+const RawPixel BUTTON_LAYOUT_MARGIN = 5_em;
258 const int PROMPT_FONT_SIZE = 13;
259
260 nux::AbstractPaintLayer* CrateBackgroundLayer(double width, double height, double scale)
261@@ -105,20 +107,29 @@
262 , username_(nullptr)
263 , msg_layout_(nullptr)
264 , prompt_layout_(nullptr)
265+ , button_layout_(nullptr)
266+ , prompted_(false)
267+ , unacknowledged_messages_(false)
268 {
269 user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
270+ prompted_ = true;
271+ unacknowledged_messages_ = false;
272 AddPrompt(message, /* visible */ true, promise);
273 });
274
275 user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
276+ prompted_ = true;
277+ unacknowledged_messages_ = false;
278 AddPrompt(message, /* visible */ false, promise);
279 });
280
281 user_authenticator_.message_requested.connect([this](std::string const& message){
282+ unacknowledged_messages_ = true;
283 AddMessage(message, nux::color::White);
284 });
285
286 user_authenticator_.error_requested.connect([this](std::string const& message){
287+ unacknowledged_messages_ = true;
288 AddMessage(message, nux::color::Red);
289 });
290
291@@ -131,8 +142,7 @@
292 UpdateSize();
293 ResetLayout();
294
295- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
296- sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
297+ StartAuthentication();
298 }
299
300 void UserPromptView::UpdateSize()
301@@ -178,6 +188,19 @@
302 }
303 }
304
305+ if (button_layout_)
306+ {
307+ button_layout_->SetVerticalInternalMargin(BUTTON_LAYOUT_MARGIN.CP(scale));
308+
309+ for (auto* area : button_layout_->GetChildren())
310+ {
311+ auto* button = static_cast<LockScreenButton*>(area);
312+ button->SetMinimumHeight(Settings::GRID_SIZE.CP(scale));
313+ button->SetMaximumHeight(Settings::GRID_SIZE.CP(scale));
314+ button->scale = scale();
315+ }
316+ }
317+
318 bg_layer_.reset();
319
320 ComputeContentSize();
321@@ -200,8 +223,13 @@
322
323 void UserPromptView::ResetLayout()
324 {
325+ bool keep_msg_layout = msg_layout_ && (!prompted_ || unacknowledged_messages_);
326+
327 focus_queue_.clear();
328
329+ if (keep_msg_layout)
330+ msg_layout_->Reference();
331+
332 SetLayout(new nux::VLayout());
333
334 GetLayout()->SetLeftAndRightPadding(PADDING.CP(scale));
335@@ -216,34 +244,54 @@
336 username_->SetFont("Ubuntu "+std::to_string(PROMPT_FONT_SIZE));
337 GetLayout()->AddView(username_);
338
339- msg_layout_ = new nux::VLayout();
340- msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN.CP(scale));
341- msg_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
342+ if (!keep_msg_layout)
343+ {
344+ msg_layout_ = new nux::VLayout();
345+ msg_layout_->SetVerticalInternalMargin(MSG_LAYOUT_MARGIN.CP(scale));
346+ msg_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
347+ }
348+
349 GetLayout()->AddLayout(msg_layout_);
350
351+ if (keep_msg_layout)
352+ msg_layout_->UnReference();
353+
354 prompt_layout_ = new nux::VLayout();
355 prompt_layout_->SetVerticalInternalMargin(PROMPT_LAYOUT_MARGIN.CP(scale));
356 prompt_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
357 GetLayout()->AddLayout(prompt_layout_);
358
359+ button_layout_ = new nux::VLayout();
360+ button_layout_->SetVerticalInternalMargin(BUTTON_LAYOUT_MARGIN.CP(scale));
361+ button_layout_->SetReconfigureParentLayoutOnGeometryChange(true);
362+
363 QueueRelayout();
364 QueueDraw();
365 }
366
367-void UserPromptView::AuthenticationCb(bool authenticated)
368+void UserPromptView::AuthenticationCb(bool is_authenticated)
369 {
370 ResetLayout();
371
372- if (authenticated)
373+ if (is_authenticated)
374 {
375- session_manager_->unlock_requested.emit();
376+ if (prompted_ && !unacknowledged_messages_)
377+ DoUnlock();
378+ else
379+ ShowAuthenticated(true);
380 }
381 else
382 {
383- AddMessage(_("Invalid password, please try again"), nux::color::Red);
384-
385- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
386- sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
387+ if (prompted_)
388+ {
389+ AddMessage(_("Invalid password, please try again"), nux::color::Red);
390+ StartAuthentication();
391+ }
392+ else
393+ {
394+ AddMessage(_("Failed to authenticate"), nux::color::Red);
395+ ShowAuthenticated(false);
396+ }
397 }
398 }
399
400@@ -299,7 +347,16 @@
401 nux::View* UserPromptView::focus_view()
402 {
403 if (focus_queue_.empty())
404- return nullptr;
405+ {
406+ if (button_layout_ && button_layout_->GetChildren().size() > 0)
407+ {
408+ return static_cast<nux::View*>(button_layout_->GetChildren().front());
409+ }
410+ else
411+ {
412+ return nullptr;
413+ }
414+ }
415
416 for (auto* view : focus_queue_)
417 if (view->text_entry()->HasKeyboardFocus())
418@@ -378,5 +435,48 @@
419 QueueDraw();
420 }
421
422+void UserPromptView::AddButton(std::string const& text, std::function<void()> const& cb)
423+{
424+ auto* button = new LockScreenButton (text, NUX_TRACKER_LOCATION);
425+ button->scale = scale();
426+ button_layout_->AddView(button, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL);
427+
428+ button->state_change.connect ([cb] (nux::View*) {
429+ cb();
430+ });
431+
432+ GetLayout()->ComputeContentPosition(0, 0);
433+ ComputeContentSize();
434+ QueueRelayout();
435+ QueueDraw();
436+}
437+
438+void UserPromptView::ShowAuthenticated(bool successful)
439+{
440+ prompted_ = true;
441+ unacknowledged_messages_ = false;
442+
443+ if (successful)
444+ AddButton(_("Unlock"), sigc::mem_fun(this, &UserPromptView::DoUnlock));
445+ else
446+ AddButton(_("Retry"), sigc::mem_fun(this, &UserPromptView::StartAuthentication));
447+
448+ GetLayout()->AddLayout(button_layout_);
449+}
450+
451+void UserPromptView::StartAuthentication()
452+{
453+ prompted_ = false;
454+ unacknowledged_messages_ = false;
455+
456+ user_authenticator_.AuthenticateStart(session_manager_->UserName(),
457+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
458+}
459+
460+void UserPromptView::DoUnlock()
461+{
462+ session_manager_->unlock_requested.emit();
463+}
464+
465 }
466 }
467
468=== modified file 'lockscreen/UserPromptView.h'
469--- lockscreen/UserPromptView.h 2016-03-31 09:51:33 +0000
470+++ lockscreen/UserPromptView.h 2016-06-23 14:53:05 +0000
471@@ -52,6 +52,7 @@
472
473 nux::View* focus_view();
474
475+ void AddButton(std::string const& text, std::function<void()> const& cb);
476 void AddPrompt(std::string const& message, bool visible, PromiseAuthCodePtr const&);
477 void AddMessage(std::string const& message, nux::Color const& color);
478 void AuthenticationCb(bool authenticated);
479@@ -59,13 +60,16 @@
480 protected:
481 void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
482 void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) override;
483+ bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character) override;
484
485 private:
486 void ResetLayout();
487 void UpdateSize();
488 void EnsureBGLayer();
489
490- bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
491+ void ShowAuthenticated(bool successful);
492+ void StartAuthentication();
493+ void DoUnlock();
494
495 session::Manager::Ptr session_manager_;
496 UserAuthenticatorPam user_authenticator_;
497@@ -73,9 +77,13 @@
498 StaticCairoText* username_;
499 nux::VLayout* msg_layout_;
500 nux::VLayout* prompt_layout_;
501+ nux::VLayout* button_layout_;
502 std::deque<TextInput*> focus_queue_;
503
504 nux::Geometry cached_focused_geo_;
505+
506+ bool prompted_;
507+ bool unacknowledged_messages_;
508 };
509
510 }
511
512=== modified file 'unity-shared/DashStyle.cpp'
513--- unity-shared/DashStyle.cpp 2016-05-10 16:07:03 +0000
514+++ unity-shared/DashStyle.cpp 2016-06-23 14:53:05 +0000
515@@ -1672,6 +1672,41 @@
516 return true;
517 }
518
519+bool Style::LockScreenButton(cairo_t* cr, std::string const& label,
520+ int font_px_size)
521+{
522+ if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
523+ return false;
524+
525+ if (cairo_surface_get_type(cairo_get_target(cr)) != CAIRO_SURFACE_TYPE_IMAGE)
526+ return false;
527+
528+ double w, h;
529+ get_actual_cairo_size(cr, &w, &h);
530+
531+ cairo_set_line_width(cr, 1);
532+
533+ double radius = 5.0;
534+ RoundedRect(cr, 1.0, 0.5, 0.5, radius, w - 1.0, h - 1.0);
535+
536+ cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.35f);
537+ cairo_fill_preserve(cr);
538+
539+ cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.7f);
540+ cairo_stroke(cr);
541+
542+ static double internal_padding = 10.0f;
543+
544+ pimpl->Text(cr,
545+ nux::color::White,
546+ label,
547+ font_px_size,
548+ internal_padding,
549+ dash::Alignment::LEFT);
550+
551+ return true;
552+}
553+
554 nux::AbstractPaintLayer* Style::FocusOverlay(int width, int height)
555 {
556 nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
557@@ -2211,6 +2246,10 @@
558 return pimpl->LoadScaledTexture("search_spin", scale);
559 }
560
561+BaseTexturePtr Style::GetLockScreenActivator(double scale) const
562+{
563+ return pimpl->LoadScaledTexture("arrow_right", scale);
564+}
565
566 RawPixel Style::GetButtonGarnishSize() const
567 {
568
569=== modified file 'unity-shared/DashStyle.h'
570--- unity-shared/DashStyle.h 2016-03-31 05:53:05 +0000
571+++ unity-shared/DashStyle.h 2016-06-23 14:53:05 +0000
572@@ -98,6 +98,9 @@
573
574 static Style& Instance();
575
576+ virtual bool LockScreenButton(cairo_t* cr, std::string const& label,
577+ int font_px_size);
578+
579 virtual bool Button(cairo_t* cr, nux::ButtonVisualState state,
580 std::string const& label, int font_px_size=-1,
581 Alignment alignment = Alignment::CENTER,
582@@ -196,6 +199,8 @@
583 BaseTexturePtr GetSearchCloseIcon(double scale) const;
584 BaseTexturePtr GetSearchSpinIcon(double scale) const;
585
586+ BaseTexturePtr GetLockScreenActivator(double scale) const;
587+
588 BaseTexturePtr const& GetGroupUnexpandIcon() const;
589 BaseTexturePtr const& GetGroupExpandIcon() const;
590