blob: e95299e173cdc645efa86fa236edc9a370d1004a [file] [log] [blame]
// 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/chromeos/login/login_auth_recorder.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/ui/ash/tablet_mode_client.h"
#include "components/session_manager/core/session_manager.h"
namespace chromeos {
using AuthMethod = LoginAuthRecorder::AuthMethod;
using AuthMethodSwitchType = LoginAuthRecorder::AuthMethodSwitchType;
namespace {
AuthMethodSwitchType SwitchFromPasswordTo(AuthMethod current) {
DCHECK_NE(AuthMethod::kPassword, current);
switch (current) {
case AuthMethod::kPin:
return AuthMethodSwitchType::kPasswordToPin;
case AuthMethod::kSmartlock:
return AuthMethodSwitchType::kPasswordToSmartlock;
case AuthMethod::kFingerprint:
return AuthMethodSwitchType::kPasswordToFingerprint;
case AuthMethod::kPassword:
case AuthMethod::kMethodCount:
NOTREACHED();
return AuthMethodSwitchType::kSwitchTypeCount;
}
}
AuthMethodSwitchType SwitchFromPinTo(AuthMethod current) {
DCHECK_NE(AuthMethod::kPin, current);
switch (current) {
case AuthMethod::kPassword:
return AuthMethodSwitchType::kPinToPassword;
case AuthMethod::kSmartlock:
return AuthMethodSwitchType::kPinToSmartlock;
case AuthMethod::kFingerprint:
return AuthMethodSwitchType::kPinToFingerprint;
case AuthMethod::kPin:
case AuthMethod::kMethodCount:
NOTREACHED();
return AuthMethodSwitchType::kSwitchTypeCount;
}
}
AuthMethodSwitchType SwitchFromSmartlockTo(AuthMethod current) {
DCHECK_NE(AuthMethod::kSmartlock, current);
switch (current) {
case AuthMethod::kPassword:
return AuthMethodSwitchType::kSmartlockToPassword;
case AuthMethod::kPin:
return AuthMethodSwitchType::kSmartlockToPin;
case AuthMethod::kFingerprint:
return AuthMethodSwitchType::kSmartlockToFingerprint;
case AuthMethod::kSmartlock:
case AuthMethod::kMethodCount:
NOTREACHED();
return AuthMethodSwitchType::kSwitchTypeCount;
}
}
AuthMethodSwitchType SwitchFromFingerprintTo(AuthMethod current) {
DCHECK_NE(AuthMethod::kFingerprint, current);
switch (current) {
case AuthMethod::kPassword:
return AuthMethodSwitchType::kFingerprintToPassword;
case AuthMethod::kSmartlock:
return AuthMethodSwitchType::kFingerprintToSmartlock;
case AuthMethod::kPin:
return AuthMethodSwitchType::kFingerprintToPin;
case AuthMethod::kFingerprint:
case AuthMethod::kMethodCount:
NOTREACHED();
return AuthMethodSwitchType::kSwitchTypeCount;
}
}
AuthMethodSwitchType FindSwitchType(AuthMethod previous, AuthMethod current) {
DCHECK_NE(previous, current);
switch (previous) {
case AuthMethod::kPassword:
return SwitchFromPasswordTo(current);
case AuthMethod::kPin:
return SwitchFromPinTo(current);
case AuthMethod::kSmartlock:
return SwitchFromSmartlockTo(current);
case AuthMethod::kFingerprint:
return SwitchFromFingerprintTo(current);
case AuthMethod::kMethodCount:
NOTREACHED();
return AuthMethodSwitchType::kSwitchTypeCount;
}
}
} // namespace
LoginAuthRecorder::LoginAuthRecorder() {
session_manager::SessionManager::Get()->AddObserver(this);
}
LoginAuthRecorder::~LoginAuthRecorder() {
session_manager::SessionManager::Get()->RemoveObserver(this);
}
void LoginAuthRecorder::RecordAuthMethod(AuthMethod method) {
DCHECK_NE(method, AuthMethod::kMethodCount);
if (session_manager::SessionManager::Get()->session_state() !=
session_manager::SessionState::LOCKED) {
return;
}
// Record usage of PIN / Password / Smartlock / Fingerprint in lock screen.
const bool is_tablet_mode = TabletModeClient::Get()->tablet_mode_enabled();
if (is_tablet_mode) {
UMA_HISTOGRAM_ENUMERATION("Ash.Login.Lock.AuthMethod.Used.TabletMode",
method, AuthMethod::kMethodCount);
} else {
UMA_HISTOGRAM_ENUMERATION("Ash.Login.Lock.AuthMethod.Used.ClamShellMode",
method, AuthMethod::kMethodCount);
}
if (last_auth_method_ != method) {
// Record switching between unlock methods.
UMA_HISTOGRAM_ENUMERATION("Ash.Login.Lock.AuthMethod.Switched",
FindSwitchType(last_auth_method_, method),
AuthMethodSwitchType::kSwitchTypeCount);
last_auth_method_ = method;
}
}
void LoginAuthRecorder::RecordFingerprintAuthSuccess(
bool success,
const base::Optional<int>& num_attempts) {
if (session_manager::SessionManager::Get()->session_state() !=
session_manager::SessionState::LOCKED) {
return;
}
UMA_HISTOGRAM_BOOLEAN("Fingerprint.Unlock.AuthSuccessful", success);
if (success) {
DCHECK(num_attempts);
UMA_HISTOGRAM_COUNTS_100("Fingerprint.Unlock.AttemptsCountBeforeSuccess",
num_attempts.value());
}
}
void LoginAuthRecorder::OnSessionStateChanged() {
// Reset local state.
last_auth_method_ = AuthMethod::kPassword;
}
} // namespace chromeos