[go: nahoru, domu]

cros: Add enrollment button for external binary auth

Bug: 890912
Change-Id: Ia55a93a2d1c2c956b95797ca175c3116a8d2b255
Reviewed-on: https://chromium-review.googlesource.com/c/1279359
Commit-Queue: Quan Nguyen <qnnguyen@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Reviewed-by: Jacob Dufault <jdufault@chromium.org>
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600837}
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc
index dc61d4fa..df054953 100644
--- a/ash/login/login_screen_controller.cc
+++ b/ash/login/login_screen_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/login/login_screen_controller.h"
 
+#include <utility>
+
 #include "ash/focus_cycler.h"
 #include "ash/login/ui/lock_screen.h"
 #include "ash/login/ui/lock_window.h"
@@ -19,6 +21,7 @@
 #include "ash/system/status_area_widget_delegate.h"
 #include "ash/system/toast/toast_data.h"
 #include "ash/system/toast/toast_manager.h"
+#include "base/bind.h"
 #include "base/debug/alias.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -149,6 +152,20 @@
                      weak_factory_.GetWeakPtr(), std::move(callback)));
 }
 
+void LoginScreenController::EnrollUserWithExternalBinary(
+    OnAuthenticateCallback callback) {
+  if (!login_screen_client_) {
+    std::move(callback).Run(base::nullopt);
+    return;
+  }
+
+  login_screen_client_->EnrollUserWithExternalBinary(base::BindOnce(
+      [](OnAuthenticateCallback callback, bool success) {
+        std::move(callback).Run(base::make_optional<bool>(success));
+      },
+      std::move(callback)));
+}
+
 void LoginScreenController::AuthenticateUserWithEasyUnlock(
     const AccountId& account_id) {
   // TODO(jdufault): integrate this into authenticate stage after mojom is
@@ -537,7 +554,7 @@
     OnAuthenticateCallback callback,
     bool success) {
   authentication_stage_ = AuthenticationStage::kUserCallback;
-  std::move(callback).Run(success);
+  std::move(callback).Run(base::make_optional<bool>(success));
   authentication_stage_ = AuthenticationStage::kIdle;
 }
 
diff --git a/ash/login/login_screen_controller.h b/ash/login/login_screen_controller.h
index 62c7ee41..850cdaa 100644
--- a/ash/login/login_screen_controller.h
+++ b/ash/login/login_screen_controller.h
@@ -63,6 +63,7 @@
                                          OnAuthenticateCallback callback);
   void AuthenticateUserWithExternalBinary(const AccountId& account_id,
                                           OnAuthenticateCallback callback);
+  void EnrollUserWithExternalBinary(OnAuthenticateCallback callback);
   void AuthenticateUserWithEasyUnlock(const AccountId& account_id);
   void HardlockPod(const AccountId& account_id);
   void RecordClickOnLockIcon(const AccountId& account_id);
diff --git a/ash/login/mock_login_screen_client.cc b/ash/login/mock_login_screen_client.cc
index e058668..7751be5 100644
--- a/ash/login/mock_login_screen_client.cc
+++ b/ash/login/mock_login_screen_client.cc
@@ -5,6 +5,7 @@
 #include "ash/login/mock_login_screen_client.h"
 
 #include <memory>
+#include <utility>
 
 #include "ash/login/login_screen_controller.h"
 #include "ash/shell.h"
@@ -48,6 +49,16 @@
   }
 }
 
