Commit ea1dfaf4 authored by Balazs Engedy's avatar Balazs Engedy Committed by Commit Bot

WebAuthn: Add TransportListView and its model.

TransportListView displays a list of transports over which the user can
access security keys.

Bug: 849323
Change-Id: Id445b7fea711f8b3e482588cc3d6213e3221d3be
Reviewed-on: https://chromium-review.googlesource.com/1097775
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568410}
parent d52474c3
...@@ -10544,6 +10544,21 @@ Please help our engineers fix this problem. Tell us what happened right before y ...@@ -10544,6 +10544,21 @@ Please help our engineers fix this problem. Tell us what happened right before y
<message name="IDS_WEBAUTHN_DIALOG_DESCRIPTION" desc="Contents of the dialog shown when a web site wants to register/verify a user's security key through the Web Authentication API."> <message name="IDS_WEBAUTHN_DIALOG_DESCRIPTION" desc="Contents of the dialog shown when a web site wants to register/verify a user's security key through the Web Authentication API.">
The site wants to verify your Security Key for added security for your account. The site wants to verify your Security Key for added security for your account.
</message> </message>
<message name="IDS_WEBAUTHN_TRANSPORT_BLE" desc="Use a Security Key with the Web Authentication API over Bluetooth Low Energy.">
Use your Security Key with Bluetooth
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_USB" desc="Use a Security Key with the Web Authentication API over Universal Serial Bus (USB).">
Use your Security Key with USB
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_NFC" desc="Use a Security Key with the Web Authentication API over Near-Field Communication (NFC).">
Use your Security Key with NFC
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_INTERNAL" desc="Use a Security Key with the Web Authentication API that is built in to the platform, such as Touch ID or Face ID.">
Use a built-in Security Key
</message>
<message name="IDS_WEBAUTHN_TRANSPORT_CABLE" desc="Use a phone as a Security Key over cloud-assisted BLE with the Web Authentication API.">
Use your phone as a Security Key
</message>
</messages> </messages>
</release> </release>
</grit> </grit>
...@@ -18,6 +18,7 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -18,6 +18,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"apps.icon", "apps.icon",
"blocked_badge.icon", "blocked_badge.icon",
"blocked_redirect.icon", "blocked_redirect.icon",
"bluetooth.icon",
"browser_tools.icon", "browser_tools.icon",
"browser_tools_animated.icon", "browser_tools_animated.icon",
"browser_tools_error.icon", "browser_tools_error.icon",
...@@ -47,6 +48,7 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -47,6 +48,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"extension_crashed.icon", "extension_crashed.icon",
"file_download.icon", "file_download.icon",
"file_download_shelf.icon", "file_download_shelf.icon",
"fingerprint.icon",
"folder.icon", "folder.icon",
"folder_supervised.icon", "folder_supervised.icon",
"forward_arrow_touch.icon", "forward_arrow_touch.icon",
...@@ -66,6 +68,7 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -66,6 +68,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"navigate_stop_touch.icon", "navigate_stop_touch.icon",
"new_tab_button_incognito.icon", "new_tab_button_incognito.icon",
"new_tab_button_plus.icon", "new_tab_button_plus.icon",
"nfc.icon",
"overflow_chevron.icon", "overflow_chevron.icon",
"page_info_content_paste.icon", "page_info_content_paste.icon",
"paintbrush.icon", "paintbrush.icon",
......
// Copyright 2018 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 17.71f, 7.71f,
LINE_TO, 12, 2,
R_H_LINE_TO, -1,
R_V_LINE_TO, 7.59f,
LINE_TO, 6.41f, 5,
LINE_TO, 5, 6.41f,
LINE_TO, 10.59f, 12,
LINE_TO, 5, 17.59f,
LINE_TO, 6.41f, 19,
LINE_TO, 11, 14.41f,
V_LINE_TO, 22,
R_H_LINE_TO, 1,
R_LINE_TO, 5.71f, -5.71f,
R_LINE_TO, -4.3f, -4.29f,
R_LINE_TO, 4.3f, -4.29f,
CLOSE,
MOVE_TO, 13, 5.83f,
R_LINE_TO, 1.88f, 1.88f,
LINE_TO, 13, 9.59f,
V_LINE_TO, 5.83f,
CLOSE,
R_MOVE_TO, 1.88f, 10.46f,
LINE_TO, 13, 18.17f,
R_V_LINE_TO, -3.76f,
R_LINE_TO, 1.88f, 1.88f,
CLOSE
// Copyright 2018 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 17.81f, 4.47f,
R_CUBIC_TO, -0.08f, 0, -0.16f, -0.02f, -0.23f, -0.06f,
CUBIC_TO, 15.66f, 3.42f, 14, 3, 12.01f, 3,
R_CUBIC_TO, -1.98f, 0, -3.86f, 0.47f, -5.57f, 1.41f,
R_CUBIC_TO, -0.24f, 0.13f, -0.54f, 0.04f, -0.68f, -0.2f,
R_CUBIC_TO, -0.13f, -0.24f, -0.04f, -0.55f, 0.2f, -0.68f,
CUBIC_TO, 7.82f, 2.52f, 9.86f, 2, 12.01f, 2,
R_CUBIC_TO, 2.13f, 0, 3.99f, 0.47f, 6.03f, 1.52f,
R_CUBIC_TO, 0.25f, 0.13f, 0.34f, 0.43f, 0.21f, 0.67f,
R_CUBIC_TO, -0.09f, 0.18f, -0.26f, 0.28f, -0.44f, 0.28f,
CLOSE,
MOVE_TO, 3.5f, 9.72f,
R_CUBIC_TO, -0.1f, 0, -0.2f, -0.03f, -0.29f, -0.09f,
R_CUBIC_TO, -0.23f, -0.16f, -0.28f, -0.47f, -0.12f, -0.7f,
R_CUBIC_TO, 0.99f, -1.4f, 2.25f, -2.5f, 3.75f, -3.27f,
CUBIC_TO, 9.98f, 4.04f, 14, 4.03f, 17.15f, 5.65f,
R_CUBIC_TO, 1.5f, 0.77f, 2.76f, 1.86f, 3.75f, 3.25f,
R_CUBIC_TO, 0.16f, 0.22f, 0.11f, 0.54f, -0.12f, 0.7f,
R_CUBIC_TO, -0.23f, 0.16f, -0.54f, 0.11f, -0.7f, -0.12f,
R_CUBIC_TO, -0.9f, -1.26f, -2.04f, -2.25f, -3.39f, -2.94f,
R_CUBIC_TO, -2.87f, -1.47f, -6.54f, -1.47f, -9.4f, 0.01f,
R_CUBIC_TO, -1.36f, 0.7f, -2.5f, 1.7f, -3.4f, 2.96f,
R_CUBIC_TO, -0.08f, 0.14f, -0.23f, 0.21f, -0.39f, 0.21f,
CLOSE,
R_MOVE_TO, 6.25f, 12.07f,
R_CUBIC_TO, -0.13f, 0, -0.26f, -0.05f, -0.35f, -0.15f,
R_CUBIC_TO, -0.87f, -0.87f, -1.34f, -1.43f, -2.01f, -2.64f,
R_CUBIC_TO, -0.69f, -1.23f, -1.05f, -2.73f, -1.05f, -4.34f,
R_CUBIC_TO, 0, -2.97f, 2.54f, -5.39f, 5.66f, -5.39f,
R_CUBIC_TO, 3.12f, 0, 5.66f, 2.42f, 5.66f, 5.39f,
R_CUBIC_TO, 0, 0.28f, -0.22f, 0.5f, -0.5f, 0.5f,
R_CUBIC_TO, -0.28f, 0, -0.5f, -0.22f, -0.5f, -0.5f,
R_CUBIC_TO, 0, -2.42f, -2.09f, -4.39f, -4.66f, -4.39f,
R_CUBIC_TO, -2.57f, 0, -4.66f, 1.97f, -4.66f, 4.39f,
R_CUBIC_TO, 0, 1.44f, 0.32f, 2.77f, 0.93f, 3.85f,
R_CUBIC_TO, 0.64f, 1.15f, 1.08f, 1.64f, 1.85f, 2.42f,
R_CUBIC_TO, 0.19f, 0.2f, 0.19f, 0.51f, 0, 0.71f,
R_CUBIC_TO, -0.11f, 0.1f, -0.24f, 0.15f, -0.37f, 0.15f,
CLOSE,
R_MOVE_TO, 7.17f, -1.85f,
R_CUBIC_TO, -1.19f, 0, -2.24f, -0.3f, -3.1f, -0.89f,
R_CUBIC_TO, -1.49f, -1.01f, -2.38f, -2.65f, -2.38f, -4.39f,
R_CUBIC_TO, 0, -0.28f, 0.22f, -0.5f, 0.5f, -0.5f,
R_CUBIC_TO, 0.28f, 0, 0.5f, 0.22f, 0.5f, 0.5f,
R_CUBIC_TO, 0, 1.41f, 0.72f, 2.74f, 1.94f, 3.56f,
R_CUBIC_TO, 0.71f, 0.48f, 1.54f, 0.71f, 2.54f, 0.71f,
R_CUBIC_TO, 0.24f, 0, 0.64f, -0.03f, 1.04f, -0.1f,
R_CUBIC_TO, 0.27f, -0.05f, 0.53f, 0.13f, 0.58f, 0.41f,
R_CUBIC_TO, 0.05f, 0.27f, -0.13f, 0.53f, -0.41f, 0.58f,
R_CUBIC_TO, -0.57f, 0.11f, -1.07f, 0.12f, -1.21f, 0.12f,
CLOSE,
MOVE_TO, 14.91f, 22,
R_CUBIC_TO, -0.04f, 0, -0.09f, -0.01f, -0.13f, -0.02f,
R_CUBIC_TO, -1.59f, -0.44f, -2.63f, -1.03f, -3.72f, -2.1f,
R_CUBIC_TO, -1.4f, -1.39f, -2.17f, -3.24f, -2.17f, -5.22f,
R_CUBIC_TO, 0, -1.62f, 1.38f, -2.94f, 3.08f, -2.94f,
R_CUBIC_TO, 1.7f, 0, 3.08f, 1.32f, 3.08f, 2.94f,
R_CUBIC_TO, 0, 1.07f, 0.93f, 1.94f, 2.08f, 1.94f,
R_CUBIC_TO, 1.15f, 0, 2.08f, -0.87f, 2.08f, -1.94f,
R_CUBIC_TO, 0, -3.77f, -3.25f, -6.83f, -7.25f, -6.83f,
R_CUBIC_TO, -2.84f, 0, -5.44f, 1.58f, -6.61f, 4.03f,
R_CUBIC_TO, -0.39f, 0.81f, -0.59f, 1.76f, -0.59f, 2.8f,
R_CUBIC_TO, 0, 0.78f, 0.07f, 2.01f, 0.67f, 3.61f,
R_CUBIC_TO, 0.1f, 0.26f, -0.03f, 0.55f, -0.29f, 0.64f,
R_CUBIC_TO, -0.26f, 0.1f, -0.55f, -0.04f, -0.64f, -0.29f,
R_CUBIC_TO, -0.49f, -1.31f, -0.73f, -2.61f, -0.73f, -3.96f,
R_CUBIC_TO, 0, -1.2f, 0.23f, -2.29f, 0.68f, -3.24f,
R_CUBIC_TO, 1.33f, -2.79f, 4.28f, -4.6f, 7.51f, -4.6f,
R_CUBIC_TO, 4.55f, 0, 8.25f, 3.51f, 8.25f, 7.83f,
R_CUBIC_TO, 0, 1.62f, -1.38f, 2.94f, -3.08f, 2.94f,
R_CUBIC_TO, -1.7f, 0, -3.08f, -1.32f, -3.08f, -2.94f,
R_CUBIC_TO, 0, -1.07f, -0.93f, -1.94f, -2.08f, -1.94f,
R_CUBIC_TO, -1.15f, 0, -2.08f, 0.87f, -2.08f, 1.94f,
R_CUBIC_TO, 0, 1.71f, 0.66f, 3.31f, 1.87f, 4.51f,
R_CUBIC_TO, 0.95f, 0.94f, 1.86f, 1.46f, 3.27f, 1.85f,
R_CUBIC_TO, 0.27f, 0.07f, 0.42f, 0.35f, 0.35f, 0.61f,
R_CUBIC_TO, -0.05f, 0.23f, -0.26f, 0.38f, -0.47f, 0.38f,
CLOSE
// Copyright 2018 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 20, 2,
H_LINE_TO, 4,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
R_V_LINE_TO, 16,
R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2,
R_H_LINE_TO, 16,
R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2,
V_LINE_TO, 4,
R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2,
CLOSE,
R_MOVE_TO, 0, 18,
H_LINE_TO, 4,
V_LINE_TO, 4,
R_H_LINE_TO, 16,
R_V_LINE_TO, 16,
CLOSE,
MOVE_TO, 18, 6,
R_H_LINE_TO, -5,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
R_V_LINE_TO, 2.28f,
R_CUBIC_TO, -0.6f, 0.35f, -1, 0.98f, -1, 1.72f,
R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2,
R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2,
R_CUBIC_TO, 0, -0.74f, -0.4f, -1.38f, -1, -1.72f,
V_LINE_TO, 8,
R_H_LINE_TO, 3,
R_V_LINE_TO, 8,
H_LINE_TO, 8,
V_LINE_TO, 8,
R_H_LINE_TO, 2,
V_LINE_TO, 6,
H_LINE_TO, 6,
R_V_LINE_TO, 12,
R_H_LINE_TO, 12,
V_LINE_TO, 6,
CLOSE
...@@ -1557,6 +1557,8 @@ jumbo_split_static_library("browser") { ...@@ -1557,6 +1557,8 @@ jumbo_split_static_library("browser") {
"webauthn/authenticator_request_scheduler.h", "webauthn/authenticator_request_scheduler.h",
"webauthn/chrome_authenticator_request_delegate.cc", "webauthn/chrome_authenticator_request_delegate.cc",
"webauthn/chrome_authenticator_request_delegate.h", "webauthn/chrome_authenticator_request_delegate.h",
"webauthn/transport_list_model.cc",
"webauthn/transport_list_model.h",
"webshare/share_target_pref_helper.cc", "webshare/share_target_pref_helper.cc",
"webshare/share_target_pref_helper.h", "webshare/share_target_pref_helper.h",
"webshare/webshare_target.cc", "webshare/webshare_target.cc",
......
...@@ -2996,8 +2996,12 @@ split_static_library("ui") { ...@@ -2996,8 +2996,12 @@ split_static_library("ui") {
"views/webauthn/authenticator_request_dialog_view.h", "views/webauthn/authenticator_request_dialog_view.h",
"views/webauthn/authenticator_request_sheet_view.cc", "views/webauthn/authenticator_request_sheet_view.cc",
"views/webauthn/authenticator_request_sheet_view.h", "views/webauthn/authenticator_request_sheet_view.h",
"views/webauthn/authenticator_transport_selector_sheet_view.cc",
"views/webauthn/authenticator_transport_selector_sheet_view.h",
"views/webauthn/sheet_view_factory.cc", "views/webauthn/sheet_view_factory.cc",
"views/webauthn/sheet_view_factory.h", "views/webauthn/sheet_view_factory.h",
"views/webauthn/transport_list_view.cc",
"views/webauthn/transport_list_view.h",
"webauthn/authenticator_request_sheet_model.h", "webauthn/authenticator_request_sheet_model.h",
"webauthn/sheet_models.cc", "webauthn/sheet_models.cc",
"webauthn/sheet_models.h", "webauthn/sheet_models.h",
......
// Copyright 2018 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/views/webauthn/authenticator_transport_selector_sheet_view.h"
#include <utility>
AuthenticatorTransportSelectorSheetView::
AuthenticatorTransportSelectorSheetView(
std::unique_ptr<AuthenticatorTransportSelectorSheetModel> model)
: AuthenticatorRequestSheetView(std::move(model)) {}
AuthenticatorTransportSelectorSheetView::
~AuthenticatorTransportSelectorSheetView() = default;
std::unique_ptr<views::View>
AuthenticatorTransportSelectorSheetView::BuildStepSpecificContent() {
return std::make_unique<TransportListView>(
model()->dialog_model()->transport_list_model(), this);
}
void AuthenticatorTransportSelectorSheetView::OnListItemSelected(
AuthenticatorTransport transport) {
model()->OnTransportSelected(transport);
}
// Copyright 2018 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_VIEWS_WEBAUTHN_AUTHENTICATOR_TRANSPORT_SELECTOR_SHEET_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_WEBAUTHN_AUTHENTICATOR_TRANSPORT_SELECTOR_SHEET_VIEW_H_
#include "base/macros.h"
#include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h"
#include "chrome/browser/ui/views/webauthn/transport_list_view.h"
#include "chrome/browser/ui/webauthn/sheet_models.h"
// Represents a sheet in the Web Authentication request dialog that allows the
// user to pick the transport protocol over which they wish to use their
// security key.
class AuthenticatorTransportSelectorSheetView
: public AuthenticatorRequestSheetView,
public TransportListView::Delegate {
public:
explicit AuthenticatorTransportSelectorSheetView(
std::unique_ptr<AuthenticatorTransportSelectorSheetModel> model);
~AuthenticatorTransportSelectorSheetView() override;
private:
AuthenticatorTransportSelectorSheetModel* model() {
return static_cast<AuthenticatorTransportSelectorSheetModel*>(
AuthenticatorRequestSheetView::model());
}
// AuthenticatorRequestSheetView:
std::unique_ptr<views::View> BuildStepSpecificContent() override;
// TransportListView::Delegate:
void OnListItemSelected(AuthenticatorTransport transport) override;
DISALLOW_COPY_AND_ASSIGN(AuthenticatorTransportSelectorSheetView);
};
#endif // CHROME_BROWSER_UI_VIEWS_WEBAUTHN_AUTHENTICATOR_TRANSPORT_SELECTOR_SHEET_VIEW_H_
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h" #include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h"
#include "chrome/browser/ui/views/webauthn/authenticator_transport_selector_sheet_view.h"
#include "chrome/browser/ui/webauthn/sheet_models.h" #include "chrome/browser/ui/webauthn/sheet_models.h"
#include "chrome/browser/webauthn/authenticator_request_dialog_model.h" #include "chrome/browser/webauthn/authenticator_request_dialog_model.h"
...@@ -37,6 +38,10 @@ std::unique_ptr<AuthenticatorRequestSheetView> CreateSheetViewForCurrentStepOf( ...@@ -37,6 +38,10 @@ std::unique_ptr<AuthenticatorRequestSheetView> CreateSheetViewForCurrentStepOf(
std::make_unique<AuthenticatorInitialSheetModel>(dialog_model)); std::make_unique<AuthenticatorInitialSheetModel>(dialog_model));
break; break;
case Step::kTransportSelection: case Step::kTransportSelection:
sheet_view = std::make_unique<AuthenticatorTransportSelectorSheetView>(
std::make_unique<AuthenticatorTransportSelectorSheetModel>(
dialog_model));
break;
case Step::kErrorTimedOut: case Step::kErrorTimedOut:
case Step::kCompleted: case Step::kCompleted:
case Step::kUsbInsert: case Step::kUsbInsert:
......
// Copyright 2018 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/views/webauthn/transport_list_view.h"
#include "base/logging.h"
#include "base/strings/string16.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
#include "chrome/browser/ui/views/harmony/chrome_typography.h"
#include "chrome/browser/ui/views/hover_button.h"
#include "chrome/grit/generated_resources.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/separator.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/vector_icons.h"
namespace {
// Gets the message ID for the human readable name of |transport|.
int GetHumanReadableTransportNameMessageId(AuthenticatorTransport transport) {
switch (transport) {
case AuthenticatorTransport::kBluetoothLowEnergy:
return IDS_WEBAUTHN_TRANSPORT_BLE;
case AuthenticatorTransport::kNearFieldCommunication:
return IDS_WEBAUTHN_TRANSPORT_NFC;
case AuthenticatorTransport::kUsb:
return IDS_WEBAUTHN_TRANSPORT_USB;
case AuthenticatorTransport::kInternal:
return IDS_WEBAUTHN_TRANSPORT_INTERNAL;
case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy:
return IDS_WEBAUTHN_TRANSPORT_CABLE;
}
NOTREACHED();
return 0;
}
// Gets the vector icon depicting the given |transport|.
const gfx::VectorIcon& GetTransportVectorIcon(
AuthenticatorTransport transport) {
switch (transport) {
case AuthenticatorTransport::kBluetoothLowEnergy:
return kBluetoothIcon;
case AuthenticatorTransport::kNearFieldCommunication:
return kNfcIcon;
case AuthenticatorTransport::kUsb:
return vector_icons::kUsbIcon;
case AuthenticatorTransport::kInternal:
return kFingerprintIcon;
case AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy:
return kSmartphoneIcon;
}
NOTREACHED();
return kFingerprintIcon;
}
// Creates, for a given transport, the corresponding row in the transport list,
// containing an icon, a human-readable name, and a chevron at the right:
//
// +--------------------------------+
// | ICON | Transport name | > |
// +--------------------------------+
//
std::unique_ptr<HoverButton> CreateTransportListItemView(
AuthenticatorTransport transport,
views::ButtonListener* listener) {
// Derive the icon color from the text color of an enabled label.
auto color_reference_label = std::make_unique<views::Label>(
base::string16(), CONTEXT_BODY_TEXT_SMALL, views::style::STYLE_PRIMARY);
const SkColor icon_color = color_utils::DeriveDefaultIconColor(
color_reference_label->enabled_color());
constexpr int kTransportIconSize = 24;
auto transport_image = std::make_unique<views::ImageView>();
transport_image->SetImage(gfx::CreateVectorIcon(
GetTransportVectorIcon(transport), kTransportIconSize, icon_color));
base::string16 transport_name = l10n_util::GetStringUTF16(
GetHumanReadableTransportNameMessageId(transport));
auto chevron_image = std::make_unique<views::ImageView>();
chevron_image->SetImage(
gfx::CreateVectorIcon(views::kSubmenuArrowIcon, icon_color));
auto hover_button = std::make_unique<HoverButton>(
listener, std::move(transport_image), transport_name,
base::string16() /* subtitle */, std::move(chevron_image));
hover_button->set_tag(static_cast<int>(transport));
return hover_button;
}
void AddSeparatorAsChild(views::View* view) {
auto separator = std::make_unique<views::Separator>();
separator->SetColor(gfx::kGoogleGrey900);
view->AddChildView(separator.release());
}
} // namespace
// TransportListView ---------------------------------------------------------
TransportListView::TransportListView(TransportListModel* model,
Delegate* delegate)
: model_(model), delegate_(delegate) {
DCHECK(model_);
model_->AddObserver(this);
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kVertical, gfx::Insets(), 0));
AddSeparatorAsChild(this);
for (size_t index = 0; index < model_->transports().size(); ++index) {
const std::vector<AuthenticatorTransport>& transports =
model_->transports();
AddViewForListItem(index, transports[index]);
}
}
TransportListView::~TransportListView() {
if (model_) {
model_->RemoveObserver(this);
model_ = nullptr;
}
}
void TransportListView::AddViewForListItem(size_t index,
AuthenticatorTransport transport) {
std::unique_ptr<HoverButton> list_item_view =
CreateTransportListItemView(transport, this);
AddChildView(list_item_view.release());
AddSeparatorAsChild(this);
}
void TransportListView::OnModelDestroyed() {
model_ = nullptr;
}
void TransportListView::OnTransportAppended() {
DCHECK(!model_->transports().empty());
AddViewForListItem(model_->transports().size() - 1,
model_->transports().back());
// TODO(engedy): The enclosing dialog may also need to be resized, similarly
// to what is done in AuthenticatorRequestDialogView::ReplaceSheetWith().
Layout();
}
void TransportListView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
if (!delegate_)
return;
auto transport = static_cast<AuthenticatorTransport>(sender->tag());
delegate_->OnListItemSelected(transport);
}
// Copyright 2018 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_VIEWS_WEBAUTHN_TRANSPORT_LIST_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_WEBAUTHN_TRANSPORT_LIST_VIEW_H_
#include <stddef.h>
#include "base/macros.h"
#include "chrome/browser/webauthn/transport_list_model.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"
// Represents a view that shows a list of transports available on a platform.
//
// +----------------------------------+
// | ICON1 | Transport 1 name | > |
// +----------------------------------+
// | ICON2 | Transport 2 name | > |
// +----------------------------------+
// | ICON3 | Transport 3 name | > |
// +----------------------------------+
//
class TransportListView : public views::View,
public views::ButtonListener,
public TransportListModel::Observer {
public:
// Interface that the client should implement to learn when the user clicks on
// one of the items.
class Delegate {
public:
virtual void OnListItemSelected(AuthenticatorTransport transport) = 0;
};
// The |model| and |delegate| must outlive this object, but the |delegate| may
// be a nullptr.
TransportListView(TransportListModel* model, Delegate* delegate);
~TransportListView() override;
private:
void AddViewForListItem(size_t index, AuthenticatorTransport transport);
// TransportListModel::Observer:
void OnModelDestroyed() override;
void OnTransportAppended() override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
TransportListModel* model_; // Weak.
Delegate* const delegate_; // Weak, may be nullptr.
DISALLOW_COPY_AND_ASSIGN(TransportListView);
};
#endif // CHROME_BROWSER_UI_VIEWS_WEBAUTHN_TRANSPORT_LIST_VIEW_H_
...@@ -22,8 +22,18 @@ class AuthenticatorDialogTest : public DialogBrowserTest { ...@@ -22,8 +22,18 @@ class AuthenticatorDialogTest : public DialogBrowserTest {
// The dialog should immediately close as soon as it is displayed. // The dialog should immediately close as soon as it is displayed.
if (name == "completed") { if (name == "completed") {
model->set_current_step( model->SetCurrentStep(AuthenticatorRequestDialogModel::Step::kCompleted);
AuthenticatorRequestDialogModel::Step::kCompleted); } else if (name == "transports") {
TransportListModel* transports = model->transport_list_model();
transports->AppendTransport(AuthenticatorTransport::kBluetoothLowEnergy);
transports->AppendTransport(AuthenticatorTransport::kUsb);
transports->AppendTransport(
AuthenticatorTransport::kNearFieldCommunication);
transports->AppendTransport(AuthenticatorTransport::kInternal);
transports->AppendTransport(
AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy);
model->SetCurrentStep(
AuthenticatorRequestDialogModel::Step::kTransportSelection);
} }
ShowAuthenticatorRequestDialog( ShowAuthenticatorRequestDialog(
...@@ -44,3 +54,7 @@ IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_default) { ...@@ -44,3 +54,7 @@ IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_default) {
IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_completed) { IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_completed) {
ShowAndVerifyUi(); ShowAndVerifyUi();
} }
IN_PROC_BROWSER_TEST_F(AuthenticatorDialogTest, InvokeUi_transports) {
ShowAndVerifyUi();
}
...@@ -78,3 +78,19 @@ base::string16 AuthenticatorInitialSheetModel::GetStepTitle() const { ...@@ -78,3 +78,19 @@ base::string16 AuthenticatorInitialSheetModel::GetStepTitle() const {
base::string16 AuthenticatorInitialSheetModel::GetStepDescription() const { base::string16 AuthenticatorInitialSheetModel::GetStepDescription() const {
return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_DESCRIPTION); return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_DESCRIPTION);
} }
// AuthenticatorTransportSelectorSheetModel -----------------------------------
base::string16 AuthenticatorTransportSelectorSheetModel::GetStepTitle() const {
return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_TITLE);
}
base::string16 AuthenticatorTransportSelectorSheetModel::GetStepDescription()
const {
return l10n_util::GetStringUTF16(IDS_WEBAUTHN_DIALOG_DESCRIPTION);
}
void AuthenticatorTransportSelectorSheetModel::OnTransportSelected(
AuthenticatorTransport transport) {
dialog_model()->StartGuidedFlowForTransport(transport);
}
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h" #include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h"
#include "chrome/browser/webauthn/authenticator_request_dialog_model.h" #include "chrome/browser/webauthn/authenticator_request_dialog_model.h"
#include "chrome/browser/webauthn/transport_list_model.h"
// Base class for sheets, implementing the shared behavior used on most sheets, // Base class for sheets, implementing the shared behavior used on most sheets,
// as well as maintaining a weak pointer to the dialog model. // as well as maintaining a weak pointer to the dialog model.
...@@ -19,11 +20,11 @@ class AuthenticatorSheetModelBase ...@@ -19,11 +20,11 @@ class AuthenticatorSheetModelBase
AuthenticatorRequestDialogModel* dialog_model); AuthenticatorRequestDialogModel* dialog_model);
~AuthenticatorSheetModelBase() override; ~AuthenticatorSheetModelBase() override;
protected:
AuthenticatorRequestDialogModel* dialog_model() const { AuthenticatorRequestDialogModel* dialog_model() const {
return dialog_model_; return dialog_model_;
} }
protected:
// AuthenticatorRequestSheetModel: // AuthenticatorRequestSheetModel:
bool IsBackButtonVisible() const override; bool IsBackButtonVisible() const override;
bool IsCancelButtonVisible() const override; bool IsCancelButtonVisible() const override;
...@@ -55,4 +56,21 @@ class AuthenticatorInitialSheetModel : public AuthenticatorSheetModelBase { ...@@ -55,4 +56,21 @@ class AuthenticatorInitialSheetModel : public AuthenticatorSheetModelBase {
base::string16 GetStepDescription() const override; base::string16 GetStepDescription() const override;
}; };
// The sheet shown for selecting the transport over which the security key
// should be accessed.
class AuthenticatorTransportSelectorSheetModel
: public AuthenticatorSheetModelBase {
public:
using AuthenticatorSheetModelBase::AuthenticatorSheetModelBase;
// Initiates the step-by-step flow with the the transport at the given |index|
// selected by the user.
void OnTransportSelected(AuthenticatorTransport transport);
private:
// AuthenticatorSheetModelBase:
base::string16 GetStepTitle() const override;
base::string16 GetStepDescription() const override;
};
#endif // CHROME_BROWSER_UI_WEBAUTHN_SHEET_MODELS_H_ #endif // CHROME_BROWSER_UI_WEBAUTHN_SHEET_MODELS_H_
...@@ -10,9 +10,16 @@ AuthenticatorRequestDialogModel::~AuthenticatorRequestDialogModel() { ...@@ -10,9 +10,16 @@ AuthenticatorRequestDialogModel::~AuthenticatorRequestDialogModel() {
observer.OnModelDestroyed(); observer.OnModelDestroyed();
} }
void AuthenticatorRequestDialogModel::SetCurrentStep(Step step) {
current_step_ = step;
for (auto& observer : observers_)
observer.OnStepTransition();
}
void AuthenticatorRequestDialogModel::StartGuidedFlowForTransport( void AuthenticatorRequestDialogModel::StartGuidedFlowForTransport(
int transport) { AuthenticatorTransport transport) {
DCHECK_EQ(current_step(), Step::kTransportSelection); DCHECK_EQ(current_step(), Step::kTransportSelection);
// TODO(engedy): Use transport here.
} }
void AuthenticatorRequestDialogModel::TryIfBleAdapterIsPowered() { void AuthenticatorRequestDialogModel::TryIfBleAdapterIsPowered() {
...@@ -54,11 +61,5 @@ void AuthenticatorRequestDialogModel::RemoveObserver(Observer* observer) { ...@@ -54,11 +61,5 @@ void AuthenticatorRequestDialogModel::RemoveObserver(Observer* observer) {
} }
void AuthenticatorRequestDialogModel::OnRequestComplete() { void AuthenticatorRequestDialogModel::OnRequestComplete() {
current_step_ = Step::kCompleted; SetCurrentStep(Step::kCompleted);
NotifyStepTransition();
}
void AuthenticatorRequestDialogModel::NotifyStepTransition() {
for (auto& observer : observers_)
observer.OnStepTransition();
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_WEBAUTHN_AUTHENTICATOR_REQUEST_DIALOG_MODEL_H_ #define CHROME_BROWSER_WEBAUTHN_AUTHENTICATOR_REQUEST_DIALOG_MODEL_H_
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chrome/browser/webauthn/transport_list_model.h"
// Encapsulates the model behind the Web Authentication request dialog's UX // Encapsulates the model behind the Web Authentication request dialog's UX
// flow. This is essentially a state machine going through the states defined in // flow. This is essentially a state machine going through the states defined in
...@@ -56,15 +57,16 @@ class AuthenticatorRequestDialogModel { ...@@ -56,15 +57,16 @@ class AuthenticatorRequestDialogModel {
AuthenticatorRequestDialogModel(); AuthenticatorRequestDialogModel();
~AuthenticatorRequestDialogModel(); ~AuthenticatorRequestDialogModel();
void set_current_step(Step step) { current_step_ = step; } void SetCurrentStep(Step step);
Step current_step() const { return current_step_; } Step current_step() const { return current_step_; }
TransportListModel* transport_list_model() { return &transport_list_model_; }
// Requests that the step-by-step wizard flow commence, guiding the user // Requests that the step-by-step wizard flow commence, guiding the user
// through using the Secutity Key with the given |transport|. // through using the Secutity Key with the given |transport|.
// //
// Valid action when at step: kTransportSelection. // Valid action when at step: kTransportSelection.
// TODO(engedy): Use AuthenticatorTransport type when ready. void StartGuidedFlowForTransport(AuthenticatorTransport transport);
void StartGuidedFlowForTransport(int transport);
// Tries if the BLE adapter is now powered -- the user claims they turned it // Tries if the BLE adapter is now powered -- the user claims they turned it
// on. // on.
...@@ -117,12 +119,10 @@ class AuthenticatorRequestDialogModel { ...@@ -117,12 +119,10 @@ class AuthenticatorRequestDialogModel {
void OnRequestComplete(); void OnRequestComplete();
private: private:
// Notifies observers when a step transition has occurred.
void NotifyStepTransition();
// The current step of the request UX flow that is currently shown. // The current step of the request UX flow that is currently shown.
Step current_step_ = Step::kInitial; Step current_step_ = Step::kInitial;
TransportListModel transport_list_model_;
base::ObserverList<Observer> observers_; base::ObserverList<Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestDialogModel); DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestDialogModel);
......
// Copyright 2018 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/webauthn/transport_list_model.h"
TransportListModel::TransportListModel() = default;
TransportListModel::~TransportListModel() {
for (auto& observer : observer_list_)
observer.OnModelDestroyed();
}
void TransportListModel::AppendTransport(AuthenticatorTransport transport) {
transports_.push_back(transport);
for (auto& observer : observer_list_)
observer.OnTransportAppended();
}
void TransportListModel::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void TransportListModel::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
// Copyright 2018 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_WEBAUTHN_TRANSPORT_LIST_MODEL_H_
#define CHROME_BROWSER_WEBAUTHN_TRANSPORT_LIST_MODEL_H_
#include <vector>
#include "base/macros.h"
#include "base/observer_list.h"
// Enumerates transports over which a Security Key can be reached.
enum class AuthenticatorTransport {
kBluetoothLowEnergy,
kUsb,
kNearFieldCommunication,
kInternal,
kCloudAssistedBluetoothLowEnergy
};
// An observable list of transports that are supported on the platform.
class TransportListModel {
public:
class Observer {
public:
// Called just before the model is destructed.
virtual void OnModelDestroyed() = 0;
// Called when a new transport is added to the end of the list.
virtual void OnTransportAppended() {}
};
TransportListModel();
~TransportListModel();
// Appends |transport| at the end of the list.
void AppendTransport(AuthenticatorTransport transport);
// The |observer| must either outlive |this|, or unregister on destruction.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
const std::vector<AuthenticatorTransport>& transports() const {
return transports_;
}
private:
std::vector<AuthenticatorTransport> transports_;
base::ObserverList<Observer> observer_list_;
DISALLOW_COPY_AND_ASSIGN(TransportListModel);
};
#endif // CHROME_BROWSER_WEBAUTHN_TRANSPORT_LIST_MODEL_H_
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