Commit e16b6ef2 authored by Sarah Hu's avatar Sarah Hu Committed by Commit Bot

cros: Update fingerprint unlock UI per latest mock.

Bug: 835357
Change-Id: I61be44e86f85175a3472669aecf630ddb5bb2fa2
Reviewed-on: https://chromium-review.googlesource.com/1159383Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarJacob Dufault <jdufault@chromium.org>
Commit-Queue: Xiaoyin Hu <xiaoyinh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580914}
parent ea304b71
...@@ -200,6 +200,7 @@ component("ash") { ...@@ -200,6 +200,7 @@ component("ash") {
"login/ui/animated_rounded_image_view.h", "login/ui/animated_rounded_image_view.h",
"login/ui/animation_frame.h", "login/ui/animation_frame.h",
"login/ui/arrow_button_view.h", "login/ui/arrow_button_view.h",
"login/ui/horizontal_image_sequence_animation_decoder.h",
"login/ui/hover_notifier.h", "login/ui/hover_notifier.h",
"login/ui/image_parser.h", "login/ui/image_parser.h",
"login/ui/lock_contents_view.h", "login/ui/lock_contents_view.h",
...@@ -849,6 +850,7 @@ component("ash") { ...@@ -849,6 +850,7 @@ component("ash") {
"login/login_screen_controller_observer.cc", "login/login_screen_controller_observer.cc",
"login/ui/animated_rounded_image_view.cc", "login/ui/animated_rounded_image_view.cc",
"login/ui/arrow_button_view.cc", "login/ui/arrow_button_view.cc",
"login/ui/horizontal_image_sequence_animation_decoder.cc",
"login/ui/hover_notifier.cc", "login/ui/hover_notifier.cc",
"login/ui/image_parser.cc", "login/ui/image_parser.cc",
"login/ui/lock_contents_view.cc", "login/ui/lock_contents_view.cc",
...@@ -1334,6 +1336,7 @@ component("ash") { ...@@ -1334,6 +1336,7 @@ component("ash") {
"//ash/components/shortcut_viewer/public/mojom", "//ash/components/shortcut_viewer/public/mojom",
"//ash/components/tap_visualizer/public/mojom", "//ash/components/tap_visualizer/public/mojom",
"//ash/keyboard/arc", "//ash/keyboard/arc",
"//ash/login/resources:resources_grit",
"//ash/system/message_center/arc", "//ash/system/message_center/arc",
"//ash/touch_hud", "//ash/touch_hud",
"//base", "//base",
......
...@@ -47,19 +47,22 @@ AnimatedRoundedImageView::AnimatedRoundedImageView(const gfx::Size& size, ...@@ -47,19 +47,22 @@ AnimatedRoundedImageView::AnimatedRoundedImageView(const gfx::Size& size,
AnimatedRoundedImageView::~AnimatedRoundedImageView() = default; AnimatedRoundedImageView::~AnimatedRoundedImageView() = default;
void AnimatedRoundedImageView::SetAnimationDecoder( void AnimatedRoundedImageView::SetAnimationDecoder(
std::unique_ptr<AnimationDecoder> decoder) { std::unique_ptr<AnimationDecoder> decoder,
Playback playback) {
decoder_ = std::move(decoder); decoder_ = std::move(decoder);
playback_ = playback;
// Force a new decode and repaint. // Force a new decode and repaint.
frames_scale_ = NAN; frames_scale_ = NAN;
SchedulePaint(); SchedulePaint();
} }
void AnimatedRoundedImageView::SetImage(const gfx::ImageSkia& image) { void AnimatedRoundedImageView::SetImage(const gfx::ImageSkia& image) {
SetAnimationDecoder(std::make_unique<SingleFrameImageDecoder>(image)); SetAnimationDecoder(std::make_unique<SingleFrameImageDecoder>(image),
Playback::kFirstFrameOnly);
} }
void AnimatedRoundedImageView::SetAnimationEnabled(bool enabled) { void AnimatedRoundedImageView::SetAnimationPlayback(Playback playback) {
should_animate_ = enabled; playback_ = playback;
StartOrStopAnimation(); StartOrStopAnimation();
} }
...@@ -100,7 +103,7 @@ void AnimatedRoundedImageView::OnPaint(gfx::Canvas* canvas) { ...@@ -100,7 +103,7 @@ void AnimatedRoundedImageView::OnPaint(gfx::Canvas* canvas) {
void AnimatedRoundedImageView::StartOrStopAnimation() { void AnimatedRoundedImageView::StartOrStopAnimation() {
// If animation is disabled or if there are less than 2 frames, show a static // If animation is disabled or if there are less than 2 frames, show a static
// image. // image.
if (!should_animate_ || frames_.size() < 2) { if (playback_ == Playback::kFirstFrameOnly || frames_.size() < 2) {
active_frame_ = 0; active_frame_ = 0;
update_frame_timer_.Stop(); update_frame_timer_.Stop();
SchedulePaint(); SchedulePaint();
...@@ -119,11 +122,14 @@ void AnimatedRoundedImageView::UpdateAnimationFrame() { ...@@ -119,11 +122,14 @@ void AnimatedRoundedImageView::UpdateAnimationFrame() {
active_frame_ = (active_frame_ + 1) % frames_.size(); active_frame_ = (active_frame_ + 1) % frames_.size();
SchedulePaint(); SchedulePaint();
// Schedule next frame update. if (static_cast<size_t>(active_frame_ + 1) < frames_.size() ||
update_frame_timer_.Start( playback_ == Playback::kRepeat) {
FROM_HERE, frames_[active_frame_].duration, // Schedule next frame update.
base::BindRepeating(&AnimatedRoundedImageView::UpdateAnimationFrame, update_frame_timer_.Start(
base::Unretained(this))); FROM_HERE, frames_[active_frame_].duration,
base::BindRepeating(&AnimatedRoundedImageView::UpdateAnimationFrame,
base::Unretained(this)));
}
} }
void AnimatedRoundedImageView::BuildAnimationFrames(float image_scale) { void AnimatedRoundedImageView::BuildAnimationFrames(float image_scale) {
......
...@@ -21,6 +21,12 @@ namespace ash { ...@@ -21,6 +21,12 @@ namespace ash {
// A custom image view with rounded edges. // A custom image view with rounded edges.
class AnimatedRoundedImageView : public views::View { class AnimatedRoundedImageView : public views::View {
public: public:
enum class Playback {
kFirstFrameOnly, // Only the first frame in the animation will be shown.
kSingle, // Play the animation only once.
kRepeat, // Play the animation repeatly.
};
// Provides animation frames. // Provides animation frames.
class AnimationDecoder { class AnimationDecoder {
public: public:
...@@ -33,14 +39,15 @@ class AnimatedRoundedImageView : public views::View { ...@@ -33,14 +39,15 @@ class AnimatedRoundedImageView : public views::View {
AnimatedRoundedImageView(const gfx::Size& size, int corner_radius); AnimatedRoundedImageView(const gfx::Size& size, int corner_radius);
~AnimatedRoundedImageView() override; ~AnimatedRoundedImageView() override;
// Show an animation. // Show an animation with specified playback mode.
void SetAnimationDecoder(std::unique_ptr<AnimationDecoder> decoder); void SetAnimationDecoder(std::unique_ptr<AnimationDecoder> decoder,
Playback playback);
// Show a static image. // Show a static image.
void SetImage(const gfx::ImageSkia& image); void SetImage(const gfx::ImageSkia& image);
// Start or stop animation. // Set playback type of the animation.
void SetAnimationEnabled(bool enabled); void SetAnimationPlayback(Playback playback);
// views::View: // views::View:
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
...@@ -51,10 +58,6 @@ class AnimatedRoundedImageView : public views::View { ...@@ -51,10 +58,6 @@ class AnimatedRoundedImageView : public views::View {
void UpdateAnimationFrame(); void UpdateAnimationFrame();
void BuildAnimationFrames(float image_scale); void BuildAnimationFrames(float image_scale);
// If true and there are multiple frames, the animation will play. If false,
// only the first frame in the animation will be shown.
bool should_animate_ = false;
// Currently displayed animation frame. // Currently displayed animation frame.
int active_frame_ = 0; int active_frame_ = 0;
...@@ -64,6 +67,8 @@ class AnimatedRoundedImageView : public views::View { ...@@ -64,6 +67,8 @@ class AnimatedRoundedImageView : public views::View {
float frames_scale_ = NAN; float frames_scale_ = NAN;
// The raw decoded animation frames. // The raw decoded animation frames.
AnimationFrames frames_; AnimationFrames frames_;
// Animation playback type.
Playback playback_ = Playback::kFirstFrameOnly;
const gfx::Size image_size_; const gfx::Size image_size_;
const int corner_radius_; const int corner_radius_;
......
// 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 "ash/login/ui/horizontal_image_sequence_animation_decoder.h"
namespace ash {
HorizontalImageSequenceAnimationDecoder::
HorizontalImageSequenceAnimationDecoder(const gfx::ImageSkia& image,
base::TimeDelta duration,
int num_frames)
: image_(image), duration_(duration), num_frames_(num_frames) {}
HorizontalImageSequenceAnimationDecoder::
~HorizontalImageSequenceAnimationDecoder() = default;
AnimationFrames HorizontalImageSequenceAnimationDecoder::Decode(
float image_scale) {
SkBitmap bitmap = image_.GetRepresentation(image_scale).sk_bitmap();
float frame_width = static_cast<float>(bitmap.width()) / num_frames_;
base::TimeDelta frame_duration = duration_ / num_frames_;
AnimationFrames animation;
animation.reserve(num_frames_);
for (int i = 0; i < num_frames_; ++i) {
// Get the subsection of the animation strip.
SkBitmap frame_bitmap;
bitmap.extractSubset(
&frame_bitmap,
SkIRect::MakeXYWH(std::round(i * frame_width), 0,
std::round(frame_width), bitmap.height()));
// Add an animation frame.
AnimationFrame frame;
frame.duration = frame_duration;
frame.image = gfx::ImageSkia::CreateFrom1xBitmap(frame_bitmap);
animation.push_back(frame);
}
return animation;
}
} // namespace ash
// 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 ASH_LOGIN_UI_HORIZONTAL_IMAGE_SEQUENCE_ANIMATION_DECODER_H_
#define ASH_LOGIN_UI_HORIZONTAL_IMAGE_SEQUENCE_ANIMATION_DECODER_H_
#include "ash/login/ui/animated_rounded_image_view.h"
namespace ash {
// Decodes an animation strip that is laid out 1xN (ie, the image grows in
// width, not height). There is no padding between frames in the animation
// strip.
//
// As an example, if the following ASCII art is 100 pixels wide, it has 4 frames
// each 25 pixels wide. The frames go from [0, 25), [25, 50), [50, 75), [75,
// 100). All frames have the same height of 25 pixels.
//
// [1][2][3][4]
//
class HorizontalImageSequenceAnimationDecoder
: public AnimatedRoundedImageView::AnimationDecoder {
public:
HorizontalImageSequenceAnimationDecoder(const gfx::ImageSkia& image,
base::TimeDelta duration,
int num_frames);
~HorizontalImageSequenceAnimationDecoder() override;
// AnimatedRoundedImageView::AnimationDecoder:
AnimationFrames Decode(float image_scale) override;
private:
// The animation image source.
gfx::ImageSkia image_;
// The total duration of the animation.
base::TimeDelta duration_;
// The total number of frames in the animation.
int num_frames_;
DISALLOW_COPY_AND_ASSIGN(HorizontalImageSequenceAnimationDecoder);
};
} // namespace ash
#endif // ASH_LOGIN_UI_HORIZONTAL_IMAGE_SEQUENCE_ANIMATION_DECODER_H_
...@@ -1446,11 +1446,8 @@ void LockContentsView::UpdateAuthForAuthUser(LoginAuthUserView* opt_to_update, ...@@ -1446,11 +1446,8 @@ void LockContentsView::UpdateAuthForAuthUser(LoginAuthUserView* opt_to_update,
const bool is_keyboard_visible = const bool is_keyboard_visible =
keyboard_controller ? keyboard_controller->IsKeyboardVisible() keyboard_controller ? keyboard_controller->IsKeyboardVisible()
: false; : false;
if (state->show_pin && !is_keyboard_visible && if (state->show_pin && !is_keyboard_visible)
state->fingerprint_state ==
mojom::FingerprintUnlockState::UNAVAILABLE) {
to_update_auth |= LoginAuthUserView::AUTH_PIN; to_update_auth |= LoginAuthUserView::AUTH_PIN;
}
if (state->enable_tap_auth) if (state->enable_tap_auth)
to_update_auth |= LoginAuthUserView::AUTH_TAP; to_update_auth |= LoginAuthUserView::AUTH_TAP;
if (state->fingerprint_state != if (state->fingerprint_state !=
......
...@@ -52,6 +52,7 @@ enum { ...@@ -52,6 +52,7 @@ enum {
kGlobalCycleAuthErrorMessage, kGlobalCycleAuthErrorMessage,
kPerUserTogglePin, kPerUserTogglePin,
kPerUserCycleEasyUnlockState, kPerUserCycleEasyUnlockState,
kPerUserCycleFingerprintState,
kPerUserForceOnlineSignIn, kPerUserForceOnlineSignIn,
kPerUserToggleAuthEnabled, kPerUserToggleAuthEnabled,
kPerUserUseDetachableBase, kPerUserUseDetachableBase,
...@@ -97,6 +98,8 @@ struct UserMetadata { ...@@ -97,6 +98,8 @@ struct UserMetadata {
bool enable_auth = true; bool enable_auth = true;
user_manager::UserType type = user_manager::USER_TYPE_REGULAR; user_manager::UserType type = user_manager::USER_TYPE_REGULAR;
mojom::EasyUnlockIconId easy_unlock_id = mojom::EasyUnlockIconId::NONE; mojom::EasyUnlockIconId easy_unlock_id = mojom::EasyUnlockIconId::NONE;
mojom::FingerprintUnlockState fingerprint_state =
mojom::FingerprintUnlockState::UNAVAILABLE;
}; };
std::string DetachableBasePairingStatusToString( std::string DetachableBasePairingStatusToString(
...@@ -301,6 +304,33 @@ class LockDebugView::DebugDataDispatcherTransformer ...@@ -301,6 +304,33 @@ class LockDebugView::DebugDataDispatcherTransformer
debug_user->account_id, debug_user->enable_click_to_unlock); debug_user->account_id, debug_user->enable_click_to_unlock);
} }
// Enables fingerprint auth for the user at |user_index|.
void CycleFingerprintUnlockForUserIndex(size_t user_index) {
DCHECK(user_index >= 0 && user_index < debug_users_.size());
UserMetadata* debug_user = &debug_users_[user_index];
// FingerprintUnlockState transition.
auto get_next_state = [](mojom::FingerprintUnlockState state) {
switch (state) {
case mojom::FingerprintUnlockState::UNAVAILABLE:
return mojom::FingerprintUnlockState::AVAILABLE;
case mojom::FingerprintUnlockState::AVAILABLE:
return mojom::FingerprintUnlockState::AUTH_SUCCESS;
case mojom::FingerprintUnlockState::AUTH_SUCCESS:
return mojom::FingerprintUnlockState::AUTH_FAILED;
case mojom::FingerprintUnlockState::AUTH_FAILED:
return mojom::FingerprintUnlockState::AUTH_DISABLED;
case mojom::FingerprintUnlockState::AUTH_DISABLED:
return mojom::FingerprintUnlockState::UNAVAILABLE;
}
};
debug_user->fingerprint_state =
get_next_state(debug_user->fingerprint_state);
debug_dispatcher_.SetFingerprintUnlockState(debug_user->account_id,
debug_user->fingerprint_state);
}
// Force online sign-in for the user at |user_index|. // Force online sign-in for the user at |user_index|.
void ForceOnlineSignInForUserIndex(size_t user_index) { void ForceOnlineSignInForUserIndex(size_t user_index) {
DCHECK(user_index >= 0 && user_index < debug_users_.size()); DCHECK(user_index >= 0 && user_index < debug_users_.size());
...@@ -873,6 +903,10 @@ void LockDebugView::ButtonPressed(views::Button* sender, ...@@ -873,6 +903,10 @@ void LockDebugView::ButtonPressed(views::Button* sender,
if (sender->id() == ButtonId::kPerUserCycleEasyUnlockState) if (sender->id() == ButtonId::kPerUserCycleEasyUnlockState)
debug_data_dispatcher_->CycleEasyUnlockForUserIndex(sender->tag()); debug_data_dispatcher_->CycleEasyUnlockForUserIndex(sender->tag());
// Cycle fingerprint unlock state.
if (sender->id() == ButtonId::kPerUserCycleFingerprintState)
debug_data_dispatcher_->CycleFingerprintUnlockForUserIndex(sender->tag());
// Force online sign-in. // Force online sign-in.
if (sender->id() == ButtonId::kPerUserForceOnlineSignIn) if (sender->id() == ButtonId::kPerUserForceOnlineSignIn)
debug_data_dispatcher_->ForceOnlineSignInForUserIndex(sender->tag()); debug_data_dispatcher_->ForceOnlineSignInForUserIndex(sender->tag());
...@@ -916,6 +950,9 @@ void LockDebugView::UpdatePerUserActionContainer() { ...@@ -916,6 +950,9 @@ void LockDebugView::UpdatePerUserActionContainer() {
AddButton("Toggle PIN", ButtonId::kPerUserTogglePin, row)->set_tag(i); AddButton("Toggle PIN", ButtonId::kPerUserTogglePin, row)->set_tag(i);
AddButton("Cycle easy unlock", ButtonId::kPerUserCycleEasyUnlockState, row) AddButton("Cycle easy unlock", ButtonId::kPerUserCycleEasyUnlockState, row)
->set_tag(i); ->set_tag(i);
AddButton("Cycle fingerprint unlock",
ButtonId::kPerUserCycleFingerprintState, row)
->set_tag(i);
AddButton("Force online sign-in", ButtonId::kPerUserForceOnlineSignIn, row) AddButton("Force online sign-in", ButtonId::kPerUserForceOnlineSignIn, row)
->set_tag(i); ->set_tag(i);
AddButton("Toggle auth enabled", ButtonId::kPerUserToggleAuthEnabled, row) AddButton("Toggle auth enabled", ButtonId::kPerUserToggleAuthEnabled, row)
......
This diff is collapsed.
...@@ -165,6 +165,11 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView, ...@@ -165,6 +165,11 @@ class ASH_EXPORT LoginAuthUserView : public NonAccessibleView,
views::LabelButton* online_sign_in_message_ = nullptr; views::LabelButton* online_sign_in_message_ = nullptr;
DisabledAuthMessageView* disabled_auth_message_ = nullptr; DisabledAuthMessageView* disabled_auth_message_ = nullptr;
FingerprintView* fingerprint_view_ = nullptr; FingerprintView* fingerprint_view_ = nullptr;
// Displays padding between:
// 1. Password field and pin keyboard
// 2. Password field and fingerprint view, when pin is not available.
// Preferred size will change base on current auth method.
NonAccessibleView* padding_below_password_view_ = nullptr;
const OnAuthCallback on_auth_; const OnAuthCallback on_auth_;
const LoginUserView::OnTap on_tap_; const LoginUserView::OnTap on_tap_;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ash/login/ui/login_password_view.h" #include "ash/login/ui/login_password_view.h"
#include "ash/login/ui/horizontal_image_sequence_animation_decoder.h"
#include "ash/login/ui/hover_notifier.h" #include "ash/login/ui/hover_notifier.h"
#include "ash/login/ui/lock_screen.h" #include "ash/login/ui/lock_screen.h"
#include "ash/login/ui/login_button.h" #include "ash/login/ui/login_button.h"
...@@ -159,62 +160,6 @@ IconBundle GetEasyUnlockResources(mojom::EasyUnlockIconId id) { ...@@ -159,62 +160,6 @@ IconBundle GetEasyUnlockResources(mojom::EasyUnlockIconId id) {
IDR_EASY_UNLOCK_LOCKED_PRESSED); IDR_EASY_UNLOCK_LOCKED_PRESSED);
} }
// Decodes an animation strip that is laid out 1xN (ie, the image grows in
// width, not height). There is no padding between frames in the animation
// strip.
//
// As an example, if the following ASCII art is 100 pixels wide, it has 4 frames
// each 25 pixels wide. The frames go from [0, 25), [25, 50), [50, 75), [75,
// 100). All frames have the same height of 25 pixels.
//
// [1][2][3][4]
//
class EasyUnlockAnimationDecoder
: public AnimatedRoundedImageView::AnimationDecoder {
public:
EasyUnlockAnimationDecoder(const gfx::ImageSkia& image,
base::TimeDelta duration,
int num_frames)
: image_(image), duration_(duration), num_frames_(num_frames) {}
~EasyUnlockAnimationDecoder() override = default;
// AnimatedRoundedImageView::AnimationDecoder:
AnimationFrames Decode(float image_scale) override {
SkBitmap bitmap = image_.GetRepresentation(image_scale).sk_bitmap();
int frame_width = bitmap.width() / num_frames_;
base::TimeDelta frame_duration = duration_ / num_frames_;
AnimationFrames animation;
animation.reserve(num_frames_);
for (int i = 0; i < num_frames_; ++i) {
// Get the subsection of the animation strip.
SkBitmap frame_bitmap;
bitmap.extractSubset(
&frame_bitmap,
SkIRect::MakeXYWH(i * frame_width, 0, frame_width, bitmap.height()));
// Add an animation frame.
AnimationFrame frame;
frame.duration = frame_duration;
frame.image = gfx::ImageSkia::CreateFrom1xBitmap(frame_bitmap);
animation.push_back(frame);
}
return animation;
}
private:
// The animation image source.
gfx::ImageSkia image_;
// The total duration of the animation.
base::TimeDelta duration_;
// The total number of frames in the animation.
int num_frames_;
DISALLOW_COPY_AND_ASSIGN(EasyUnlockAnimationDecoder);
};
} // namespace } // namespace
class LoginPasswordView::EasyUnlockIcon : public views::Button, class LoginPasswordView::EasyUnlockIcon : public views::Button,
...@@ -225,7 +170,6 @@ class LoginPasswordView::EasyUnlockIcon : public views::Button, ...@@ -225,7 +170,6 @@ class LoginPasswordView::EasyUnlockIcon : public views::Button,
SetPreferredSize(size); SetPreferredSize(size);
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
icon_ = new AnimatedRoundedImageView(size, corner_radius); icon_ = new AnimatedRoundedImageView(size, corner_radius);
icon_->SetAnimationEnabled(true);
AddChildView(icon_); AddChildView(icon_);
} }
~EasyUnlockIcon() override = default; ~EasyUnlockIcon() override = default;
...@@ -328,8 +272,10 @@ class LoginPasswordView::EasyUnlockIcon : public views::Button, ...@@ -328,8 +272,10 @@ class LoginPasswordView::EasyUnlockIcon : public views::Button,
DCHECK_EQ(resources.normal, resources.hover); DCHECK_EQ(resources.normal, resources.hover);
DCHECK_EQ(resources.normal, resources.pressed); DCHECK_EQ(resources.normal, resources.pressed);
if (changed_states) { if (changed_states) {
icon_->SetAnimationDecoder(std::make_unique<EasyUnlockAnimationDecoder>( icon_->SetAnimationDecoder(
*image, resources.duration, resources.num_frames)); std::make_unique<HorizontalImageSequenceAnimationDecoder>(
*image, resources.duration, resources.num_frames),
AnimatedRoundedImageView::Playback::kRepeat);
} }
} else { } else {
icon_->SetImage(*image); icon_->SetImage(*image);
......
...@@ -139,7 +139,11 @@ class LoginUserView::UserImage : public NonAccessibleView { ...@@ -139,7 +139,11 @@ class LoginUserView::UserImage : public NonAccessibleView {
} }
} }
void SetAnimationEnabled(bool enable) { image_->SetAnimationEnabled(enable); } void SetAnimationEnabled(bool enable) {
image_->SetAnimationPlayback(
enable ? AnimatedRoundedImageView::Playback::kRepeat
: AnimatedRoundedImageView::Playback::kFirstFrameOnly);
}
private: private:
void OnImageDecoded(AnimationFrames animation) { void OnImageDecoded(AnimationFrames animation) {
...@@ -150,7 +154,8 @@ class LoginUserView::UserImage : public NonAccessibleView { ...@@ -150,7 +154,8 @@ class LoginUserView::UserImage : public NonAccessibleView {
} }
image_->SetAnimationDecoder( image_->SetAnimationDecoder(
std::make_unique<PassthroughAnimationDecoder>(animation)); std::make_unique<PassthroughAnimationDecoder>(animation),
AnimatedRoundedImageView::Playback::kRepeat);
} }
AnimatedRoundedImageView* image_ = nullptr; AnimatedRoundedImageView* image_ = nullptr;
......
...@@ -46,8 +46,14 @@ enum FingerprintUnlockState { ...@@ -46,8 +46,14 @@ enum FingerprintUnlockState {
AVAILABLE, AVAILABLE,
// The unlock attempt is successful, the fingerprint is matched. // The unlock attempt is successful, the fingerprint is matched.
AUTH_SUCCESS, AUTH_SUCCESS,
// The unlock attempt is unsuccessful, the fingerprint is not recognized. // The unlock attempt is unsuccessful; the fingerprint is not
// recognized; however, the user can make another fingerprint auth
// attempt.
AUTH_FAILED, AUTH_FAILED,
// The unlock attempt is unsuccessful; the fingerprint is not
// recognized. There have been too many unlock attempts and fingerprint
// is now disabled.
AUTH_DISABLED,
}; };
// Information about the custom icon in the user pod. // Information about the custom icon in the user pod.
......
...@@ -42,14 +42,16 @@ constexpr char kLockDisplay[] = "lock"; ...@@ -42,14 +42,16 @@ constexpr char kLockDisplay[] = "lock";
ash::mojom::FingerprintUnlockState ConvertFromFingerprintState( ash::mojom::FingerprintUnlockState ConvertFromFingerprintState(
ScreenLocker::FingerprintState state) { ScreenLocker::FingerprintState state) {
switch (state) { switch (state) {
case ScreenLocker::FingerprintState::kRemoved:
case ScreenLocker::FingerprintState::kHidden: case ScreenLocker::FingerprintState::kHidden:
case ScreenLocker::FingerprintState::kDefault:
return ash::mojom::FingerprintUnlockState::UNAVAILABLE; return ash::mojom::FingerprintUnlockState::UNAVAILABLE;
case ScreenLocker::FingerprintState::kDefault:
return ash::mojom::FingerprintUnlockState::AVAILABLE;
case ScreenLocker::FingerprintState::kSignin: case ScreenLocker::FingerprintState::kSignin:
return ash::mojom::FingerprintUnlockState::AUTH_SUCCESS; return ash::mojom::FingerprintUnlockState::AUTH_SUCCESS;
case ScreenLocker::FingerprintState::kFailed: case ScreenLocker::FingerprintState::kFailed:
return ash::mojom::FingerprintUnlockState::AUTH_FAILED; return ash::mojom::FingerprintUnlockState::AUTH_FAILED;
case ScreenLocker::FingerprintState::kRemoved:
return ash::mojom::FingerprintUnlockState::AUTH_DISABLED;
} }
} }
......
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