+void MockLoginScreenClient::EnrollUserWithExternalBinary(
+    EnrollUserWithExternalBinaryCallback callback) {
+  EnrollUserWithExternalBinary_(callback);
+  if (enroll_user_with_external_binary_callback_storage_) {
+    *enroll_user_with_external_binary_callback_storage_ = std::move(callback);
+  } else {
+    std::move(callback).Run(authenticate_user_callback_result_);
+  }
+}
+
 std::unique_ptr<MockLoginScreenClient> BindMockLoginScreenClient() {
   auto client = std::make_unique<MockLoginScreenClient>();
   Shell::Get()->login_screen_controller()->SetClient(
diff --git a/ash/login/mock_login_screen_client.h b/ash/login/mock_login_screen_client.h
index 71176e6..00cfd90 100644
--- a/ash/login/mock_login_screen_client.h
+++ b/ash/login/mock_login_screen_client.h
@@ -28,6 +28,8 @@
   MOCK_METHOD2(AuthenticateUserWithExternalBinary_,
                void(const AccountId& account_id,
                     AuthenticateUserWithExternalBinaryCallback& callback));
+  MOCK_METHOD1(EnrollUserWithExternalBinary_,
+               void(EnrollUserWithExternalBinaryCallback& callback));
 
   // Set the result that should be passed to |callback| in
   // |AuthenticateUserWithPasswordOrPin| or
@@ -46,6 +48,10 @@
       AuthenticateUserWithPasswordOrPinCallback* storage) {
     authenticate_user_with_external_binary_callback_storage_ = storage;
   }
+  void set_enroll_user_with_external_binary_storage(
+      EnrollUserWithExternalBinaryCallback* storage) {
+    enroll_user_with_external_binary_callback_storage_ = storage;
+  }
 
   // mojom::LoginScreenClient:
   void AuthenticateUserWithPasswordOrPin(
@@ -56,6 +62,8 @@
   void AuthenticateUserWithExternalBinary(
       const AccountId& account_id,
       AuthenticateUserWithExternalBinaryCallback callback) override;
+  void EnrollUserWithExternalBinary(
+      EnrollUserWithExternalBinaryCallback callback) override;
   MOCK_METHOD1(AuthenticateUserWithEasyUnlock,
                void(const AccountId& account_id));
   MOCK_METHOD1(HardlockPod, void(const AccountId& account_id));
@@ -93,6 +101,8 @@
       authenticate_user_with_password_or_pin_callback_storage_ = nullptr;
   AuthenticateUserWithExternalBinaryCallback*
       authenticate_user_with_external_binary_callback_storage_ = nullptr;
+  EnrollUserWithExternalBinaryCallback*
+      enroll_user_with_external_binary_callback_storage_ = nullptr;
 
   mojo::Binding<mojom::LoginScreenClient> binding_;
 
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc
index 2ed146d..2776704 100644
--- a/ash/login/ui/login_auth_user_view.cc
+++ b/ash/login/ui/login_auth_user_view.cc
@@ -23,7 +23,9 @@
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/night_light/time_of_day.h"
+#include "ash/system/toast/toast_manager.h"
 #include "ash/wallpaper/wallpaper_controller.h"
+#include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/user_manager/user.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -456,6 +458,8 @@
   // TODO(jdufault): Implement real UI.
   external_binary_auth_button_ = views::MdTextButton::Create(
       this, base::ASCIIToUTF16("Authenticate with external binary"));
+  external_binary_enrollment_button_ = views::MdTextButton::Create(
+      this, base::ASCIIToUTF16("Enroll with external binary"));
 
   SetPaintToLayer(ui::LayerType::LAYER_NOT_DRAWN);
 
@@ -479,6 +483,9 @@
       login_views_utils::WrapViewForPreferredSize(fingerprint_view_);
   auto* wrapped_external_binary_view =
       login_views_utils::WrapViewForPreferredSize(external_binary_auth_button_);
+  auto* wrapped_external_binary_enrollment_view =
+      login_views_utils::WrapViewForPreferredSize(
+          external_binary_enrollment_button_);
   auto* wrapped_padding_below_password_view =
       login_views_utils::WrapViewForPreferredSize(padding_below_password_view_);
 
@@ -489,6 +496,7 @@
   AddChildView(wrapped_pin_view);
   AddChildView(wrapped_fingerprint_view);
   AddChildView(wrapped_external_binary_view);
+  AddChildView(wrapped_external_binary_enrollment_view);
   AddChildView(wrapped_user_view);
   AddChildView(wrapped_padding_below_password_view);
 
@@ -519,6 +527,7 @@
   add_view(wrapped_pin_view);
   add_view(wrapped_fingerprint_view);
   add_view(wrapped_external_binary_view);
+  add_view(wrapped_external_binary_enrollment_view);
   add_padding(kDistanceFromPinKeyboardToBigUserViewBottomDp);
 
   // Update authentication UI.
@@ -565,6 +574,7 @@
   pin_view_->SetVisible(has_pin);
   fingerprint_view_->SetVisible(has_fingerprint);
   external_binary_auth_button_->SetVisible(has_external_binary);
+  external_binary_enrollment_button_->SetVisible(has_external_binary);
 
   int padding_view_height = kDistanceBetweenPasswordFieldAndPinKeyboardDp;
   if (has_fingerprint && !has_pin) {
@@ -778,10 +788,18 @@
   } else if (sender == external_binary_auth_button_) {
     password_view_->SetReadOnly(true);
     external_binary_auth_button_->SetEnabled(false);
+    external_binary_enrollment_button_->SetEnabled(false);
     Shell::Get()->login_screen_controller()->AuthenticateUserWithExternalBinary(
         current_user()->basic_user_info->account_id,
         base::BindOnce(&LoginAuthUserView::OnAuthComplete,
                        weak_factory_.GetWeakPtr()));
+  } else if (sender == external_binary_enrollment_button_) {
+    password_view_->SetReadOnly(true);
+    external_binary_auth_button_->SetEnabled(false);
+    external_binary_enrollment_button_->SetEnabled(false);
+    Shell::Get()->login_screen_controller()->EnrollUserWithExternalBinary(
+        base::BindOnce(&LoginAuthUserView::OnEnrollmentComplete,
+                       weak_factory_.GetWeakPtr()));
   }
 }
 
@@ -803,22 +821,39 @@
 }
 
 void LoginAuthUserView::OnAuthComplete(base::Optional<bool> auth_success) {
-  if (!auth_success.has_value())
-    return;
-
   // Clear the password only if auth fails. Make sure to keep the password view
   // disabled even if auth succeededs, as if the user submits a password while
   // animating the next lock screen will not work as expected. See
   // https://crbug.com/808486.
-  if (!auth_success.value()) {
+  if (!auth_success.has_value() || !auth_success.value()) {
     password_view_->Clear();
     password_view_->SetReadOnly(false);
     external_binary_auth_button_->SetEnabled(true);
+    external_binary_enrollment_button_->SetEnabled(true);
   }
 
   on_auth_.Run(auth_success.value());
 }
 
+void LoginAuthUserView::OnEnrollmentComplete(
+    base::Optional<bool> enrollment_success) {
+  password_view_->SetReadOnly(false);
+  external_binary_auth_button_->SetEnabled(true);
+  external_binary_enrollment_button_->SetEnabled(true);
+
+  std::string result_message;
+  if (!enrollment_success.has_value()) {
+    result_message = "Enrollment attempt failed to received response.";
+  } else {
+    result_message = enrollment_success.value() ? "Enrollment successful."
+                                                : "Enrollment failed.";
+  }
+
+  ToastData toast_data("EnrollmentToast", base::ASCIIToUTF16(result_message),
+                       2000, base::nullopt, true /*visible_on_lock_screen*/);
+  Shell::Get()->toast_manager()->Show(toast_data);
+}
+
 void LoginAuthUserView::OnUserViewTap() {
   if (HasAuthMethod(AUTH_TAP)) {
     Shell::Get()->login_screen_controller()->AuthenticateUserWithEasyUnlock(
diff --git a/ash/login/ui/login_auth_user_view.h b/ash/login/ui/login_auth_user_view.h
index 28246fc..18e87736 100644
--- a/ash/login/ui/login_auth_user_view.h
+++ b/ash/login/ui/login_auth_user_view.h
@@ -14,6 +14,7 @@
 #include "ash/login/ui/non_accessible_view.h"
 #include "ash/public/interfaces/user_info.mojom.h"
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "base/scoped_observer.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/view.h"
@@ -141,6 +142,8 @@
   void OnAuthSubmit(const base::string16& password);
   // Called with the result of the request started in |OnAuthSubmit|.
   void OnAuthComplete(base::Optional<bool> auth_success);
+  // Called with the result of the external binary enrollment request.
+  void OnEnrollmentComplete(base::Optional<bool> enrollment_success);
 
   // Called when the user view has been tapped. This will run |on_auth_| if tap
   // to unlock is enabled, or run |OnOnlineSignInMessageTap| if the online
@@ -166,6 +169,7 @@
   DisabledAuthMessageView* disabled_auth_message_ = nullptr;
   FingerprintView* fingerprint_view_ = nullptr;
   views::LabelButton* external_binary_auth_button_ = nullptr;
+  views::LabelButton* external_binary_enrollment_button_ = nullptr;
 
   // Displays padding between:
   // 1. Password field and pin keyboard
diff --git a/ash/public/interfaces/login_screen.mojom b/ash/public/interfaces/login_screen.mojom
index 8337afdf..84180bc8 100644
--- a/ash/public/interfaces/login_screen.mojom
+++ b/ash/public/interfaces/login_screen.mojom
@@ -229,6 +229,9 @@
   AuthenticateUserWithExternalBinary(signin.mojom.AccountId account_id)
       => (bool auth_success);
 
+  // Attempt to enroll a user in the external binary authentication system.
+  EnrollUserWithExternalBinary() => (bool enrollment_success);
+
   // Try to authenticate |account_id| using easy unlock. This can be used on the
   // login or lock screen.
   // |account_id|: The account id of the user we are authenticating.
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
index ae877463..5ae6107 100644
--- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -44,6 +44,7 @@
 namespace {
 constexpr char kLockDisplay[] = "lock";
 constexpr char kExternalBinaryAuth[] = "external_binary_auth";
+constexpr char kExternalBinaryEnrollment[] = "external_binary_enrollment";
 constexpr char kWebCameraDeviceContext[] = "WebCamera: WebCamera";
 constexpr base::TimeDelta kExternalBinaryAuthTimeout =
     base::TimeDelta::FromSeconds(2);
@@ -236,7 +237,7 @@
     const AccountId& account_id,
     AuthenticateUserWithExternalBinaryCallback callback) {
   authenticate_with_external_binary_callback_ = std::move(callback);
-  external_binary_auth_timer_.Start(
+  external_binary_timer_.Start(
       FROM_HERE, kExternalBinaryAuthTimeout,
       base::BindOnce(&ViewsScreenLocker::OnExternalBinaryAuthTimeout,
                      weak_factory_.GetWeakPtr()));
@@ -244,6 +245,17 @@
       &StartGraphIfNeeded, media_analytics_client_, kExternalBinaryAuth));
 }
 
+void ViewsScreenLocker::HandleEnrollUserWithExternalBinary(
+    EnrollUserWithExternalBinaryCallback callback) {
+  enroll_user_with_external_binary_callback_ = std::move(callback);
+  external_binary_timer_.Start(
+      FROM_HERE, kExternalBinaryAuthTimeout,
+      base::BindOnce(&ViewsScreenLocker::OnExternalBinaryEnrollmentTimeout,
+                     weak_factory_.GetWeakPtr()));
+  media_analytics_client_->GetState(base::BindOnce(
+      &StartGraphIfNeeded, media_analytics_client_, kExternalBinaryEnrollment));
+}
+
 void ViewsScreenLocker::HandleAuthenticateUserWithEasyUnlock(
     const AccountId& account_id) {
   user_selection_screen_->AttemptEasyUnlock(account_id);
@@ -338,21 +350,29 @@
 
 void ViewsScreenLocker::OnDetectionSignal(
     const mri::MediaPerception& media_perception) {
-  if (!authenticate_with_external_binary_callback_)
-    return;
+  if (authenticate_with_external_binary_callback_) {
+    const mri::FramePerception& frame = media_perception.frame_perception(0);
+    if (frame.frame_id() != 1)
+      return;
 
-  const mri::FramePerception& frame = media_perception.frame_perception(0);
-  if (frame.frame_id() != 1)
-    return;
+    mri::State new_state;
+    new_state.set_status(mri::State::SUSPENDED);
+    media_analytics_client_->SetState(new_state, base::DoNothing());
 
-  mri::State new_state;
-  new_state.set_status(mri::State::SUSPENDED);
-  media_analytics_client_->SetState(new_state, base::DoNothing());
+    external_binary_timer_.Stop();
+    std::move(authenticate_with_external_binary_callback_)
+        .Run(true /*auth_success*/);
+    ScreenLocker::Hide();
+  } else if (enroll_user_with_external_binary_callback_) {
+    const mri::FramePerception& frame = media_perception.frame_perception(0);
 
-  external_binary_auth_timer_.Stop();
-  std::move(authenticate_with_external_binary_callback_)
-      .Run(true /*auth_success*/);
-  ScreenLocker::Hide();
+    external_binary_timer_.Stop();
+    mri::State new_state;
+    new_state.set_status(mri::State::SUSPENDED);
+    media_analytics_client_->SetState(new_state, base::DoNothing());
+    std::move(enroll_user_with_external_binary_callback_)
+        .Run(frame.frame_id() == 1 /*enrollment_success*/);
+  }
 }
 
 void ViewsScreenLocker::UpdatePinKeyboardState(const AccountId& account_id) {
@@ -388,4 +408,12 @@
   media_analytics_client_->SetState(new_state, base::DoNothing());
 }
 
+void ViewsScreenLocker::OnExternalBinaryEnrollmentTimeout() {
+  std::move(enroll_user_with_external_binary_callback_)
+      .Run(false /*auth_success*/);
+  mri::State new_state;
+  new_state.set_status(mri::State::SUSPENDED);
+  media_analytics_client_->SetState(new_state, base::DoNothing());
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.h b/chrome/browser/chromeos/login/lock/views_screen_locker.h
index 26a063e3..bb6ff2f 100644
--- a/chrome/browser/chromeos/login/lock/views_screen_locker.h
+++ b/chrome/browser/chromeos/login/lock/views_screen_locker.h
@@ -61,6 +61,8 @@
   void HandleAuthenticateUserWithExternalBinary(
       const AccountId& account_id,
       AuthenticateUserWithExternalBinaryCallback callback) override;
+  void HandleEnrollUserWithExternalBinary(
+      EnrollUserWithExternalBinaryCallback) override;
   void HandleAuthenticateUserWithEasyUnlock(
       const AccountId& account_id) override;
   void HandleHardlockPod(const AccountId& account_id) override;
@@ -91,6 +93,7 @@
   void OnAllowedInputMethodsChanged();
   void OnPinCanAuthenticate(const AccountId& account_id, bool can_authenticate);
   void OnExternalBinaryAuthTimeout();
+  void OnExternalBinaryEnrollmentTimeout();
 
   std::unique_ptr<UserBoardViewMojo> user_board_view_mojo_;
   std::unique_ptr<UserSelectionScreen> user_selection_screen_;
@@ -114,6 +117,9 @@
   AuthenticateUserWithExternalBinaryCallback
       authenticate_with_external_binary_callback_;
 
+  EnrollUserWithExternalBinaryCallback
+      enroll_user_with_external_binary_callback_;
+
   // Callback registered as a lock screen apps focus handler - it should be
   // called to hand focus over to lock screen apps.
   LockScreenAppFocusCallback lock_screen_app_focus_handler_;
@@ -123,9 +129,9 @@
 
   chromeos::MediaAnalyticsClient* media_analytics_client_;
 
-  // Timer for external binary auth attempt. Allows repeated auth attempts up to
-  // a specific timeout.
-  base::OneShotTimer external_binary_auth_timer_;
+  // Timer for external binary auth/enrollment attempt. Allows repeated attempts
+  // up to a specific timeout.
+  base::OneShotTimer external_binary_timer_;
 
   ScopedObserver<chromeos::MediaAnalyticsClient, ViewsScreenLocker>
       scoped_observer_{this};
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
index 95f6fb7d..c661f18 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -380,6 +380,12 @@
   std::move(callback).Run(false);
 }
 
+void LoginDisplayHostMojo::HandleEnrollUserWithExternalBinary(
+    EnrollUserWithExternalBinaryCallback callback) {
+  // Enroll in external binary auth system is not supported for login.
+  std::move(callback).Run(false);
+}
+
 void LoginDisplayHostMojo::HandleAuthenticateUserWithEasyUnlock(
     const AccountId& account_id) {
   user_selection_screen_->AttemptEasyUnlock(account_id);
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
index f07bea84..05ed24f 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
@@ -106,6 +106,8 @@
   void HandleAuthenticateUserWithExternalBinary(
       const AccountId& account_id,
       AuthenticateUserWithExternalBinaryCallback callback) override;
+  void HandleEnrollUserWithExternalBinary(
+      EnrollUserWithExternalBinaryCallback callback) override;
   void HandleAuthenticateUserWithEasyUnlock(
       const AccountId& account_id) override;
   void HandleHardlockPod(const AccountId& account_id) override;
diff --git a/chrome/browser/ui/ash/login_screen_client.cc b/chrome/browser/ui/ash/login_screen_client.cc
index d2fb0862..c4f7990 100644
--- a/chrome/browser/ui/ash/login_screen_client.cc
+++ b/chrome/browser/ui/ash/login_screen_client.cc
@@ -91,15 +91,24 @@
 void LoginScreenClient::AuthenticateUserWithExternalBinary(
     const AccountId& account_id,
     AuthenticateUserWithExternalBinaryCallback callback) {
-  if (delegate_) {
-    delegate_->HandleAuthenticateUserWithExternalBinary(account_id,
-                                                        std::move(callback));
-    // TODO(jdufault): Record auth method attempt here
-    NOTIMPLEMENTED() << "Missing UMA recording for external binary auth";
-  } else {
-    LOG(ERROR) << "Failed AuthenticateUserWithExternalBinary; no delegate";
-    std::move(callback).Run(false);
-  }
+  if (!delegate_)
+    LOG(FATAL) << "Failed AuthenticateUserWithExternalBinary; no delegate";
+
+  delegate_->HandleAuthenticateUserWithExternalBinary(account_id,
+                                                      std::move(callback));
+  // TODO: Record auth method attempt here
+  NOTIMPLEMENTED() << "Missing UMA recording for external binary auth";
+}
+
+void LoginScreenClient::EnrollUserWithExternalBinary(
+    EnrollUserWithExternalBinaryCallback callback) {
+  if (!delegate_)
+    LOG(FATAL) << "Failed EnrollUserWithExternalBinary; no delegate";
+
+  delegate_->HandleEnrollUserWithExternalBinary(std::move(callback));
+
+  // TODO: Record enrollment attempt here
+  NOTIMPLEMENTED() << "Missing UMA recording for external binary enrollment";
 }
 
 void LoginScreenClient::AuthenticateUserWithEasyUnlock(
diff --git a/chrome/browser/ui/ash/login_screen_client.h b/chrome/browser/ui/ash/login_screen_client.h
index df22aa0a..195ec050 100644
--- a/chrome/browser/ui/ash/login_screen_client.h
+++ b/chrome/browser/ui/ash/login_screen_client.h
@@ -14,6 +14,8 @@
     ash::mojom::LoginScreenClient::AuthenticateUserWithPasswordOrPinCallback;
 using AuthenticateUserWithExternalBinaryCallback =
     ash::mojom::LoginScreenClient::AuthenticateUserWithExternalBinaryCallback;
+using EnrollUserWithExternalBinaryCallback =
+    ash::mojom::LoginScreenClient::EnrollUserWithExternalBinaryCallback;
 
 namespace chromeos {
 class LoginAuthRecorder;
@@ -36,6 +38,8 @@
     virtual void HandleAuthenticateUserWithExternalBinary(
         const AccountId& account_id,
         AuthenticateUserWithExternalBinaryCallback callback) = 0;
+    virtual void HandleEnrollUserWithExternalBinary(
+        EnrollUserWithExternalBinaryCallback) = 0;
     virtual void HandleAuthenticateUserWithEasyUnlock(
         const AccountId& account_id) = 0;
     virtual void HandleHardlockPod(const AccountId& account_id) = 0;
@@ -78,6 +82,8 @@
   void AuthenticateUserWithExternalBinary(
       const AccountId& account_id,
       AuthenticateUserWithExternalBinaryCallback callback) override;
+  void EnrollUserWithExternalBinary(
+      EnrollUserWithExternalBinaryCallback callback) override;
   void AuthenticateUserWithEasyUnlock(const AccountId& account_id) override;
   void HardlockPod(const AccountId& account_id) override;
   void RecordClickOnLockIcon(const AccountId& account_id) override;