blob: ca384220093b8c11454d7968720a5b04a0388916 [file] [log] [blame]
// Copyright 2020 The Chromium OS 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 CRYPTOHOME_FINGERPRINT_MANAGER_H_
#define CRYPTOHOME_FINGERPRINT_MANAGER_H_
#include <memory>
#include <string>
#include <biod/biod_proxy/biometrics_manager_proxy_base.h>
namespace cryptohome {
const char kCrosFpBiometricsManagerRelativePath[] = "/CrosFpBiometricsManager";
const int kMaxFingerprintRetries = 5;
enum class FingerprintScanStatus {
SUCCESS = 0,
FAILED_RETRY_ALLOWED = 1,
FAILED_RETRY_NOT_ALLOWED = 2,
};
// FingerprintManager talks to Biometrics Daemon for starting/stopping
// fingerprint auth sessions, and receiving fingerprint auth results.
//
// This class is intended to be used only on a single thread / task runner only.
// Response callbacks will also be run on the same thread / task runner.
class FingerprintManager {
public:
using StartSessionCallback = base::Callback<void(bool success)>;
using ResultCallback = base::Callback<void(FingerprintScanStatus status)>;
// Factory method. Returns nullptr if Biometrics Daemon is not in a good
// state or if the device does not have fingerprint support.
static std::unique_ptr<FingerprintManager> Create(
const scoped_refptr<dbus::Bus>& bus, const dbus::ObjectPath& path);
FingerprintManager();
virtual ~FingerprintManager();
const std::string& GetCurrentUser();
// Returns a weak pointer to this instance. Used when creating callbacks.
base::WeakPtr<FingerprintManager> GetWeakPtr();
// Starts fingerprint auth session asynchronously, and sets the user if auth
// session started successfully.
// |auth_session_start_client_callback| will be called with true if auth
// session started successfully, or called with false otherwise.
//
// One auth session may serve multiple fingerprint-related calls, e.g.
// multiple CheckKey() calls with KEY_TYPE_FINGERPRINT, until one of the
// following occurs:
// 1. One fingerprint scan succeeds, or a non-recoverable error occurs.
// |state_| will be set to AUTH_SESSION_LOCKED.
// 2. Max retry count reached for the current auth session. |state_| will be
// set to AUTH_SESSION_LOCKED.
// 3. EndAuthSession() is called, e.g. user decides to cancel operation
// through UI.
virtual void StartAuthSessionAsyncForUser(
const std::string& user,
StartSessionCallback auth_session_start_client_callback);
// Tells Biometrics Daemon to end fingerprint auth session and resets all
// states.
virtual void EndAuthSession();
virtual bool HasAuthSessionForUser(const std::string& user);
// Sets the callback for a fingerprint scan. Must be called after
// StartAuthSessionAsyncForUser. |auth_scan_done_callback| will be
// called with the status of a fingerprint match, once biod sends it.
virtual void SetAuthScanDoneCallback(ResultCallback auth_scan_done_callback);
// For testing.
void SetProxy(biod::BiometricsManagerProxyBase* proxy);
private:
friend class FingerprintManagerPeer;
enum class State {
NO_AUTH_SESSION = 0,
AUTH_SESSION_OPEN = 1,
// A fatal error occurred, or max retry count reached, but auth
// session is not cancelled yet.
AUTH_SESSION_LOCKED = 2,
};
// Class for properly finish processing an AuthScanDone signal.
class AuthScanDoneResourceManager {
public:
explicit AuthScanDoneResourceManager(
FingerprintManager* fingerprint_manager)
: fingerprint_manager_(fingerprint_manager) {}
~AuthScanDoneResourceManager() {
fingerprint_manager_->auth_scan_done_callback_.Reset();
// If auth session is still open, then we are waiting for retry, so keep
// |current_user_|.
if (fingerprint_manager_->state_ != State::AUTH_SESSION_OPEN)
fingerprint_manager_->current_user_.clear();
}
private:
FingerprintManager* fingerprint_manager_;
};
// Initializes the underlying dbus object proxy for BiometricsDaemon, and
// connects to relevant dbus signals. Returns false if failing to get the
// dbus object proxy (e.g. if biod is not in a good state or the device does
// not have fingerprint support).
bool Initialize(const scoped_refptr<dbus::Bus>& bus,
const dbus::ObjectPath& path);
// Callback for connecting to biod's AuthScanDoneSignal.
void OnAuthScanDoneSignalConnected(const std::string& interface,
const std::string& signal,
bool success);
// Signal handler biod::kBiometricsManagerAuthScanDoneSignal.
// Parses the auth scan result from biod, compares the matched user to
// |current_user_|, and calls |auth_scan_done_callback_|.
void OnAuthScanDone(dbus::Signal* signal);
// Internal wrapper around the client's callback for starting auth session
// asynchronously. If auth session starts successfully, set |current_user_|
// before running the client's callback.
void SetUserAndRunClientCallback(
StartSessionCallback auth_session_start_client_callback,
const std::string& user,
bool success);
// Calculates the retry count left in the current auth session, and run
// |auth_scan_done_callback_|.
void ProcessRetry();
void Reset();
// The default BiometricsManagerProxyBase object.
std::unique_ptr<biod::BiometricsManagerProxyBase> default_proxy_;
// The actual BiometricsManagerProxyBase object used in this class.
// Can be overridden for testing.
biod::BiometricsManagerProxyBase* proxy_;
bool connected_to_auth_scan_done_signal_;
ResultCallback auth_scan_done_callback_;
State state_ = State::NO_AUTH_SESSION;
// The obfuscated username tied to the current auth session.
std::string current_user_;
// The number of retries left in the current auth session.
int retry_left_ = 0;
base::WeakPtrFactory<FingerprintManager> weak_factory_;
base::PlatformThreadId mount_thread_id_;
};
} // namespace cryptohome
#endif // CRYPTOHOME_FINGERPRINT_MANAGER_H_