Commit 244f3943 authored by Fabian Sommer's avatar Fabian Sommer Committed by Commit Bot

Add UI for security token session end notification

Users who log in with a security token (smart card) can be required to
keep their smart card inserted at all times. If they remove their smart
card, they are logged out or the session will be locked. This behavior
is controlled by two policies SecurityTokenSessionBehavior and
SecurityTokenSessionNotificationSeconds.

This CL adds UI for this: A notification that informs the user they are
about to be logged out unless they re-insert their smart card.

The UI will be wired up with the controller for this behavior in a
follow-up CL.

Bug: 1131450
Change-Id: Ifc16c5720ab8da4b5a1678db6d06ed8ce321dc57
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2480082Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarNancy Wang <nancylingwang@chromium.org>
Commit-Queue: Fabian Sommer <fabiansommer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825327}
parent f230d9a5
......@@ -96,6 +96,7 @@
#include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "components/user_manager/user_type.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/accelerator_manager.h"
......@@ -1281,7 +1282,7 @@ void NotifyAccessibilityFeatureDisabledByAdmin(
feature_state ? IDS_ASH_ACCESSIBILITY_FEATURE_ACTIVATED
: IDS_ASH_ACCESSIBILITY_FEATURE_DEACTIVATED),
l10n_util::GetStringUTF16(feature_name_id)),
notification_id, kLoginScreenEnterpriseIcon);
notification_id, chromeos::kEnterpriseIcon);
}
void RemoveStickyNotitification(const std::string& notification_id) {
......
......@@ -55,6 +55,7 @@
#include "chromeos/components/proximity_auth/public/mojom/auth_type.mojom.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/user_type.h"
#include "ui/accessibility/ax_node_data.h"
......@@ -776,7 +777,7 @@ void LockContentsView::ShowEnterpriseDomainManager(
if (!chromeos::features::IsLoginDeviceManagementDisclosureEnabled())
return;
bottom_status_indicator_->SetIcon(
kLoginScreenEnterpriseIcon,
chromeos::kEnterpriseIcon,
AshColorProvider::ContentLayerType::kIconColorPrimary);
bottom_status_indicator_->SetText(l10n_util::GetStringFUTF16(
IDS_ASH_LOGIN_MANAGED_DEVICE_INDICATOR, ui::GetChromeOSDeviceName(),
......
......@@ -22,6 +22,7 @@
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "components/user_manager/user_type.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -103,7 +104,7 @@ class IconRoundedView : public views::View {
public:
IconRoundedView(int size) : radius_(size / 2) {
icon_ = gfx::ImageSkiaOperations::CreateResizedImage(
gfx::CreateVectorIcon(kLoginScreenEnterpriseIcon, gfx::kGoogleGrey500),
gfx::CreateVectorIcon(chromeos::kEnterpriseIcon, gfx::kGoogleGrey500),
skia::ImageOperations::RESIZE_BEST,
gfx::Size(size * kIconProportion, size * kIconProportion));
}
......
......@@ -79,7 +79,6 @@ aggregate_vector_icons("ash_vector_icons") {
"lock_screen_time_limit_moon.icon",
"lock_screen_time_limit_timer.icon",
"login_screen_button_dropdown.icon",
"login_screen_enterprise.icon",
"login_screen_menu_dropdown.icon",
"mic.icon",
"music_note.icon",
......
......@@ -40,6 +40,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "chromeos/constants/chromeos_switches.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "skia/ext/image_operations.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -554,7 +555,7 @@ LoginShelfView::LoginShelfView(
&LoginScreenController::HandleAccelerator,
base::Unretained(Shell::Get()->login_screen_controller()),
ash::LoginAcceleratorAction::kStartEnrollment),
IDS_ASH_ENTERPRISE_ENROLLMENT_BUTTON, kLoginScreenEnterpriseIcon);
IDS_ASH_ENTERPRISE_ENROLLMENT_BUTTON, chromeos::kEnterpriseIcon);
// Adds observers for states that affect the visiblity of different buttons.
tray_action_observer_.Add(Shell::Get()->tray_action());
......
......@@ -18,6 +18,7 @@
#include "ash/system/tray/size_range_layout.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/unfocusable_label.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/insets.h"
......@@ -350,7 +351,7 @@ void TrayPopupUtils::InitializeAsCheckableRow(HoverHighlightView* container,
AshColorProvider::ContentLayerType::kIconColorProminent));
if (enterprise_managed) {
gfx::ImageSkia enterprise_managed_icon = CreateVectorIcon(
kLoginScreenEnterpriseIcon, dip_size, gfx::kGoogleGrey100);
chromeos::kEnterpriseIcon, dip_size, gfx::kGoogleGrey100);
container->AddRightIcon(enterprise_managed_icon,
enterprise_managed_icon.width());
}
......
......@@ -5878,4 +5878,40 @@ You can manage this account’s settings by installing the Family Link app on yo
Can’t connect to proxy, please sign in again
</message>
<!-- Strings for Security Token Sessions -->
<message name="IDS_SECURITY_TOKEN_SESSION_LOGOUT_NOTIFICATION_BUTTON_TITLE" desc="This belongs to a notification that informs the user that they will be logged out in a few seconds. This string is the title of a button with which the user can log out immediately.">
Sign out now
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_LOGOUT_NOTIFICATION_TITLE" desc="This is the title of a notification informing the user that they will be logged out soon, unless they re-insert the smart card they used to log into the session. The notification appears when they remove this smart card.">
Insert smart card to stay signed in
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_LOGOUT_NOTIFICATION_BODY" desc="This is the text of a notification informing the user that they will be logged out soon, unless they re-insert the smart card they used to log into the session. The notification appears when they remove this smart card.">
{0, plural,
=1 {You will be automatically signed out in # second.
<ph name="DOMAIN">{1}<ex>example.com</ex></ph> requires you to keep your smart card inserted.}
other {You will be automatically signed out in # seconds.
<ph name="DOMAIN">{1}<ex>example.com</ex></ph> requires you to keep your smart card inserted.}}
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_IMMEDIATE_LOGOUT_NOTIFICATION_BODY" desc="This is the text of a notification informing the user that they will be logged out now because they removed their smart card.">
You will be automatically signed out now.
<ph name="DOMAIN">{0}<ex>example.com</ex></ph> requires you to keep your smart card inserted.
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_LOCK_NOTIFICATION_BUTTON_TITLE" desc="This belongs to a notification that informs the user that the session will be locked in a few seconds. This string is the title of a button with which the user can lock the session immediately.">
Lock now
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_LOCK_NOTIFICATION_TITLE" desc="This is the title of a notification informing the user that the session will be locked soon, unless they re-insert the smart card they used to log into the session. The notification appears when they remove this smart card.">
Insert smart card to keep using your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_LOCK_NOTIFICATION_BODY" desc="This is the text of a notification informing the user that the session will be locked soon, unless they re-insert the smart card they used to log into the session. The notification appears when they remove this smart card.">
{0, plural,
=1 {Your <ph name="DEVICE_TYPE">{1}<ex>Chromebook</ex></ph> will be locked automatically in # second.
<ph name="DOMAIN">{2}<ex>example.com</ex></ph> requires you to keep your smart card inserted.}
other {Your <ph name="DEVICE_TYPE">{1}<ex>Chromebook</ex></ph> will be locked automatically in # seconds.
<ph name="DOMAIN">{2}<ex>example.com</ex></ph> requires you to keep your smart card inserted.}}
</message>
<message name="IDS_SECURITY_TOKEN_SESSION_IMMEDIATE_LOCK_NOTIFICATION_BODY" desc="This is the text of a notification informing the user that the session will be locked now because they removed their smart card.">
Your <ph name="DEVICE_TYPE">{0}<ex>Chromebook</ex></ph> will be locked now.
<ph name="DOMAIN">{1}<ex>example.com</ex></ph> requires you to keep your smart card inserted.
</message>
</grit-part>
e55a02acc082d1975642cdbc7511c907cc7ddd1e
\ No newline at end of file
e55a02acc082d1975642cdbc7511c907cc7ddd1e
\ No newline at end of file
e55a02acc082d1975642cdbc7511c907cc7ddd1e
\ No newline at end of file
d4d819793c73d3232d4d3347c6b0c3b123b61465
\ No newline at end of file
d4d819793c73d3232d4d3347c6b0c3b123b61465
\ No newline at end of file
......@@ -2010,6 +2010,8 @@ static_library("ui") {
"ash/screen_orientation_delegate_chromeos.h",
"ash/screenshot_area.cc",
"ash/screenshot_area.h",
"ash/security_token_session_restriction_view.cc",
"ash/security_token_session_restriction_view.h",
"ash/session_controller_client_impl.cc",
"ash/session_controller_client_impl.h",
"ash/session_util.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/ash/security_token_session_restriction_view.h"
#include "base/i18n/message_formatter.h"
#include "base/strings/string16.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/time_format.h"
#include "ui/base/ui_base_types.h"
#include "ui/chromeos/devicetype_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
namespace {
constexpr base::TimeDelta kCountdownUpdateInterval =
base::TimeDelta::FromMilliseconds(1000);
constexpr base::TimeDelta kLastUpdateTime =
base::TimeDelta::FromMilliseconds(1000);
gfx::ImageSkia GetImage() {
return gfx::CreateVectorIcon(chromeos::kEnterpriseIcon, 20, SK_ColorDKGRAY);
}
base::string16 GetTitle(
chromeos::login::SecurityTokenSessionController::Behavior behavior) {
switch (behavior) {
case chromeos::login::SecurityTokenSessionController::Behavior::kLogout:
return l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_LOGOUT_NOTIFICATION_TITLE);
case chromeos::login::SecurityTokenSessionController::Behavior::kLock:
return l10n_util::GetStringFUTF16(
IDS_SECURITY_TOKEN_SESSION_LOCK_NOTIFICATION_TITLE,
ui::GetChromeOSDeviceName());
case chromeos::login::SecurityTokenSessionController::Behavior::kIgnore:
// Intentionally falling through to NOTREACHED().
break;
}
NOTREACHED();
return base::string16();
}
base::string16 GetButtonLabel(
chromeos::login::SecurityTokenSessionController::Behavior behavior) {
switch (behavior) {
case chromeos::login::SecurityTokenSessionController::Behavior::kLogout:
return l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_LOGOUT_NOTIFICATION_BUTTON_TITLE);
case chromeos::login::SecurityTokenSessionController::Behavior::kLock:
return l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_LOCK_NOTIFICATION_BUTTON_TITLE);
case chromeos::login::SecurityTokenSessionController::Behavior::kIgnore:
// Intentionally falling through to NOTREACHED().
break;
}
NOTREACHED();
return base::string16();
}
base::string16 GetDialogText(
chromeos::login::SecurityTokenSessionController::Behavior behavior,
const std::string& domain,
base::TimeDelta time_remaining) {
// The text and the arguments required for it depend on both `behavior` and
// `time_remaining`.
switch (behavior) {
case chromeos::login::SecurityTokenSessionController::Behavior::kLogout:
if (time_remaining <= kLastUpdateTime) {
return base::i18n::MessageFormatter::FormatWithNumberedArgs(
l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_IMMEDIATE_LOGOUT_NOTIFICATION_BODY),
domain);
}
return base::i18n::MessageFormatter::FormatWithNumberedArgs(
l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_LOGOUT_NOTIFICATION_BODY),
time_remaining.InSeconds(), domain);
case chromeos::login::SecurityTokenSessionController::Behavior::kLock:
if (time_remaining <= kLastUpdateTime) {
return base::i18n::MessageFormatter::FormatWithNumberedArgs(
l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_IMMEDIATE_LOCK_NOTIFICATION_BODY),
ui::GetChromeOSDeviceName(), domain);
}
return base::i18n::MessageFormatter::FormatWithNumberedArgs(
l10n_util::GetStringUTF16(
IDS_SECURITY_TOKEN_SESSION_LOCK_NOTIFICATION_BODY),
time_remaining.InSeconds(), ui::GetChromeOSDeviceName(), domain);
case chromeos::login::SecurityTokenSessionController::Behavior::kIgnore:
break;
}
NOTREACHED();
return base::string16();
}
} // namespace
SecurityTokenSessionRestrictionView::SecurityTokenSessionRestrictionView(
base::TimeDelta duration,
base::OnceClosure accept_callback,
base::OnceClosure window_closing_callback,
chromeos::login::SecurityTokenSessionController::Behavior behavior,
const std::string& domain)
: AppDialogView(GetImage()),
behavior_(behavior),
clock_(base::DefaultTickClock::GetInstance()),
domain_(domain),
end_time_(base::TimeTicks::Now() + duration) {
SetModalType(ui::MODAL_TYPE_SYSTEM);
SetButtonLabel(ui::DIALOG_BUTTON_OK, GetButtonLabel(behavior));
SetTitle(GetTitle(behavior));
SetAcceptCallback(std::move(accept_callback));
RegisterWindowClosingCallback(std::move(window_closing_callback));
InitializeView(/*heading_text=*/base::string16());
UpdateLabel();
update_timer_.Start(FROM_HERE, kCountdownUpdateInterval, this,
&SecurityTokenSessionRestrictionView::UpdateLabel);
}
SecurityTokenSessionRestrictionView::~SecurityTokenSessionRestrictionView() =
default;
void SecurityTokenSessionRestrictionView::UpdateLabel() {
const base::TimeDelta time_remaining = end_time_ - clock_->NowTicks();
SetLabelText(GetDialogText(behavior_, domain_, time_remaining));
if (time_remaining < kLastUpdateTime) {
update_timer_.Stop();
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_ASH_SECURITY_TOKEN_SESSION_RESTRICTION_VIEW_H_
#define CHROME_BROWSER_UI_ASH_SECURITY_TOKEN_SESSION_RESTRICTION_VIEW_H_
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/login/security_token_session_controller.h"
#include "chrome/browser/ui/views/apps/app_dialog/app_dialog_view.h"
// The dialog informing the user they are about to be logged out or locked
// because they removed their security token (smart card).
class SecurityTokenSessionRestrictionView : public AppDialogView {
public:
// Creates the dialog.
// `duration`: Initial countdown time, will be displayed in seconds.
// `accept_callback`: Callback when the user accepts the dialog.
// `windows_closing_callback`: Callback when the window closes for any reason.
// `behavior`: Determines the displayed strings. Needs to be
// chromeos::login::SecurityTokenSessionController::Behavior::kLogout or
// chromeos::login::SecurityTokenSessionController::Behavior::kLock.
// `domain`: The domain the device is enrolled in.
SecurityTokenSessionRestrictionView(
base::TimeDelta duration,
base::OnceClosure accept_callback,
base::OnceClosure window_closing_callback,
chromeos::login::SecurityTokenSessionController::Behavior behavior,
const std::string& domain);
SecurityTokenSessionRestrictionView(
const SecurityTokenSessionRestrictionView& other) = delete;
SecurityTokenSessionRestrictionView& operator=(
const SecurityTokenSessionRestrictionView& other) = delete;
~SecurityTokenSessionRestrictionView() override;
private:
void UpdateLabel();
const chromeos::login::SecurityTokenSessionController::Behavior behavior_;
const base::TickClock* clock_;
const std::string domain_;
base::TimeTicks end_time_;
base::RepeatingTimer update_timer_;
};
#endif // CHROME_BROWSER_UI_ASH_SECURITY_TOKEN_SESSION_RESTRICTION_VIEW_H_
......@@ -31,8 +31,13 @@ void AppDialogView::InitializeView(const base::string16& heading_text) {
views::BoxLayout::Orientation::kVertical, gfx::Insets(),
provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
auto* label = AddChildView(std::make_unique<views::Label>(heading_text));
label->SetMultiLine(true);
label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
label->SetAllowCharacterBreak(true);
label_ = AddChildView(std::make_unique<views::Label>(heading_text));
label_->SetMultiLine(true);
label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
label_->SetAllowCharacterBreak(true);
}
void AppDialogView::SetLabelText(const base::string16& text) {
DCHECK(label_);
label_->SetText(text);
}
......@@ -7,6 +7,7 @@
#include "base/strings/string16.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/label.h"
namespace gfx {
class ImageSkia;
......@@ -21,6 +22,12 @@ class AppDialogView : public views::BubbleDialogDelegateView {
protected:
void InitializeView(const base::string16& heading_text);
// Can only be called after InitializeView().
void SetLabelText(const base::string16& text);
private:
views::Label* label_ = nullptr;
};
#endif // CHROME_BROWSER_UI_VIEWS_APPS_APP_DIALOG_APP_DIALOG_VIEW_H_
......@@ -13,6 +13,7 @@ aggregate_vector_icons("chromeos_ui_vector_icons") {
"assistant.icon",
"calculate.icon",
"conversion_path.icon",
"enterprise.icon",
"filetype_archive.icon",
"filetype_audio.icon",
"filetype_chart.icon",
......
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