| Index: chromeos/dbus/biod/biod_client.cc
|
| diff --git a/chromeos/dbus/biod/biod_client.cc b/chromeos/dbus/biod/biod_client.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6bc3b59695b9f600b30403caa5fae43b012892fe
|
| --- /dev/null
|
| +++ b/chromeos/dbus/biod/biod_client.cc
|
| @@ -0,0 +1,284 @@
|
| +// Copyright 2017 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 "chromeos/dbus/biod/biod_client.h"
|
| +
|
| +#include <stdint.h>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/macros.h"
|
| +#include "dbus/bus.h"
|
| +#include "dbus/message.h"
|
| +#include "dbus/object_path.h"
|
| +#include "dbus/object_proxy.h"
|
| +
|
| +namespace chromeos {
|
| +
|
| +// The BiodClient implementation used in production.
|
| +class BiodClientImpl : public BiodClient {
|
| + public:
|
| + BiodClientImpl() : biod_proxy_(nullptr), weak_ptr_factory_(this) {}
|
| +
|
| + ~BiodClientImpl() override {}
|
| +
|
| + // BiodClient overrides:
|
| + void AddObserver(Observer* observer) override {
|
| + observers_.AddObserver(observer);
|
| + }
|
| +
|
| + void RemoveObserver(Observer* observer) override {
|
| + observers_.RemoveObserver(observer);
|
| + }
|
| +
|
| + bool HasObserver(const Observer* observer) const override {
|
| + return observers_.HasObserver(observer);
|
| + }
|
| +
|
| + void StartEnrollSession(const std::string& user_id,
|
| + const std::string& label,
|
| + const ObjectPathCallback& callback) override {
|
| + dbus::MethodCall method_call(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerStartEnrollSessionMethod);
|
| + dbus::MessageWriter writer(&method_call);
|
| + writer.AppendString(user_id);
|
| + writer.AppendString(label);
|
| +
|
| + biod_proxy_->CallMethod(
|
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&BiodClientImpl::OnStartEnrollSession,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| + }
|
| +
|
| + void GetRecordsForUser(const std::string& user_id,
|
| + const UserRecordsCallback& callback) override {
|
| + dbus::MethodCall method_call(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerGetRecordsForUserMethod);
|
| + dbus::MessageWriter writer(&method_call);
|
| + writer.AppendString(user_id);
|
| +
|
| + biod_proxy_->CallMethod(
|
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&BiodClientImpl::OnGetRecordsForUser,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| + }
|
| +
|
| + void DestroyAllRecords() override {
|
| + dbus::MethodCall method_call(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerDestroyAllRecordsMethod);
|
| +
|
| + biod_proxy_->CallMethod(&method_call,
|
| + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + dbus::ObjectProxy::EmptyResponseCallback());
|
| + }
|
| +
|
| + void StartAuthSession(const ObjectPathCallback& callback) override {
|
| + dbus::MethodCall method_call(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerStartAuthSessionMethod);
|
| +
|
| + biod_proxy_->CallMethod(
|
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&BiodClientImpl::OnStartAuthSession,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| + }
|
| +
|
| + void RequestType(const BiometricTypeCallback& callback) override {
|
| + dbus::MethodCall method_call(dbus::kDBusPropertiesInterface,
|
| + dbus::kDBusPropertiesGet);
|
| + dbus::MessageWriter writer(&method_call);
|
| + writer.AppendString(biod::kBiometricsManagerInterface);
|
| + writer.AppendString(biod::kBiometricsManagerBiometricTypeProperty);
|
| +
|
| + biod_proxy_->CallMethod(
|
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
|
| + base::Bind(&BiodClientImpl::OnRequestType,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| + }
|
| +
|
| + protected:
|
| + void Init(dbus::Bus* bus) override {
|
| + biod_proxy_ = bus->GetObjectProxy(biod::kBiodServiceName,
|
| + dbus::ObjectPath(biod::kBiodServicePath));
|
| +
|
| + biod_proxy_->SetNameOwnerChangedCallback(
|
| + base::Bind(&BiodClientImpl::NameOwnerChangedReceived,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +
|
| + biod_proxy_->ConnectToSignal(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerEnrollScanDoneSignal,
|
| + base::Bind(&BiodClientImpl::EnrollScanDoneReceived,
|
| + weak_ptr_factory_.GetWeakPtr()),
|
| + base::Bind(&BiodClientImpl::OnSignalConnected,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +
|
| + biod_proxy_->ConnectToSignal(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerAuthScanDoneSignal,
|
| + base::Bind(&BiodClientImpl::AuthScanDoneReceived,
|
| + weak_ptr_factory_.GetWeakPtr()),
|
| + base::Bind(&BiodClientImpl::OnSignalConnected,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +
|
| + biod_proxy_->ConnectToSignal(
|
| + biod::kBiometricsManagerInterface,
|
| + biod::kBiometricsManagerSessionFailedSignal,
|
| + base::Bind(&BiodClientImpl::SessionFailedReceived,
|
| + weak_ptr_factory_.GetWeakPtr()),
|
| + base::Bind(&BiodClientImpl::OnSignalConnected,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| + }
|
| +
|
| + private:
|
| + void OnStartEnrollSession(const ObjectPathCallback& callback,
|
| + dbus::Response* response) {
|
| + dbus::ObjectPath result;
|
| + if (response) {
|
| + dbus::MessageReader reader(response);
|
| + if (!reader.PopObjectPath(&result)) {
|
| + LOG(ERROR) << biod::kBiometricsManagerStartEnrollSessionMethod
|
| + << " had incorrect response.";
|
| + }
|
| + }
|
| +
|
| + callback.Run(result);
|
| + }
|
| +
|
| + void OnGetRecordsForUser(const UserRecordsCallback& callback,
|
| + dbus::Response* response) {
|
| + std::vector<dbus::ObjectPath> result;
|
| + if (response) {
|
| + dbus::MessageReader reader(response);
|
| + if (!reader.PopArrayOfObjectPaths(&result)) {
|
| + LOG(ERROR) << biod::kBiometricsManagerGetRecordsForUserMethod
|
| + << " had incorrect response.";
|
| + }
|
| + }
|
| +
|
| + callback.Run(result);
|
| + }
|
| +
|
| + void OnStartAuthSession(const ObjectPathCallback& callback,
|
| + dbus::Response* response) {
|
| + dbus::ObjectPath result;
|
| + if (response) {
|
| + dbus::MessageReader reader(response);
|
| + if (!reader.PopObjectPath(&result)) {
|
| + LOG(ERROR) << biod::kBiometricsManagerStartAuthSessionMethod
|
| + << " had incorrect response.";
|
| + }
|
| + }
|
| +
|
| + callback.Run(result);
|
| + }
|
| +
|
| + void OnRequestType(const BiometricTypeCallback& callback,
|
| + dbus::Response* response) {
|
| + uint32_t result =
|
| + static_cast<uint32_t>(biod::BiometricType::BIOMETRIC_TYPE_UNKNOWN);
|
| + if (response) {
|
| + dbus::MessageReader reader(response);
|
| + if (!reader.PopVariantOfUint32(&result)) {
|
| + LOG(ERROR) << biod::kBiometricsManagerBiometricTypeProperty
|
| + << " had incorrect response.";
|
| + }
|
| + }
|
| +
|
| + callback.Run(static_cast<biod::BiometricType>(result));
|
| + }
|
| +
|
| + // Called when the biometrics signal is initially connected.
|
| + void OnSignalConnected(const std::string& interface_name,
|
| + const std::string& signal_name,
|
| + bool success) {
|
| + LOG_IF(ERROR, !success)
|
| + << "Failed to connect to biometrics signal: " << signal_name;
|
| + }
|
| +
|
| + void NameOwnerChangedReceived(const std::string& /* old_owner */,
|
| + const std::string& new_owner) {
|
| + if (!new_owner.empty()) {
|
| + for (auto& observer : observers_)
|
| + observer.BiodServiceRestarted();
|
| + }
|
| + }
|
| +
|
| + void EnrollScanDoneReceived(dbus::Signal* signal) {
|
| + dbus::MessageReader reader(signal);
|
| + uint32_t scan_result;
|
| + bool enroll_session_complete;
|
| + if (!reader.PopUint32(&scan_result) ||
|
| + !reader.PopBool(&enroll_session_complete)) {
|
| + LOG(ERROR) << "Error reading signal from biometrics: "
|
| + << signal->ToString();
|
| + return;
|
| + }
|
| +
|
| + for (auto& observer : observers_) {
|
| + observer.BiodEnrollScanDoneReceived(
|
| + static_cast<biod::ScanResult>(scan_result), enroll_session_complete);
|
| + }
|
| + }
|
| +
|
| + void AuthScanDoneReceived(dbus::Signal* signal) {
|
| + dbus::MessageReader signal_reader(signal);
|
| + dbus::MessageReader array_reader(nullptr);
|
| + uint32_t scan_result;
|
| + AuthScanMatches matches;
|
| + if (!signal_reader.PopUint32(&scan_result) ||
|
| + !signal_reader.PopArray(&array_reader)) {
|
| + LOG(ERROR) << "Error reading signal from biometrics: "
|
| + << signal->ToString();
|
| + return;
|
| + }
|
| +
|
| + while (array_reader.HasMoreData()) {
|
| + dbus::MessageReader entry_reader(nullptr);
|
| + std::string user_id;
|
| + std::vector<std::string> labels;
|
| + if (!array_reader.PopDictEntry(&entry_reader) ||
|
| + !entry_reader.PopString(&user_id) ||
|
| + !entry_reader.PopArrayOfStrings(&labels)) {
|
| + LOG(ERROR) << "Error reading signal from biometrics: "
|
| + << signal->ToString();
|
| + return;
|
| + }
|
| +
|
| + matches[user_id] = std::move(labels);
|
| + }
|
| +
|
| + for (auto& observer : observers_) {
|
| + observer.BiodAuthScanDoneReceived(
|
| + static_cast<biod::ScanResult>(scan_result), matches);
|
| + }
|
| + }
|
| +
|
| + void SessionFailedReceived(dbus::Signal* signal) {
|
| + for (auto& observer : observers_)
|
| + observer.BiodSessionFailedReceived();
|
| + }
|
| +
|
| + dbus::ObjectProxy* biod_proxy_;
|
| + base::ObserverList<Observer> observers_;
|
| +
|
| + // Note: This should remain the last member so it'll be destroyed and
|
| + // invalidate its weak pointers before any other members are destroyed.
|
| + base::WeakPtrFactory<BiodClientImpl> weak_ptr_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(BiodClientImpl);
|
| +};
|
| +
|
| +BiodClient::BiodClient() {}
|
| +
|
| +BiodClient::~BiodClient() {}
|
| +
|
| +// static
|
| +BiodClient* BiodClient::Create(DBusClientImplementationType /* type */) {
|
| + return new BiodClientImpl();
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|