summaryrefslogtreecommitdiff
diff options
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2017-10-02 14:04:05 -0400
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2017-10-02 14:04:05 -0400
commit9d83ef73448c092d425b2e622ec2f3be079cbe7d (patch)
tree9c5ac546d871439f4fe48a37a4c882cf2c2c7c82
parent2424475c6a3ed4b7a5ecfbde7ce6862e6108dd74 (diff)
parentde253aa81d99d81ec240dd99c99cfe7bb307cdf1 (diff)
Merging with trunk
(bzr r4253.4.3)
-rw-r--r--debian/changelog16
-rwxr-xr-xdebian/rules20
-rw-r--r--lockscreen/KylinUserPromptView.cpp30
-rw-r--r--lockscreen/KylinUserPromptView.h5
-rw-r--r--lockscreen/LockScreenAbstractPromptView.h8
-rw-r--r--lockscreen/LockScreenController.cpp44
-rw-r--r--lockscreen/LockScreenController.h9
-rw-r--r--lockscreen/LockScreenPromptFactory.cpp7
-rw-r--r--lockscreen/LockScreenPromptFactory.h4
-rw-r--r--lockscreen/SuspendInhibitorManager.cpp2
-rw-r--r--lockscreen/SuspendInhibitorManager.h1
-rw-r--r--lockscreen/UserAuthenticator.h2
-rw-r--r--lockscreen/UserAuthenticatorPam.cpp54
-rw-r--r--lockscreen/UserAuthenticatorPam.h17
-rw-r--r--lockscreen/UserPromptView.cpp66
-rw-r--r--lockscreen/UserPromptView.h11
-rw-r--r--plugins/unityshell/src/unityshell.cpp12
-rw-r--r--tests/test_icon_loader.cpp6
18 files changed, 225 insertions, 89 deletions
diff --git a/debian/changelog b/debian/changelog
index 7388884e3..cf9b93892 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,19 @@
+unity (7.5.0+17.10.20170925.1-0ubuntu1) artful; urgency=medium
+
+ [ Andrea Azzarone ]
+ * Fix build issues with gcc-7 and g++-7
+ * Refactor the way UserAuthenticator is created and passed around.
+ Handle failures to create new threads and fallback to a "Switch to
+ greeter..." button in case of failure. (LP: #1311316)
+ * Wait until the color buffer is cleared before suspending. (LP:
+ #1532508)
+
+ [ Marco Trevisan (Treviño) ]
+ * Tests: split unit tests in single binaries, enable unstable tests
+ * debian/rules: ignore warnings in armhf and ppc64el
+
+ -- Marco Trevisan (Treviño) <mail@3v1n0.net> Mon, 25 Sep 2017 16:05:06 +0000
+
unity (7.5.0+17.10.20170721.1-0ubuntu1) artful; urgency=medium
* GLibSignal: allow to block, unblock signals
diff --git a/debian/rules b/debian/rules
index 5f4d89837..fea379dda 100755
--- a/debian/rules
+++ b/debian/rules
@@ -6,15 +6,10 @@
DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
gles2_architectures := armel armhf
+ignore_warnings_archs := armhf ppc64el s390x
DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ')
-# avoid template instance removal (lp:1286284)
-ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), ppc64el))
- export DEB_CXXFLAGS_MAINT_STRIP=-O3
- export DEB_CXXFLAGS_MAINT_APPEND=-O2
-endif
-
# http://ccache.samba.org/manual.html#_precompiled_headers
CCACHE_SLOPPINESS=time_macros
@@ -23,13 +18,20 @@ NUX_ABIVERSION := $(shell sed -rn 's/^\#define[[:space:]]+NUX_ABIVERSION[[:space
LIBUNITY_PRIVATE := $(shell pkg-config --libs-only-L unity-protocol-private | sed -e 's/-L\(.*\)/\1/' )
SCOPES_RECOMMENDS := $(shell perl debian/scopes-recommends-generator /usr/share/unity/client-scopes.json)
-cmake_base_options := -DUSE_GSETTINGS=TRUE -DCOMPIZ_BUILD_WITH_RPATH=FALSE -DCOMPIZ_PACKAGING_ENABLED=TRUE -DCOMPIZ_PLUGIN_INSTALL_TYPE=package
+cmake_options := -DCOMPIZ_BUILD_WITH_RPATH=FALSE \
+ -DCOMPIZ_PACKAGING_ENABLED=TRUE \
+ -DCOMPIZ_PLUGIN_INSTALL_TYPE=package
+
ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), $(gles2_architectures)))
- cmake_gl_options := -DBUILD_GLES=TRUE -DDISABLE_MAINTAINER_CFLAGS=ON
+ cmake_options += -DBUILD_GLES=TRUE -DDISABLE_MAINTAINER_CXXFLAGS=ON
+endif
+
+ifeq ($(DEB_HOST_ARCH),$(findstring $(DEB_HOST_ARCH), $(ignore_warnings_archs)))
+ cmake_options += -DDISABLE_MAINTAINER_CXXFLAGS=ON
endif
override_dh_auto_configure:
- dh_auto_configure -- $(cmake_base_options) $(cmake_gl_options) $(cmake_pch_options)
+ dh_auto_configure -- $(cmake_options)
override_dh_install:
# install autopilot tests
diff --git a/lockscreen/KylinUserPromptView.cpp b/lockscreen/KylinUserPromptView.cpp
index 138287c3b..c8c420ebe 100644
--- a/lockscreen/KylinUserPromptView.cpp
+++ b/lockscreen/KylinUserPromptView.cpp
@@ -79,9 +79,9 @@ std::string SanitizeMessage(std::string const& message)
}
-KylinUserPromptView::KylinUserPromptView(session::Manager::Ptr const& session_manager)
- : AbstractUserPromptView(session_manager)
- , session_manager_(session_manager)
+KylinUserPromptView::KylinUserPromptView(session::Manager::Ptr const& session_manager,
+ UserAuthenticator::Ptr const& user_authenticator)
+ : AbstractUserPromptView(session_manager, user_authenticator)
, username_(nullptr)
, msg_layout_(nullptr)
, prompt_layout_(nullptr)
@@ -90,25 +90,25 @@ KylinUserPromptView::KylinUserPromptView(session::Manager::Ptr const& session_ma
, avatar_(nullptr)
, avatar_icon_file("")
{
- user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
+ user_authenticator_->echo_on_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
AddPrompt(message, true, promise);
- });
+ }, *this));
- user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
+ user_authenticator_->echo_off_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
AddPrompt(message, false, promise);
- });
+ }, *this));
- user_authenticator_.message_requested.connect([this](std::string const& message){
+ user_authenticator_->message_requested.connect(sigc::track_obj([this](std::string const& message){
AddMessage(message, nux::color::White);
- });
+ }, *this));
- user_authenticator_.error_requested.connect([this](std::string const& message){
+ user_authenticator_->error_requested.connect(sigc::track_obj([this](std::string const& message){
AddMessage(message, nux::color::Red);
- });
+ }, *this));
- user_authenticator_.clear_prompts.connect([this](){
+ user_authenticator_->clear_prompts.connect(sigc::track_obj([this](){
ResetLayout();
- });
+ }, *this));
scale.changed.connect(sigc::hide(sigc::mem_fun(this, &KylinUserPromptView::UpdateSize)));
@@ -121,7 +121,7 @@ KylinUserPromptView::KylinUserPromptView(session::Manager::Ptr const& session_ma
ResetLayout();
TextureCache::GetDefault().themed_invalidated.connect(sigc::mem_fun(this, &KylinUserPromptView::ResetLayout));
- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
+ user_authenticator_->AuthenticateStart(session_manager_->UserName(),
sigc::mem_fun(this, &KylinUserPromptView::AuthenticationCb));
}
@@ -244,7 +244,7 @@ void KylinUserPromptView::AuthenticationCb(bool authenticated)
{
AddMessage(_("Invalid password, please try again"), nux::color::Red);
- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
+ user_authenticator_->AuthenticateStart(session_manager_->UserName(),
sigc::mem_fun(this, &KylinUserPromptView::AuthenticationCb));
}
}
diff --git a/lockscreen/KylinUserPromptView.h b/lockscreen/KylinUserPromptView.h
index 0c1d3730b..e0931d2d8 100644
--- a/lockscreen/KylinUserPromptView.h
+++ b/lockscreen/KylinUserPromptView.h
@@ -44,7 +44,8 @@ namespace lockscreen
class KylinUserPromptView : public AbstractUserPromptView
{
public:
- KylinUserPromptView(session::Manager::Ptr const& session_manager);
+ KylinUserPromptView(session::Manager::Ptr const& session_manager,
+ UserAuthenticator::Ptr const& user_authenticator);
nux::View* focus_view();
@@ -62,8 +63,6 @@ protected:
nux::ObjectPtr<nux::BaseTexture> LoadUserIcon(std::string const& icon_file, int icon_size);
private:
- session::Manager::Ptr session_manager_;
- UserAuthenticatorPam user_authenticator_;
StaticCairoText* username_;
nux::VLayout* msg_layout_;
nux::VLayout* prompt_layout_;
diff --git a/lockscreen/LockScreenAbstractPromptView.h b/lockscreen/LockScreenAbstractPromptView.h
index fdbbd8cdc..0339cb0a5 100644
--- a/lockscreen/LockScreenAbstractPromptView.h
+++ b/lockscreen/LockScreenAbstractPromptView.h
@@ -29,7 +29,7 @@
#include <Nux/VLayout.h>
#include "UnityCore/SessionManager.h"
-#include "UserAuthenticatorPam.h"
+#include "UserAuthenticator.h"
#include "unity-shared/IMTextEntry.h"
namespace nux
@@ -48,10 +48,12 @@ namespace lockscreen
class AbstractUserPromptView : public nux::View
{
public:
- AbstractUserPromptView(session::Manager::Ptr const& session_manager)
+ AbstractUserPromptView(session::Manager::Ptr const& session_manager,
+ UserAuthenticator::Ptr const& user_authenticator)
: nux::View(NUX_TRACKER_LOCATION)
, scale(1.0)
, session_manager_(session_manager)
+ , user_authenticator_(user_authenticator)
{}
nux::Property<double> scale;
@@ -64,7 +66,7 @@ public:
protected:
session::Manager::Ptr session_manager_;
- UserAuthenticatorPam user_authenticator_;
+ UserAuthenticator::Ptr user_authenticator_;
std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
StaticCairoText* username_;
nux::VLayout* msg_layout_;
diff --git a/lockscreen/LockScreenController.cpp b/lockscreen/LockScreenController.cpp
index 2ede0f7a7..8f6e7bc9b 100644
--- a/lockscreen/LockScreenController.cpp
+++ b/lockscreen/LockScreenController.cpp
@@ -27,6 +27,7 @@
#include "LockScreenPromptFactory.h"
#include "LockScreenShield.h"
#include "LockScreenSettings.h"
+#include "UserAuthenticatorPam.h"
#include "unity-shared/AnimationUtils.h"
#include "unity-shared/InputMonitor.h"
#include "unity-shared/UnitySettings.h"
@@ -70,10 +71,13 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
, upstart_wrapper_(upstart_wrapper)
, shield_factory_(shield_factory)
, suspend_inhibitor_manager_(std::make_shared<SuspendInhibitorManager>())
+ , user_authenticator_(std::make_shared<UserAuthenticatorPam>())
, fade_animator_(unity::Settings::Instance().low_gfx() ? 0 : LOCK_FADE_DURATION)
, blank_window_animator_(IDLE_FADE_DURATION)
, test_mode_(test_mode)
, prompt_activation_(false)
+ , is_paint_inhibited_(false)
+ , buffer_cleared_(true)
{
auto* uscreen = UScreen::GetDefault();
uscreen_connection_ = uscreen->changed.connect([this] (int, std::vector<nux::Geometry> const& monitors) {
@@ -91,7 +95,13 @@ Controller::Controller(DBusManager::Ptr const& dbus_manager,
suspend_inhibitor_manager_->connected.connect(sigc::mem_fun(this, &Controller::SyncInhibitor));
suspend_inhibitor_manager_->about_to_suspend.connect([this] () {
if (Settings::Instance().lock_on_suspend())
+ {
+ InhibitPaint();
session_manager_->PromptLockScreen();
+ }
+ });
+ suspend_inhibitor_manager_->resumed.connect([this] () {
+ UninhibitPaint();
});
Settings::Instance().lock_on_suspend.changed.connect(sigc::hide(sigc::mem_fun(this, &Controller::SyncInhibitor)));
@@ -259,7 +269,7 @@ void Controller::EnsureShields(std::vector<nux::Geometry> const& monitors)
if (!prompt_view)
{
- prompt_view = test_mode_ ? nux::ObjectPtr<AbstractUserPromptView>() : PromptFactory::CreatePrompt(session_manager_);
+ prompt_view = test_mode_ ? nux::ObjectPtr<AbstractUserPromptView>() : PromptFactory::CreatePrompt(session_manager_, user_authenticator_);
prompt_view_ = prompt_view.GetPointer();
}
@@ -554,6 +564,36 @@ bool Controller::HasOpenMenu() const
return primary_shield_.IsValid() ? primary_shield_->IsIndicatorOpen() : false;
}
+void Controller::InhibitPaint()
+{
+ buffer_cleared_ = false;
+ is_paint_inhibited_ = true;
+}
+
+void Controller::UninhibitPaint()
+{
+ if (!is_paint_inhibited_)
+ return;
+
+ buffer_cleared_ = true;
+ is_paint_inhibited_ = false;
+ SyncInhibitor();
+}
+
+bool Controller::IsPaintInhibited() const
+{
+ return is_paint_inhibited_;
+}
+
+void Controller::MarkBufferHasCleared()
+{
+ if (buffer_cleared_)
+ return;
+
+ buffer_cleared_ = true;
+ SyncInhibitor();
+}
+
void Controller::SyncInhibitor()
{
bool locked = IsLocked() && primary_shield_.IsValid() && primary_shield_->GetOpacity() == 1.0f;
@@ -564,7 +604,7 @@ void Controller::SyncInhibitor()
if (inhibit)
suspend_inhibitor_manager_->Inhibit("Unity needs to lock the screen");
- else
+ else if (buffer_cleared_)
suspend_inhibitor_manager_->Uninhibit();
}
diff --git a/lockscreen/LockScreenController.h b/lockscreen/LockScreenController.h
index f1b50426e..2b03de4fd 100644
--- a/lockscreen/LockScreenController.h
+++ b/lockscreen/LockScreenController.h
@@ -29,6 +29,7 @@
#include "LockScreenAcceleratorController.h"
#include "SuspendInhibitorManager.h"
#include "ScreenSaverDBusManager.h"
+#include "UserAuthenticator.h"
#include "unity-shared/BackgroundEffectHelper.h"
#include "unity-shared/SystemdWrapper.h"
#include "unity-shared/UpstartWrapper.h"
@@ -55,6 +56,8 @@ public:
bool IsLocked() const;
bool HasOpenMenu() const;
+ bool IsPaintInhibited() const;
+ void MarkBufferHasCleared();
private:
friend class TestLockScreenController;
@@ -81,6 +84,9 @@ private:
void OnLockScreenInputEvent(XEvent const&);
void OnBlankWindowInputEvent(XEvent const&);
+ void InhibitPaint();
+ void UninhibitPaint();
+
std::vector<nux::ObjectPtr<BaseShield>> shields_;
nux::ObjectWeakPtr<BaseShield> primary_shield_;
nux::ObjectWeakPtr<AbstractUserPromptView> prompt_view_;
@@ -95,6 +101,7 @@ private:
UpstartWrapper::Ptr upstart_wrapper_;
ShieldFactoryInterface::Ptr shield_factory_;
SuspendInhibitorManager::Ptr suspend_inhibitor_manager_;
+ UserAuthenticator::Ptr user_authenticator_;
nux::animation::AnimateValue<double> fade_animator_;
nux::animation::AnimateValue<double> blank_window_animator_;
@@ -102,6 +109,8 @@ private:
bool test_mode_;
bool prompt_activation_;
BlurType old_blur_type_;
+ bool is_paint_inhibited_;
+ bool buffer_cleared_;
connection::Wrapper uscreen_connection_;
connection::Wrapper hidden_window_connection_;
diff --git a/lockscreen/LockScreenPromptFactory.cpp b/lockscreen/LockScreenPromptFactory.cpp
index 02e39eb24..9693cf653 100644
--- a/lockscreen/LockScreenPromptFactory.cpp
+++ b/lockscreen/LockScreenPromptFactory.cpp
@@ -26,14 +26,15 @@ namespace unity
{
namespace lockscreen
{
-nux::ObjectPtr<AbstractUserPromptView> PromptFactory::CreatePrompt(session::Manager::Ptr const& sm)
+nux::ObjectPtr<AbstractUserPromptView> PromptFactory::CreatePrompt(session::Manager::Ptr const& sm,
+ UserAuthenticator::Ptr const& ua)
{
nux::ObjectPtr<AbstractUserPromptView> prompt;
if (unity::Settings::Instance().desktop_type() == DesktopType::UBUNTUKYLIN)
- prompt = new KylinUserPromptView(sm);
+ prompt = new KylinUserPromptView(sm, ua);
else
- prompt = new UserPromptView(sm);
+ prompt = new UserPromptView(sm, ua);
return prompt;
}
diff --git a/lockscreen/LockScreenPromptFactory.h b/lockscreen/LockScreenPromptFactory.h
index 5fa9b81ad..72f8f87ed 100644
--- a/lockscreen/LockScreenPromptFactory.h
+++ b/lockscreen/LockScreenPromptFactory.h
@@ -22,6 +22,7 @@
#include <NuxCore/NuxCore.h>
#include "UnityCore/SessionManager.h"
+#include "UserAuthenticator.h"
namespace unity
{
@@ -33,7 +34,8 @@ class AbstractUserPromptView;
struct PromptFactory
{
- static nux::ObjectPtr<AbstractUserPromptView> CreatePrompt(session::Manager::Ptr const&);
+ static nux::ObjectPtr<AbstractUserPromptView> CreatePrompt(session::Manager::Ptr const&,
+ UserAuthenticator::Ptr const&);
};
}
diff --git a/lockscreen/SuspendInhibitorManager.cpp b/lockscreen/SuspendInhibitorManager.cpp
index 8131e7d51..6135ef790 100644
--- a/lockscreen/SuspendInhibitorManager.cpp
+++ b/lockscreen/SuspendInhibitorManager.cpp
@@ -60,6 +60,8 @@ SuspendInhibitorManager::Impl::Impl(SuspendInhibitorManager *parent)
lm_proxy_->Connect("PrepareForSleep", [this] (GVariant* variant) {
if (glib::Variant(variant).GetBool())
parent_->about_to_suspend.emit();
+ else
+ parent_->resumed.emit();
});
lm_proxy_->connected.connect(sigc::mem_fun(&parent->connected, &decltype(parent->connected)::emit));
diff --git a/lockscreen/SuspendInhibitorManager.h b/lockscreen/SuspendInhibitorManager.h
index 1954a36e6..75c95f5f1 100644
--- a/lockscreen/SuspendInhibitorManager.h
+++ b/lockscreen/SuspendInhibitorManager.h
@@ -42,6 +42,7 @@ public:
sigc::signal<void> connected;
sigc::signal<void> about_to_suspend;
+ sigc::signal<void> resumed;
private:
class Impl;
diff --git a/lockscreen/UserAuthenticator.h b/lockscreen/UserAuthenticator.h
index a8b46b816..e30ce2fdb 100644
--- a/lockscreen/UserAuthenticator.h
+++ b/lockscreen/UserAuthenticator.h
@@ -36,6 +36,7 @@ typedef std::shared_ptr<std::promise<std::string>> PromiseAuthCodePtr;
class UserAuthenticator
{
public:
+ typedef std::shared_ptr<UserAuthenticator> Ptr;
typedef std::function<void(bool)> AuthenticateEndCallback;
virtual ~UserAuthenticator() = default;
@@ -43,6 +44,7 @@ public:
// Authenticate the user in a background thread.
virtual bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) = 0;
+ sigc::signal<void> start_failed;
sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_on_requested;
sigc::signal<void, std::string, PromiseAuthCodePtr const&> echo_off_requested;
sigc::signal<void, std::string> message_requested;
diff --git a/lockscreen/UserAuthenticatorPam.cpp b/lockscreen/UserAuthenticatorPam.cpp
index 0b2c9f2b2..f4e1952c8 100644
--- a/lockscreen/UserAuthenticatorPam.cpp
+++ b/lockscreen/UserAuthenticatorPam.cpp
@@ -23,6 +23,7 @@
#include "UserAuthenticatorPam.h"
#include "unity-shared/UnitySettings.h"
+#include "UnityCore/GLibWrapper.h"
#include <cstring>
#include <security/pam_appl.h>
@@ -36,42 +37,49 @@ namespace lockscreen
bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
AuthenticateEndCallback const& authenticate_cb)
{
+ if (pam_handle_)
+ return false;
+
first_prompt_ = true;
username_ = username;
authenticate_cb_ = authenticate_cb;
- pam_handle_ = nullptr;
- if (!InitPam() || !pam_handle_)
- return false;
+ glib::Error error;
+ g_thread_try_new(nullptr, AuthenticationThreadFunc, this, &error);
- glib::Object<GTask> task(g_task_new(nullptr, cancellable_, [] (GObject*, GAsyncResult*, gpointer data) {
- auto self = static_cast<UserAuthenticatorPam*>(data);
- pam_end(self->pam_handle_, self->status_);
- self->authenticate_cb_(self->status_ == PAM_SUCCESS);
- }, this));
+ return !error;
+}
- g_task_set_task_data(task, this, nullptr);
+gpointer UserAuthenticatorPam::AuthenticationThreadFunc(gpointer data)
+{
+ auto self = static_cast<UserAuthenticatorPam*>(data);
- g_task_run_in_thread(task, [] (GTask* task, gpointer, gpointer data, GCancellable*) {
- auto self = static_cast<UserAuthenticatorPam*>(data);
+ if (!self->InitPam() || !self->pam_handle_)
+ {
+ self->pam_handle_ = nullptr;
+ self->source_manager_.AddTimeout(0, [self] { self->start_failed.emit(); return false; });
+ return nullptr;
+ }
- self->status_ = pam_authenticate(self->pam_handle_, 0);
+ self->status_ = pam_authenticate(self->pam_handle_, 0);
- if (self->status_ == PAM_SUCCESS)
- {
- int status2 = pam_acct_mgmt(self->pam_handle_, 0);
+ if (self->status_ == PAM_SUCCESS)
+ {
+ int status2 = pam_acct_mgmt(self->pam_handle_, 0);
- if (status2 == PAM_NEW_AUTHTOK_REQD)
- status2 = pam_chauthtok(self->pam_handle_, PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (status2 == PAM_NEW_AUTHTOK_REQD)
+ status2 = pam_chauthtok(self->pam_handle_, PAM_CHANGE_EXPIRED_AUTHTOK);
- if (unity::Settings::Instance().pam_check_account_type())
- self->status_ = status2;
+ if (unity::Settings::Instance().pam_check_account_type())
+ self->status_ = status2;
- pam_setcred(self->pam_handle_, PAM_REINITIALIZE_CRED);
- }
- });
+ pam_setcred(self->pam_handle_, PAM_REINITIALIZE_CRED);
+ }
- return true;
+ pam_end(self->pam_handle_, self->status_);
+ self->pam_handle_ = nullptr;
+ self->source_manager_.AddTimeout(0, [self] { self->authenticate_cb_(self->status_ == PAM_SUCCESS); return false; });
+ return nullptr;
}
bool UserAuthenticatorPam::InitPam()
diff --git a/lockscreen/UserAuthenticatorPam.h b/lockscreen/UserAuthenticatorPam.h
index 5174aec81..82273cd49 100644
--- a/lockscreen/UserAuthenticatorPam.h
+++ b/lockscreen/UserAuthenticatorPam.h
@@ -20,8 +20,6 @@
#ifndef UNITY_USER_AUTHENTICATOR_PAM_H
#define UNITY_USER_AUTHENTICATOR_PAM_H
-#include <boost/noncopyable.hpp>
-#include <UnityCore/GLibWrapper.h>
#include <UnityCore/GLibSource.h>
#include "UserAuthenticator.h"
@@ -36,13 +34,17 @@ namespace unity
namespace lockscreen
{
-class UserAuthenticatorPam : public UserAuthenticator, private boost::noncopyable
+class UserAuthenticatorPam : public UserAuthenticator
{
public:
+ UserAuthenticatorPam() = default;
bool AuthenticateStart(std::string const& username, AuthenticateEndCallback const&) override;
private:
- // TODO (andy) move to pimpl
+ UserAuthenticatorPam(UserAuthenticatorPam const&) = delete;
+ UserAuthenticatorPam& operator=(UserAuthenticatorPam const&) = delete;
+
+ static gpointer AuthenticationThreadFunc(gpointer);
bool InitPam();
static int ConversationFunction(int num_msg,
@@ -53,10 +55,9 @@ private:
std::string username_;
AuthenticateEndCallback authenticate_cb_;
- int status_;
- bool first_prompt_;
- pam_handle* pam_handle_;
- glib::Cancellable cancellable_;
+ int status_ = 0;
+ bool first_prompt_ = true;
+ pam_handle* pam_handle_ = nullptr;
glib::SourceManager source_manager_;
};
diff --git a/lockscreen/UserPromptView.cpp b/lockscreen/UserPromptView.cpp
index 3abb6c25a..7a083632d 100644
--- a/lockscreen/UserPromptView.cpp
+++ b/lockscreen/UserPromptView.cpp
@@ -23,6 +23,7 @@
#include <glib/gi18n-lib.h>
#include <boost/algorithm/string/trim.hpp>
+#include <NuxCore/Logger.h>
#include <Nux/VLayout.h>
#include "LockScreenSettings.h"
@@ -38,6 +39,9 @@ namespace lockscreen
{
namespace
{
+
+DECLARE_LOGGER(logger, "unity.lockscreen");
+
const RawPixel PADDING = 10_em;
const RawPixel LAYOUT_MARGIN = 10_em;
const RawPixel MSG_LAYOUT_MARGIN = 15_em;
@@ -101,41 +105,46 @@ std::string SanitizeMessage(std::string const& message)
}
-UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager)
- : AbstractUserPromptView(session_manager)
- , session_manager_(session_manager)
+UserPromptView::UserPromptView(session::Manager::Ptr const& session_manager,
+ UserAuthenticator::Ptr const& user_authenticator)
+ : AbstractUserPromptView(session_manager, user_authenticator)
, username_(nullptr)
, msg_layout_(nullptr)
, prompt_layout_(nullptr)
, button_layout_(nullptr)
, prompted_(false)
, unacknowledged_messages_(false)
+ , num_retry_auth_(0)
{
- user_authenticator_.echo_on_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
+ user_authenticator_->start_failed.connect(sigc::track_obj([this](){
+ HandleAuthenticationStartFailure();
+ }, *this));
+
+ user_authenticator_->echo_on_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
prompted_ = true;
unacknowledged_messages_ = false;
AddPrompt(message, /* visible */ true, promise);
- });
+ }, *this));
- user_authenticator_.echo_off_requested.connect([this](std::string const& message, PromiseAuthCodePtr const& promise){
+ user_authenticator_->echo_off_requested.connect(sigc::track_obj([this](std::string const& message, PromiseAuthCodePtr const& promise){
prompted_ = true;
unacknowledged_messages_ = false;
AddPrompt(message, /* visible */ false, promise);
- });
+ }, *this));
- user_authenticator_.message_requested.connect([this](std::string const& message){
+ user_authenticator_->message_requested.connect(sigc::track_obj([this](std::string const& message){
unacknowledged_messages_ = true;
AddMessage(message, nux::color::White);
- });
+ }, *this));
- user_authenticator_.error_requested.connect([this](std::string const& message){
+ user_authenticator_->error_requested.connect(sigc::track_obj([this](std::string const& message){
unacknowledged_messages_ = true;
AddMessage(message, nux::color::Red);
- });
+ }, *this));
- user_authenticator_.clear_prompts.connect([this](){
+ user_authenticator_->clear_prompts.connect(sigc::track_obj([this](){
ResetLayout();
- });
+ }, *this));
scale.changed.connect(sigc::hide(sigc::mem_fun(this, &UserPromptView::UpdateSize)));
@@ -469,8 +478,11 @@ void UserPromptView::StartAuthentication()
prompted_ = false;
unacknowledged_messages_ = false;
- user_authenticator_.AuthenticateStart(session_manager_->UserName(),
- sigc::mem_fun(this, &UserPromptView::AuthenticationCb));
+ if(!user_authenticator_->AuthenticateStart(session_manager_->UserName(),
+ sigc::mem_fun(this, &UserPromptView::AuthenticationCb)))
+ {
+ HandleAuthenticationStartFailure();
+ }
}
void UserPromptView::DoUnlock()
@@ -478,5 +490,29 @@ void UserPromptView::DoUnlock()
session_manager_->unlock_requested.emit();
}
+void UserPromptView::HandleAuthenticationStartFailure()
+{
+ ++num_retry_auth_;
+
+ if (num_retry_auth_ <= 5)
+ {
+ LOG_WARNING(logger) << "Failed to start the authentication process. Retrying for " << num_retry_auth_ << " time.";
+ source_manager_.AddTimeout(100, [this] {
+ StartAuthentication();
+ return false;
+ });
+ }
+ else
+ {
+ num_retry_auth_ = 0;
+
+ AddMessage(_("Authentication failure"), nux::color::Red);
+ AddButton(_("Switch to greeter…"), [this] {
+ session_manager_->SwitchToGreeter();
+ });
+ GetLayout()->AddLayout(button_layout_);
+ }
+}
+
}
}
diff --git a/lockscreen/UserPromptView.h b/lockscreen/UserPromptView.h
index e0d4f9be1..0481334b8 100644
--- a/lockscreen/UserPromptView.h
+++ b/lockscreen/UserPromptView.h
@@ -25,10 +25,10 @@
#include <Nux/Nux.h>
#include <Nux/View.h>
+#include "UnityCore/GLibSource.h"
#include "UnityCore/SessionManager.h"
#include "LockScreenAbstractPromptView.h"
-#include "UserAuthenticatorPam.h"
#include "unity-shared/IMTextEntry.h"
namespace nux
@@ -48,7 +48,8 @@ namespace lockscreen
class UserPromptView : public AbstractUserPromptView
{
public:
- UserPromptView(session::Manager::Ptr const& session_manager);
+ UserPromptView(session::Manager::Ptr const& session_manager,
+ UserAuthenticator::Ptr const& user_authenticator);
nux::View* focus_view();
@@ -70,9 +71,8 @@ private:
void ShowAuthenticated(bool successful);
void StartAuthentication();
void DoUnlock();
+ void HandleAuthenticationStartFailure();
- session::Manager::Ptr session_manager_;
- UserAuthenticatorPam user_authenticator_;
std::shared_ptr<nux::AbstractPaintLayer> bg_layer_;
StaticCairoText* username_;
nux::VLayout* msg_layout_;
@@ -84,6 +84,9 @@ private:
bool prompted_;
bool unacknowledged_messages_;
+ int num_retry_auth_ = 0;
+
+ glib::SourceManager source_manager_;
};
}
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 20e644860..0ecff9515 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -1496,6 +1496,13 @@ bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
CompOutput* output,
unsigned int mask)
{
+ if (G_UNLIKELY(lockscreen_controller_->IsPaintInhibited()))
+ {
+ CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
+ CHECKGL(glClear(GL_COLOR_BUFFER_BIT));
+ return true;
+ }
+
bool ret;
/*
@@ -1692,6 +1699,11 @@ void UnityScreen::preparePaint(int ms)
void UnityScreen::donePaint()
{
+ if (G_UNLIKELY(lockscreen_controller_->IsPaintInhibited()))
+ {
+ lockscreen_controller_->MarkBufferHasCleared();
+ }
+
/*
* It's only safe to clear the draw list if drawing actually occurred
* (i.e. the shell was not obscured behind a fullscreen window).
diff --git a/tests/test_icon_loader.cpp b/tests/test_icon_loader.cpp
index 5223efc24..852f88701 100644
--- a/tests/test_icon_loader.cpp
+++ b/tests/test_icon_loader.cpp
@@ -104,7 +104,7 @@ TEST_F(TestIconLoader, TestGetDefault)
EXPECT_EQ(&icon_loader, &IconLoader::GetDefault());
}
-TEST_F(TestIconLoader, TestGetOneIcon)
+TEST_F(TestIconLoader, UNSTABLE_TEST (TestGetOneIcon))
{
LoadResult load_result;
@@ -176,7 +176,7 @@ TEST_F(TestIconLoader, TestGetOneIconManyTimes)
CheckResults(results);
}
-TEST_F(TestIconLoader, TestGetManyIcons)
+TEST_F(TestIconLoader, UNSTABLE_TEST (TestGetManyIcons))
{
std::vector<LoadResult> results;
int i = 0;
@@ -198,7 +198,7 @@ TEST_F(TestIconLoader, TestGetManyIcons)
CheckResults(results);
}
-TEST_F(TestIconLoader, TestCancelSome)
+TEST_F(TestIconLoader, UNSTABLE_TEST (TestCancelSome))
{
std::vector<LoadResult> results;
std::vector<IconLoader::Handle> handles;