Commit 67a4df6f authored by Roman Aleksandrov's avatar Roman Aleksandrov Committed by Commit Bot

LoginScreen: Show TPM lock status.

If TPM is locked show banner with steps on how to fix this issue.

Bug: 1114656
Change-Id: I85dab0f4ce003ac3dad61c318efb3333457993ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2346266Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Commit-Queue: Roman Aleksandrov <raleksandrov@google.com>
Cr-Commit-Position: refs/heads/master@{#797992}
parent f1a2ccf7
...@@ -2186,6 +2186,12 @@ This file contains the strings for ash. ...@@ -2186,6 +2186,12 @@ This file contains the strings for ash.
<message name="IDS_ASH_LOGIN_SCREEN_UNVERIFIED_CODE_WARNING" desc="Message shown at the bottom of the login screen when the device has ran or is capable to run unverified code."> <message name="IDS_ASH_LOGIN_SCREEN_UNVERIFIED_CODE_WARNING" desc="Message shown at the bottom of the login screen when the device has ran or is capable to run unverified code.">
This device may contain apps that haven't been verified by Google. This device may contain apps that haven't been verified by Google.
</message> </message>
<message name="IDS_ASH_LOGIN_POD_TPM_LOCKED_ISSUE_WARNING" desc="Message shown as part of the TPM locked warning bubble when TPM is locked.">
Your Chromebook is locked due to a known issue. You will be able to sign in after: <ph name="TIME_LEFT">$1<ex>1 hour, 15 minutes, 10 seconds</ex></ph>.
</message>
<message name="IDS_ASH_LOGIN_POD_TPM_LOCKED_ISSUE_DESCRIPTION" desc="Message shown as part of the TPM locked warning bubble when TPM is locked.">
Your Chromebook needs to stay on and connected to power during this time. Make sure the charger or adapter cables are completely plugged in, both to your Chromebook and the power outlet. Do not turn off your Chromebook.
</message>
<!-- Multi-profiles intro dialog --> <!-- Multi-profiles intro dialog -->
<message name="IDS_ASH_MULTIPROFILES_INTRO_HEADLINE" desc="Describes which feature multi-profiles intro dialog presents."> <message name="IDS_ASH_MULTIPROFILES_INTRO_HEADLINE" desc="Describes which feature multi-profiles intro dialog presents.">
......
f51cff68354bd8a9f31e7c0bc42b520d6ae2b591
\ No newline at end of file
f51cff68354bd8a9f31e7c0bc42b520d6ae2b591
\ No newline at end of file
...@@ -1049,6 +1049,17 @@ void LockContentsView::OnAuthDisabledForUser( ...@@ -1049,6 +1049,17 @@ void LockContentsView::OnAuthDisabledForUser(
} }
} }
void LockContentsView::OnSetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left) {
LoginBigUserView* big_user =
TryToFindBigUser(user, false /*require_auth_active*/);
if (big_user && big_user->auth_user()) {
LayoutAuth(big_user, nullptr /*opt_to_hide*/, true /*animate*/);
big_user->auth_user()->SetTpmLockedState(is_locked, time_left);
}
}
void LockContentsView::OnTapToUnlockEnabledForUserChanged(const AccountId& user, void LockContentsView::OnTapToUnlockEnabledForUserChanged(const AccountId& user,
bool enabled) { bool enabled) {
LockContentsView::UserState* state = FindStateForUser(user); LockContentsView::UserState* state = FindStateForUser(user);
......
...@@ -172,6 +172,9 @@ class ASH_EXPORT LockContentsView ...@@ -172,6 +172,9 @@ class ASH_EXPORT LockContentsView
void OnAuthDisabledForUser( void OnAuthDisabledForUser(
const AccountId& user, const AccountId& user,
const AuthDisabledData& auth_disabled_data) override; const AuthDisabledData& auth_disabled_data) override;
void OnSetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left) override;
void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override; void OnLockScreenNoteStateChanged(mojom::TrayActionState state) override;
void OnTapToUnlockEnabledForUserChanged(const AccountId& user, void OnTapToUnlockEnabledForUserChanged(const AccountId& user,
bool enabled) override; bool enabled) override;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "base/i18n/time_formatting.h" #include "base/i18n/time_formatting.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "components/user_manager/user.h" #include "components/user_manager/user.h"
...@@ -54,6 +55,7 @@ ...@@ -54,6 +55,7 @@
#include "ui/views/border.h" #include "ui/views/border.h"
#include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/highlight_path_generator.h" #include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h" #include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout.h"
...@@ -123,6 +125,15 @@ constexpr int kDisabledAuthMessageTitleFontSizeDeltaDp = 3; ...@@ -123,6 +125,15 @@ constexpr int kDisabledAuthMessageTitleFontSizeDeltaDp = 3;
constexpr int kDisabledAuthMessageContentsFontSizeDeltaDp = -1; constexpr int kDisabledAuthMessageContentsFontSizeDeltaDp = -1;
constexpr int kDisabledAuthMessageRoundedCornerRadiusDp = 8; constexpr int kDisabledAuthMessageRoundedCornerRadiusDp = 8;
constexpr int kLockedTpmMessageVerticalBorderDp = 16;
constexpr int kLockedTpmMessageHorizontalBorderDp = 16;
constexpr int kLockedTpmMessageChildrenSpacingDp = 4;
constexpr int kLockedTpmMessageWidthDp = 360;
constexpr int kLockedTpmMessageHeightDp = 108;
constexpr int kLockedTpmMessageIconSizeDp = 24;
constexpr int kLockedTpmMessageDeltaDp = 0;
constexpr int kLockedTpmMessageRoundedCornerRadiusDp = 8;
constexpr int kNonEmptyWidthDp = 1; constexpr int kNonEmptyWidthDp = 1;
// Returns an observer that will hide |view| when it fires. The observer will // Returns an observer that will hide |view| when it fires. The observer will
...@@ -744,6 +755,88 @@ class LoginAuthUserView::DisabledAuthMessageView : public views::View { ...@@ -744,6 +755,88 @@ class LoginAuthUserView::DisabledAuthMessageView : public views::View {
DISALLOW_COPY_AND_ASSIGN(DisabledAuthMessageView); DISALLOW_COPY_AND_ASSIGN(DisabledAuthMessageView);
}; };
// The message shown to user when TPM is locked.
class LoginAuthUserView::LockedTpmMessageView : public views::View {
public:
LockedTpmMessageView() {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical,
gfx::Insets(kLockedTpmMessageVerticalBorderDp,
kLockedTpmMessageHorizontalBorderDp),
kLockedTpmMessageChildrenSpacingDp));
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
SetPreferredSize(
gfx::Size(kLockedTpmMessageWidthDp, kLockedTpmMessageHeightDp));
SetFocusBehavior(FocusBehavior::ALWAYS);
auto message_icon = std::make_unique<views::ImageView>();
message_icon->SetPreferredSize(
gfx::Size(kLockedTpmMessageIconSizeDp, kLockedTpmMessageIconSizeDp));
message_icon->SetImage(
gfx::CreateVectorIcon(kLockScreenAlertIcon, SK_ColorWHITE));
message_icon_ = AddChildView(std::move(message_icon));
message_warning_ = CreateLabel();
message_description_ = CreateLabel();
// Set content.
base::string16 message_description = l10n_util::GetStringUTF16(
IDS_ASH_LOGIN_POD_TPM_LOCKED_ISSUE_DESCRIPTION);
message_description_->SetText(message_description);
}
LockedTpmMessageView(const LockedTpmMessageView&) = delete;
LockedTpmMessageView& operator=(const LockedTpmMessageView&) = delete;
~LockedTpmMessageView() override = default;
// Set the parameters needed to render the message.
void SetRemainingTime(base::TimeDelta time_left) {
base::string16 time_left_message;
if (base::TimeDurationFormatWithSeconds(
time_left, base::DurationFormatWidth::DURATION_WIDTH_WIDE,
&time_left_message)) {
base::string16 message_warning = l10n_util::GetStringFUTF16(
IDS_ASH_LOGIN_POD_TPM_LOCKED_ISSUE_WARNING, time_left_message);
message_warning_->SetText(message_warning);
}
Layout();
}
// views::View:
void OnPaint(gfx::Canvas* canvas) override {
views::View::OnPaint(canvas);
cc::PaintFlags flags;
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(
PinRequestView::GetChildUserDialogColor(false /*using blur*/));
canvas->DrawRoundRect(GetContentsBounds(),
kLockedTpmMessageRoundedCornerRadiusDp, flags);
}
void RequestFocus() override { message_warning_->RequestFocus(); }
private:
views::Label* CreateLabel() {
auto label = std::make_unique<views::Label>(base::string16(),
views::style::CONTEXT_LABEL,
views::style::STYLE_PRIMARY);
label->SetFontList(gfx::FontList().Derive(kLockedTpmMessageDeltaDp,
gfx::Font::NORMAL,
gfx::Font::Weight::NORMAL));
label->SetSubpixelRenderingEnabled(false);
label->SetAutoColorReadabilityEnabled(false);
label->SetEnabledColor(SK_ColorWHITE);
label->SetFocusBehavior(FocusBehavior::ALWAYS);
label->SetMultiLine(true);
return AddChildView(std::move(label));
}
views::Label* message_warning_;
views::Label* message_description_;
views::ImageView* message_icon_;
};
struct LoginAuthUserView::AnimationState { struct LoginAuthUserView::AnimationState {
explicit AnimationState(LoginAuthUserView* view) { explicit AnimationState(LoginAuthUserView* view) {
non_pin_y_start_in_screen = view->GetBoundsInScreen().y(); non_pin_y_start_in_screen = view->GetBoundsInScreen().y();
...@@ -884,6 +977,9 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user, ...@@ -884,6 +977,9 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user,
auto disabled_auth_message = std::make_unique<DisabledAuthMessageView>(); auto disabled_auth_message = std::make_unique<DisabledAuthMessageView>();
disabled_auth_message_ = disabled_auth_message.get(); disabled_auth_message_ = disabled_auth_message.get();
auto locked_tpm_message_view = std::make_unique<LockedTpmMessageView>();
locked_tpm_message_view_ = locked_tpm_message_view.get();
auto fingerprint_view = std::make_unique<FingerprintView>(); auto fingerprint_view = std::make_unique<FingerprintView>();
fingerprint_view_ = fingerprint_view.get(); fingerprint_view_ = fingerprint_view.get();
...@@ -904,6 +1000,9 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user, ...@@ -904,6 +1000,9 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user,
auto wrapped_disabled_auth_message_view = auto wrapped_disabled_auth_message_view =
login_views_utils::WrapViewForPreferredSize( login_views_utils::WrapViewForPreferredSize(
std::move(disabled_auth_message)); std::move(disabled_auth_message));
auto wrapped_locked_tpm_message_view =
login_views_utils::WrapViewForPreferredSize(
std::move(locked_tpm_message_view));
auto wrapped_user_view = auto wrapped_user_view =
login_views_utils::WrapViewForPreferredSize(std::move(user_view)); login_views_utils::WrapViewForPreferredSize(std::move(user_view));
auto wrapped_pin_view = auto wrapped_pin_view =
...@@ -927,6 +1026,8 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user, ...@@ -927,6 +1026,8 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user,
AddChildView(std::move(wrapped_online_sign_in_message_view)); AddChildView(std::move(wrapped_online_sign_in_message_view));
views::View* wrapped_disabled_auth_message_view_ptr = views::View* wrapped_disabled_auth_message_view_ptr =
AddChildView(std::move(wrapped_disabled_auth_message_view)); AddChildView(std::move(wrapped_disabled_auth_message_view));
views::View* wrapped_locked_tpm_message_view_ptr =
AddChildView(std::move(wrapped_locked_tpm_message_view));
views::View* wrapped_pin_view_ptr = AddChildView(std::move(wrapped_pin_view)); views::View* wrapped_pin_view_ptr = AddChildView(std::move(wrapped_pin_view));
views::View* wrapped_fingerprint_view_ptr = views::View* wrapped_fingerprint_view_ptr =
AddChildView(std::move(wrapped_fingerprint_view)); AddChildView(std::move(wrapped_fingerprint_view));
...@@ -960,6 +1061,7 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user, ...@@ -960,6 +1061,7 @@ LoginAuthUserView::LoginAuthUserView(const LoginUserInfo& user,
add_padding(kDistanceFromTopOfBigUserViewToUserIconDp); add_padding(kDistanceFromTopOfBigUserViewToUserIconDp);
add_view(wrapped_user_view_ptr); add_view(wrapped_user_view_ptr);
add_view(wrapped_padding_below_user_view_ptr); add_view(wrapped_padding_below_user_view_ptr);
add_view(wrapped_locked_tpm_message_view_ptr);
add_view(wrapped_password_view_ptr); add_view(wrapped_password_view_ptr);
add_view(wrapped_online_sign_in_message_view_ptr); add_view(wrapped_online_sign_in_message_view_ptr);
add_view(wrapped_disabled_auth_message_view_ptr); add_view(wrapped_disabled_auth_message_view_ptr);
...@@ -992,13 +1094,17 @@ void LoginAuthUserView::SetAuthMethods(uint32_t auth_methods, ...@@ -992,13 +1094,17 @@ void LoginAuthUserView::SetAuthMethods(uint32_t auth_methods,
bool has_challenge_response = HasAuthMethod(AUTH_CHALLENGE_RESPONSE); bool has_challenge_response = HasAuthMethod(AUTH_CHALLENGE_RESPONSE);
bool auth_disabled = HasAuthMethod(AUTH_DISABLED); bool auth_disabled = HasAuthMethod(AUTH_DISABLED);
bool hide_auth = auth_disabled || force_online_sign_in; bool hide_auth = auth_disabled || force_online_sign_in || tpm_is_locked_;
online_sign_in_message_->SetVisible(force_online_sign_in); online_sign_in_message_->SetVisible(force_online_sign_in);
disabled_auth_message_->SetVisible(auth_disabled); disabled_auth_message_->SetVisible(auth_disabled);
if (auth_disabled) if (auth_disabled && !tpm_is_locked_)
disabled_auth_message_->RequestFocus(); disabled_auth_message_->RequestFocus();
locked_tpm_message_view_->SetVisible(tpm_is_locked_);
if (tpm_is_locked_)
locked_tpm_message_view_->RequestFocus();
// Adjust the PIN keyboard visibility before the password textfield's one, so // Adjust the PIN keyboard visibility before the password textfield's one, so
// that when both are about to be hidden the focus doesn't jump to the "1" // that when both are about to be hidden the focus doesn't jump to the "1"
// keyboard button, causing unexpected accessibility effects. // keyboard button, causing unexpected accessibility effects.
...@@ -1248,6 +1354,15 @@ void LoginAuthUserView::SetAuthDisabledMessage( ...@@ -1248,6 +1354,15 @@ void LoginAuthUserView::SetAuthDisabledMessage(
Layout(); Layout();
} }
void LoginAuthUserView::SetTpmLockedState(bool is_locked,
base::TimeDelta time_left) {
if (is_locked)
locked_tpm_message_view_->SetRemainingTime(time_left);
tpm_is_locked_ = is_locked;
// Update auth methods which are available.
SetAuthMethods(auth_methods_, auth_metadata_);
}
const LoginUserInfo& LoginAuthUserView::current_user() const { const LoginUserInfo& LoginAuthUserView::current_user() const {
return user_view_->current_user(); return user_view_->current_user();
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <memory> #include <memory>
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/login/ui/login_error_bubble.h"
#include "ash/login/ui/login_password_view.h" #include "ash/login/ui/login_password_view.h"
#include "ash/login/ui/login_user_view.h" #include "ash/login/ui/login_user_view.h"
#include "ash/login/ui/non_accessible_view.h" #include "ash/login/ui/non_accessible_view.h"
...@@ -156,6 +157,8 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView, ...@@ -156,6 +157,8 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView,
// auth method is |AUTH_DISABLED|. // auth method is |AUTH_DISABLED|.
void SetAuthDisabledMessage(const AuthDisabledData& auth_disabled_data); void SetAuthDisabledMessage(const AuthDisabledData& auth_disabled_data);
void SetTpmLockedState(bool is_locked, base::TimeDelta time_left);
const LoginUserInfo& current_user() const; const LoginUserInfo& current_user() const;
// Provides the view that should be the anchor to message bubbles. Either the // Provides the view that should be the anchor to message bubbles. Either the
...@@ -176,6 +179,7 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView, ...@@ -176,6 +179,7 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView,
class FingerprintView; class FingerprintView;
class ChallengeResponseView; class ChallengeResponseView;
class DisabledAuthMessageView; class DisabledAuthMessageView;
class LockedTpmMessageView;
// Called when the user submits an auth method. Runs mojo call. // Called when the user submits an auth method. Runs mojo call.
void OnAuthSubmit(const base::string16& password); void OnAuthSubmit(const base::string16& password);
...@@ -240,6 +244,7 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView, ...@@ -240,6 +244,7 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView,
DisabledAuthMessageView* disabled_auth_message_ = nullptr; DisabledAuthMessageView* disabled_auth_message_ = nullptr;
FingerprintView* fingerprint_view_ = nullptr; FingerprintView* fingerprint_view_ = nullptr;
ChallengeResponseView* challenge_response_view_ = nullptr; ChallengeResponseView* challenge_response_view_ = nullptr;
LockedTpmMessageView* locked_tpm_message_view_ = nullptr;
// Padding below the user view. Grows when there isn't an input field // Padding below the user view. Grows when there isn't an input field
// or smart card login. // or smart card login.
...@@ -252,6 +257,8 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView, ...@@ -252,6 +257,8 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView,
const OnAuthCallback on_auth_; const OnAuthCallback on_auth_;
const LoginUserView::OnTap on_tap_; const LoginUserView::OnTap on_tap_;
bool tpm_is_locked_ = false;
// Animation state that was cached from before a layout. Generated by // Animation state that was cached from before a layout. Generated by
// |CaptureStateForAnimationPreLayout| and consumed by // |CaptureStateForAnimationPreLayout| and consumed by
// |ApplyAnimationPostLayout|. // |ApplyAnimationPostLayout|.
......
...@@ -38,6 +38,11 @@ void LoginDataDispatcher::Observer::OnAuthDisabledForUser( ...@@ -38,6 +38,11 @@ void LoginDataDispatcher::Observer::OnAuthDisabledForUser(
const AccountId& user, const AccountId& user,
const AuthDisabledData& auth_disabled_data) {} const AuthDisabledData& auth_disabled_data) {}
void LoginDataDispatcher::Observer::OnSetTpmLockedState(
const AccountId& user,
bool is_locked,
base::TimeDelta time_left) {}
void LoginDataDispatcher::Observer::OnTapToUnlockEnabledForUserChanged( void LoginDataDispatcher::Observer::OnTapToUnlockEnabledForUserChanged(
const AccountId& user, const AccountId& user,
bool enabled) {} bool enabled) {}
...@@ -154,6 +159,13 @@ void LoginDataDispatcher::DisableAuthForUser( ...@@ -154,6 +159,13 @@ void LoginDataDispatcher::DisableAuthForUser(
observer.OnAuthDisabledForUser(account_id, auth_disabled_data); observer.OnAuthDisabledForUser(account_id, auth_disabled_data);
} }
void LoginDataDispatcher::SetTpmLockedState(const AccountId& account_id,
bool is_locked,
base::TimeDelta time_left) {
for (auto& observer : observers_)
observer.OnSetTpmLockedState(account_id, is_locked, time_left);
}
void LoginDataDispatcher::SetTapToUnlockEnabledForUser(const AccountId& user, void LoginDataDispatcher::SetTapToUnlockEnabledForUser(const AccountId& user,
bool enabled) { bool enabled) {
for (auto& observer : observers_) for (auto& observer : observers_)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "ash/public/mojom/tray_action.mojom.h" #include "ash/public/mojom/tray_action.mojom.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/time/time.h"
namespace ash { namespace ash {
...@@ -76,6 +77,11 @@ class ASH_EXPORT LoginDataDispatcher : public LoginScreenModel { ...@@ -76,6 +77,11 @@ class ASH_EXPORT LoginDataDispatcher : public LoginScreenModel {
const AccountId& user, const AccountId& user,
const AuthDisabledData& auth_disabled_data); const AuthDisabledData& auth_disabled_data);
// Called when TPM is locked.
virtual void OnSetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left);
// Called when the given user can click their pod to unlock. // Called when the given user can click their pod to unlock.
virtual void OnTapToUnlockEnabledForUserChanged(const AccountId& user, virtual void OnTapToUnlockEnabledForUserChanged(const AccountId& user,
bool enabled); bool enabled);
...@@ -167,6 +173,9 @@ class ASH_EXPORT LoginDataDispatcher : public LoginScreenModel { ...@@ -167,6 +173,9 @@ class ASH_EXPORT LoginDataDispatcher : public LoginScreenModel {
void EnableAuthForUser(const AccountId& account_id) override; void EnableAuthForUser(const AccountId& account_id) override;
void DisableAuthForUser(const AccountId& account_id, void DisableAuthForUser(const AccountId& account_id,
const AuthDisabledData& auth_disabled_data) override; const AuthDisabledData& auth_disabled_data) override;
void SetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left) override;
void SetTapToUnlockEnabledForUser(const AccountId& user, void SetTapToUnlockEnabledForUser(const AccountId& user,
bool enabled) override; bool enabled) override;
void ForceOnlineSignInForUser(const AccountId& user) override; void ForceOnlineSignInForUser(const AccountId& user) override;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/public/cpp/ash_public_export.h" #include "ash/public/cpp/ash_public_export.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/time/time.h"
class AccountId; class AccountId;
...@@ -77,6 +78,10 @@ class ASH_PUBLIC_EXPORT LoginScreenModel { ...@@ -77,6 +78,10 @@ class ASH_PUBLIC_EXPORT LoginScreenModel {
const AccountId& account_id, const AccountId& account_id,
const AuthDisabledData& auth_disabled_data) = 0; const AuthDisabledData& auth_disabled_data) = 0;
virtual void SetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left) = 0;
// Enables or disables the authentication type to tap-to-unlock for the user. // Enables or disables the authentication type to tap-to-unlock for the user.
virtual void SetTapToUnlockEnabledForUser(const AccountId& account_id, virtual void SetTapToUnlockEnabledForUser(const AccountId& account_id,
bool enabled) = 0; bool enabled) = 0;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/browser_process_platform_part.h"
...@@ -56,7 +57,10 @@ ...@@ -56,7 +57,10 @@
#include "components/user_manager/known_user.h" #include "components/user_manager/known_user.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "components/user_manager/user_type.h" #include "components/user_manager/user_type.h"
#include "content/public/browser/device_service.h"
#include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_auth_util.h"
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
...@@ -69,6 +73,9 @@ namespace { ...@@ -69,6 +73,9 @@ namespace {
bool g_skip_force_online_signin_for_testing = false; bool g_skip_force_online_signin_for_testing = false;
const char kWakeLockReason[] = "TPMLockedIssue";
const int kWaitingOvertimeInSeconds = 1;
// User dictionary keys. // User dictionary keys.
const char kKeyUsername[] = "username"; const char kKeyUsername[] = "username";
const char kKeyDisplayName[] = "displayName"; const char kKeyDisplayName[] = "displayName";
...@@ -376,6 +383,121 @@ class UserSelectionScreen::DircryptoMigrationChecker { ...@@ -376,6 +383,121 @@ class UserSelectionScreen::DircryptoMigrationChecker {
DISALLOW_COPY_AND_ASSIGN(DircryptoMigrationChecker); DISALLOW_COPY_AND_ASSIGN(DircryptoMigrationChecker);
}; };
// Helper class to call cryptohome to check whether tpm is locked and update
// UI with time left to unlocking.
class UserSelectionScreen::TpmLockedChecker {
public:
explicit TpmLockedChecker(UserSelectionScreen* owner) : owner_(owner) {}
TpmLockedChecker(const TpmLockedChecker&) = delete;
TpmLockedChecker& operator=(const TpmLockedChecker&) = delete;
~TpmLockedChecker() = default;
void Check() {
CryptohomeClient::Get()->WaitForServiceToBeAvailable(base::BindOnce(
&TpmLockedChecker::RunCryptohomeCheck, weak_ptr_factory_.GetWeakPtr()));
}
private:
void RunCryptohomeCheck(bool service_is_ready) {
if (!service_is_ready) {
LOG(ERROR) << "Cryptohome is not available.";
return;
}
chromeos::CryptohomeClient::Get()->GetTpmStatus(
cryptohome::GetTpmStatusRequest(),
base::BindOnce(&TpmLockedChecker::OnGetTpmStatus,
weak_ptr_factory_.GetWeakPtr()));
}
// Callback invoked when GetTpmStatus call is finished.
void OnGetTpmStatus(base::Optional<cryptohome::BaseReply> reply) {
check_finised_ = base::TimeTicks::Now();
if (!reply.has_value()) {
return;
}
if (reply->has_error() &&
reply->error() != cryptohome::CRYPTOHOME_ERROR_NOT_SET) {
return;
}
if (!reply->HasExtension(cryptohome::GetTpmStatusReply::reply)) {
return;
}
auto reply_proto =
reply->GetExtension(cryptohome::GetTpmStatusReply::reply);
if (reply_proto.dictionary_attack_lockout_in_effect()) {
int time_remaining =
reply_proto.dictionary_attack_lockout_seconds_remaining();
// Add `kWaitingOvertimeInSeconds` for safetiness, i.e hiding UI and
// releasing `wake_lock_` happens after TPM becomes unlocked.
dictionary_attack_lockout_time_remaining_ = base::TimeDelta::FromSeconds(
time_remaining + kWaitingOvertimeInSeconds);
OnTpmIsLocked();
} else {
TpmIsUnlocked();
}
}
void OnTpmIsLocked() {
AcquireWakeLock();
clock_ticking_animator_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1),
this, &TpmLockedChecker::UpdateUI);
tpm_recheck_.Start(FROM_HERE, base::TimeDelta::FromMinutes(1), this,
&TpmLockedChecker::Check);
}
void UpdateUI() {
const base::TimeDelta time_spent = base::TimeTicks::Now() - check_finised_;
if (time_spent > dictionary_attack_lockout_time_remaining_) {
Check();
} else {
owner_->SetTpmLockedState(
true, dictionary_attack_lockout_time_remaining_ - time_spent);
}
}
void TpmIsUnlocked() {
ReleaseWakeLock();
clock_ticking_animator_.Stop();
tpm_recheck_.Stop();
owner_->SetTpmLockedState(false, base::TimeDelta());
}
void AcquireWakeLock() {
if (!wake_lock_) {
mojo::Remote<device::mojom::WakeLockProvider> provider;
content::GetDeviceService().BindWakeLockProvider(
provider.BindNewPipeAndPassReceiver());
provider->GetWakeLockWithoutContext(
device::mojom::WakeLockType::kPreventDisplaySleep,
device::mojom::WakeLockReason::kOther, kWakeLockReason,
wake_lock_.BindNewPipeAndPassReceiver());
}
wake_lock_->RequestWakeLock();
}
void ReleaseWakeLock() {
if (!wake_lock_)
return;
wake_lock_->CancelWakeLock();
}
UserSelectionScreen* const owner_;
base::TimeTicks check_finised_;
base::TimeDelta dictionary_attack_lockout_time_remaining_;
base::RepeatingTimer clock_ticking_animator_;
base::RepeatingTimer tpm_recheck_;
mojo::Remote<device::mojom::WakeLock> wake_lock_;
base::WeakPtrFactory<TpmLockedChecker> weak_ptr_factory_{this};
};
UserSelectionScreen::UserSelectionScreen(const std::string& display_type) UserSelectionScreen::UserSelectionScreen(const std::string& display_type)
: BaseScreen(UserBoardView::kScreenId, OobeScreenPriority::DEFAULT), : BaseScreen(UserBoardView::kScreenId, OobeScreenPriority::DEFAULT),
display_type_(display_type) { display_type_(display_type) {
...@@ -402,6 +524,13 @@ void UserSelectionScreen::InitEasyUnlock() { ...@@ -402,6 +524,13 @@ void UserSelectionScreen::InitEasyUnlock() {
proximity_auth::ScreenlockBridge::Get()->SetLockHandler(this); proximity_auth::ScreenlockBridge::Get()->SetLockHandler(this);
} }
void UserSelectionScreen::SetTpmLockedState(bool is_locked,
base::TimeDelta time_left) {
for (user_manager::User* user : users_) {
view_->SetTpmLockedState(user->GetAccountId(), is_locked, time_left);
}
}
// static // static
void UserSelectionScreen::FillUserDictionary( void UserSelectionScreen::FillUserDictionary(
const user_manager::User* user, const user_manager::User* user,
...@@ -584,6 +713,12 @@ void UserSelectionScreen::Init(const user_manager::UserList& users) { ...@@ -584,6 +713,12 @@ void UserSelectionScreen::Init(const user_manager::UserList& users) {
activity_detector->AddObserver(this); activity_detector->AddObserver(this);
if (!ime_state_.get()) if (!ime_state_.get())
ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState(); ime_state_ = input_method::InputMethodManager::Get()->GetActiveIMEState();
if (tpm_locked_checker_)
return;
tpm_locked_checker_ = std::make_unique<TpmLockedChecker>(this);
tpm_locked_checker_->Check();
} }
void UserSelectionScreen::OnUserImageChanged(const user_manager::User& user) { void UserSelectionScreen::OnUserImageChanged(const user_manager::User& user) {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_USER_SELECTION_SCREEN_H_ #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_USER_SELECTION_SCREEN_H_
#include <map> #include <map>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -13,6 +14,7 @@ ...@@ -13,6 +14,7 @@
#include "ash/public/cpp/session/user_info.h" #include "ash/public/cpp/session/user_info.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/chromeos/login/screens/base_screen.h" #include "chrome/browser/chromeos/login/screens/base_screen.h"
...@@ -20,6 +22,7 @@ ...@@ -20,6 +22,7 @@
#include "chrome/browser/chromeos/login/ui/login_display.h" #include "chrome/browser/chromeos/login/ui/login_display.h"
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chromeos/components/proximity_auth/screenlock_bridge.h" #include "chromeos/components/proximity_auth/screenlock_bridge.h"
#include "chromeos/dbus/cryptohome/rpc.pb.h"
#include "components/account_id/account_id.h" #include "components/account_id/account_id.h"
#include "components/session_manager/core/session_manager_observer.h" #include "components/session_manager/core/session_manager_observer.h"
#include "components/user_manager/user.h" #include "components/user_manager/user.h"
...@@ -76,6 +79,8 @@ class UserSelectionScreen ...@@ -76,6 +79,8 @@ class UserSelectionScreen
void InitEasyUnlock(); void InitEasyUnlock();
void SetTpmLockedState(bool is_locked, base::TimeDelta time_left);
// proximity_auth::ScreenlockBridge::LockHandler implementation: // proximity_auth::ScreenlockBridge::LockHandler implementation:
void ShowBannerMessage(const base::string16& message, void ShowBannerMessage(const base::string16& message,
bool is_warning) override; bool is_warning) override;
...@@ -144,6 +149,7 @@ class UserSelectionScreen ...@@ -144,6 +149,7 @@ class UserSelectionScreen
private: private:
class DircryptoMigrationChecker; class DircryptoMigrationChecker;
class TpmLockedChecker;
EasyUnlockService* GetEasyUnlockServiceForUser( EasyUnlockService* GetEasyUnlockServiceForUser(
const AccountId& account_id) const; const AccountId& account_id) const;
...@@ -173,6 +179,9 @@ class UserSelectionScreen ...@@ -173,6 +179,9 @@ class UserSelectionScreen
// Helper to check whether a user needs dircrypto migration. // Helper to check whether a user needs dircrypto migration.
std::unique_ptr<DircryptoMigrationChecker> dircrypto_migration_checker_; std::unique_ptr<DircryptoMigrationChecker> dircrypto_migration_checker_;
// Helper to check whether TPM is locked or not.
std::unique_ptr<TpmLockedChecker> tpm_locked_checker_;
user_manager::UserList users_to_send_; user_manager::UserList users_to_send_;
AccountId focused_pod_account_id_; AccountId focused_pod_account_id_;
......
...@@ -54,6 +54,10 @@ class UserBoardView { ...@@ -54,6 +54,10 @@ class UserBoardView {
virtual void SetAuthType(const AccountId& account_id, virtual void SetAuthType(const AccountId& account_id,
proximity_auth::mojom::AuthType auth_type, proximity_auth::mojom::AuthType auth_type,
const base::string16& initial_value) = 0; const base::string16& initial_value) = 0;
virtual void SetTpmLockedState(const AccountId& account_id,
bool is_locked,
base::TimeDelta time_left) = 0;
}; };
} // namespace chromeos } // namespace chromeos
......
...@@ -130,6 +130,13 @@ void UserBoardViewMojo::SetAuthType(const AccountId& account_id, ...@@ -130,6 +130,13 @@ void UserBoardViewMojo::SetAuthType(const AccountId& account_id,
} }
} }
void UserBoardViewMojo::SetTpmLockedState(const AccountId& account_id,
bool is_locked,
base::TimeDelta time_left) {
ash::LoginScreen::Get()->GetModel()->SetTpmLockedState(account_id, is_locked,
time_left);
}
base::WeakPtr<UserBoardView> UserBoardViewMojo::GetWeakPtr() { base::WeakPtr<UserBoardView> UserBoardViewMojo::GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
......
...@@ -36,6 +36,9 @@ class UserBoardViewMojo : public UserBoardView { ...@@ -36,6 +36,9 @@ class UserBoardViewMojo : public UserBoardView {
void SetAuthType(const AccountId& account_id, void SetAuthType(const AccountId& account_id,
proximity_auth::mojom::AuthType auth_type, proximity_auth::mojom::AuthType auth_type,
const base::string16& initial_value) override; const base::string16& initial_value) override;
void SetTpmLockedState(const AccountId& account_id,
bool is_locked,
base::TimeDelta time_left) override;
void Bind(UserSelectionScreen* screen) override {} void Bind(UserSelectionScreen* screen) override {}
void Unbind() override {} void Unbind() override {}
base::WeakPtr<UserBoardView> GetWeakPtr() override; base::WeakPtr<UserBoardView> GetWeakPtr() override;
......
...@@ -22,6 +22,9 @@ void TestLoginScreenModel::EnableAuthForUser(const AccountId& account_id) {} ...@@ -22,6 +22,9 @@ void TestLoginScreenModel::EnableAuthForUser(const AccountId& account_id) {}
void TestLoginScreenModel::DisableAuthForUser( void TestLoginScreenModel::DisableAuthForUser(
const AccountId& account_id, const AccountId& account_id,
const ash::AuthDisabledData& auth_disabled_data) {} const ash::AuthDisabledData& auth_disabled_data) {}
void TestLoginScreenModel::SetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left) {}
void TestLoginScreenModel::SetTapToUnlockEnabledForUser( void TestLoginScreenModel::SetTapToUnlockEnabledForUser(
const AccountId& account_id, const AccountId& account_id,
bool enabled) {} bool enabled) {}
......
...@@ -27,6 +27,9 @@ class TestLoginScreenModel : public ash::LoginScreenModel { ...@@ -27,6 +27,9 @@ class TestLoginScreenModel : public ash::LoginScreenModel {
void DisableAuthForUser( void DisableAuthForUser(
const AccountId& account_id, const AccountId& account_id,
const ash::AuthDisabledData& auth_disabled_data) override; const ash::AuthDisabledData& auth_disabled_data) override;
void SetTpmLockedState(const AccountId& user,
bool is_locked,
base::TimeDelta time_left) override;
void SetTapToUnlockEnabledForUser(const AccountId& account_id, void SetTapToUnlockEnabledForUser(const AccountId& account_id,
bool enabled) override; bool enabled) override;
void ForceOnlineSignInForUser(const AccountId& account_id) override; void ForceOnlineSignInForUser(const AccountId& account_id) override;
......
...@@ -94,6 +94,10 @@ void UserBoardScreenHandler::SetAuthType( ...@@ -94,6 +94,10 @@ void UserBoardScreenHandler::SetAuthType(
static_cast<int>(auth_type), base::Value(initial_value)); static_cast<int>(auth_type), base::Value(initial_value));
} }
void UserBoardScreenHandler::SetTpmLockedState(const AccountId& account_id,
bool is_locked,
base::TimeDelta time_left) {}
void UserBoardScreenHandler::Bind(UserSelectionScreen* screen) { void UserBoardScreenHandler::Bind(UserSelectionScreen* screen) {
screen_ = screen; screen_ = screen;
SetBaseScreen(screen_); SetBaseScreen(screen_);
......
...@@ -58,6 +58,10 @@ class UserBoardScreenHandler : public BaseScreenHandler, public UserBoardView { ...@@ -58,6 +58,10 @@ class UserBoardScreenHandler : public BaseScreenHandler, public UserBoardView {
void SetAuthType(const AccountId& account_id, void SetAuthType(const AccountId& account_id,
proximity_auth::mojom::AuthType auth_type, proximity_auth::mojom::AuthType auth_type,
const base::string16& initial_value) override; const base::string16& initial_value) override;
void SetTpmLockedState(const AccountId& account_id,
bool is_locked,
base::TimeDelta time_left) override;
void Bind(UserSelectionScreen* screen) override; void Bind(UserSelectionScreen* screen) override;
void Unbind() override; void Unbind() override;
base::WeakPtr<UserBoardView> GetWeakPtr() override; base::WeakPtr<UserBoardView> GetWeakPtr() override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment