Commit 1850b0d5 authored by Fergus Dall's avatar Fergus Dall Committed by Commit Bot

Add AnomalyDetectorClient to //chromeos/dbus

This will be used to detect VM filesystem corruption.

Bug: 1018093
Change-Id: Icf95a14e6d106a7e7f391e15a3f2e9cd648c4499
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1915649
Commit-Queue: Fergus Dall <sidereal@google.com>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718016}
parent de4a565f
......@@ -23,6 +23,7 @@ component("dbus") {
"//dbus",
]
deps = [
":anomaly_detector_proto",
":cicerone_proto",
":concierge_proto",
":metrics_event_proto",
......@@ -42,6 +43,8 @@ component("dbus") {
"//url",
]
sources = [
"anomaly_detector_client.cc",
"anomaly_detector_client.h",
"arc_appfuse_provider_client.cc",
"arc_appfuse_provider_client.h",
"arc_camera_client.cc",
......@@ -69,6 +72,8 @@ component("dbus") {
"dbus_thread_manager.h",
"easy_unlock_client.cc",
"easy_unlock_client.h",
"fake_anomaly_detector_client.cc",
"fake_anomaly_detector_client.h",
"fake_arc_appfuse_provider_client.cc",
"fake_arc_appfuse_provider_client.h",
"fake_arc_camera_client.cc",
......@@ -241,6 +246,14 @@ source_set("unit_tests") {
]
}
proto_library("anomaly_detector_proto") {
sources = [
"//third_party/cros_system_api/dbus/anomaly_detector/anomaly_detector.proto",
]
proto_out_dir = "chromeos/dbus/anomaly_detector"
}
proto_library("cicerone_proto") {
sources = [
"//third_party/cros_system_api/dbus/vm_cicerone/cicerone_service.proto",
......
// Copyright 2019 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/anomaly_detector_client.h"
#include <memory>
#include "base/bind.h"
#include "base/observer_list.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/anomaly_detector/dbus-constants.h"
namespace chromeos {
class AnomalyDetectorClientImpl : public AnomalyDetectorClient {
public:
AnomalyDetectorClientImpl() = default;
AnomalyDetectorClientImpl(const AnomalyDetectorClientImpl&) = delete;
AnomalyDetectorClientImpl& operator=(const AnomalyDetectorClientImpl&) =
delete;
~AnomalyDetectorClientImpl() override = default;
void AddObserver(Observer* observer) override {
observer_list_.AddObserver(observer);
}
void RemoveObserver(Observer* observer) override {
observer_list_.RemoveObserver(observer);
}
bool IsGuestFileCorruptionSignalConnected() override {
return is_guest_file_corruption_signal_connected_;
}
protected:
void Init(dbus::Bus* bus) override {
anomaly_detector_proxy_ = bus->GetObjectProxy(
anomaly_detector::kAnomalyEventServiceName,
dbus::ObjectPath(anomaly_detector::kAnomalyEventServicePath));
if (!anomaly_detector_proxy_) {
LOG(ERROR) << "Unable to get dbus proxy for "
<< anomaly_detector::kAnomalyEventServiceName;
}
anomaly_detector_proxy_->ConnectToSignal(
anomaly_detector::kAnomalyEventServiceInterface,
anomaly_detector::kAnomalyGuestFileCorruptionSignalName,
base::BindRepeating(
&AnomalyDetectorClientImpl::OnGuestFileCorruptionSignal,
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&AnomalyDetectorClientImpl::OnSignalConnected,
weak_ptr_factory_.GetWeakPtr()));
}
private:
void OnGuestFileCorruptionSignal(dbus::Signal* signal) {
anomaly_detector::GuestFileCorruptionSignal proto_signal;
dbus::MessageReader reader(signal);
if (!reader.PopArrayOfBytesAsProto(&proto_signal)) {
LOG(ERROR) << "Failed to parse proto from DBus Signal";
return;
}
for (auto& observer : observer_list_) {
observer.OnGuestFileCorruption(proto_signal);
}
}
void OnSignalConnected(const std::string& interface_name,
const std::string& signal_name,
bool is_connected) {
if (!is_connected) {
LOG(ERROR) << "Failed to connect to signal " << signal_name;
}
DCHECK_EQ(interface_name, anomaly_detector::kAnomalyEventServiceInterface);
if (signal_name ==
anomaly_detector::kAnomalyGuestFileCorruptionSignalName) {
is_guest_file_corruption_signal_connected_ = is_connected;
} else {
NOTREACHED();
}
}
dbus::ObjectProxy* anomaly_detector_proxy_ = nullptr;
base::ObserverList<Observer> observer_list_;
bool is_guest_file_corruption_signal_connected_ = false;
// 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<AnomalyDetectorClientImpl> weak_ptr_factory_{this};
};
AnomalyDetectorClient::AnomalyDetectorClient() = default;
AnomalyDetectorClient::~AnomalyDetectorClient() = default;
std::unique_ptr<AnomalyDetectorClient> AnomalyDetectorClient::Create() {
return std::make_unique<AnomalyDetectorClientImpl>();
}
} // namespace chromeos
// Copyright 2019 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 CHROMEOS_DBUS_ANOMALY_DETECTOR_CLIENT_H_
#define CHROMEOS_DBUS_ANOMALY_DETECTOR_CLIENT_H_
#include <memory>
#include "base/component_export.h"
#include "base/observer_list_types.h"
#include "chromeos/dbus/anomaly_detector/anomaly_detector.pb.h"
#include "chromeos/dbus/dbus_client.h"
namespace chromeos {
// AnomalyDetectorClient is used to communicate with anomaly_detector.
// Currently this just amounts to listening to signals it sends.
class COMPONENT_EXPORT(CHROMEOS_DBUS) AnomalyDetectorClient
: public DBusClient {
public:
class Observer : public base::CheckedObserver {
public:
// OnGuestFileCorruption is signaled by anomaly_detector when it detects
// that a VM has encountered filesystem corruption.
virtual void OnGuestFileCorruption(
const anomaly_detector::GuestFileCorruptionSignal& signal) = 0;
};
AnomalyDetectorClient(const AnomalyDetectorClient&) = delete;
AnomalyDetectorClient& operator=(const AnomalyDetectorClient&) = delete;
~AnomalyDetectorClient() override;
// Adds an observer.
virtual void AddObserver(Observer* observer) = 0;
// Removes an observer if added.
virtual void RemoveObserver(Observer* observer) = 0;
// IsGuestFileCorruptionSignalConnected must return true before starting a VM,
// or we will be unable to detect if it's filesystem is corrupt.
virtual bool IsGuestFileCorruptionSignalConnected() = 0;
// Creates an instance of AnomalyDetectorClient.
static std::unique_ptr<AnomalyDetectorClient> Create();
protected:
// Create() should be used instead.
AnomalyDetectorClient();
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_ANOMALY_DETECTOR_CLIENT_H_
......@@ -5,6 +5,7 @@
#include "chromeos/dbus/dbus_clients_browser.h"
#include "base/logging.h"
#include "chromeos/dbus/anomaly_detector_client.h"
#include "chromeos/dbus/arc_appfuse_provider_client.h"
#include "chromeos/dbus/arc_keymaster_client.h"
#include "chromeos/dbus/arc_midis_client.h"
......@@ -19,6 +20,7 @@
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
#include "chromeos/dbus/debug_daemon/fake_debug_daemon_client.h"
#include "chromeos/dbus/easy_unlock_client.h"
#include "chromeos/dbus/fake_anomaly_detector_client.h"
#include "chromeos/dbus/fake_arc_appfuse_provider_client.h"
#include "chromeos/dbus/fake_arc_keymaster_client.h"
#include "chromeos/dbus/fake_arc_midis_client.h"
......@@ -73,6 +75,8 @@ DBusClientsBrowser::DBusClientsBrowser(bool use_real_clients) {
use_real_clients ? REAL_DBUS_CLIENT_IMPLEMENTATION
: FAKE_DBUS_CLIENT_IMPLEMENTATION;
anomaly_detector_client_ =
CREATE_DBUS_CLIENT(AnomalyDetectorClient, use_real_clients);
arc_appfuse_provider_client_ =
CREATE_DBUS_CLIENT(ArcAppfuseProviderClient, use_real_clients);
arc_keymaster_client_ =
......@@ -115,6 +119,7 @@ DBusClientsBrowser::~DBusClientsBrowser() = default;
void DBusClientsBrowser::Initialize(dbus::Bus* system_bus) {
DCHECK(DBusThreadManager::IsInitialized());
anomaly_detector_client_->Init(system_bus);
arc_appfuse_provider_client_->Init(system_bus);
arc_keymaster_client_->Init(system_bus);
arc_midis_client_->Init(system_bus);
......
......@@ -16,6 +16,7 @@ class Bus;
namespace chromeos {
class AnomalyDetectorClient;
class ArcAppfuseProviderClient;
class ArcKeymasterClient;
class ArcMidisClient;
......@@ -54,6 +55,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusClientsBrowser {
friend class DBusThreadManager;
friend class DBusThreadManagerSetter;
std::unique_ptr<AnomalyDetectorClient> anomaly_detector_client_;
std::unique_ptr<ArcAppfuseProviderClient> arc_appfuse_provider_client_;
std::unique_ptr<ArcKeymasterClient> arc_keymaster_client_;
std::unique_ptr<ArcMidisClient> arc_midis_client_;
......
......@@ -11,6 +11,7 @@
#include "base/message_loop/message_pump_type.h"
#include "base/system/sys_info.h"
#include "base/threading/thread.h"
#include "chromeos/dbus/anomaly_detector_client.h"
#include "chromeos/dbus/arc_keymaster_client.h"
#include "chromeos/dbus/arc_midis_client.h"
#include "chromeos/dbus/arc_obb_mounter_client.h"
......@@ -107,6 +108,11 @@ dbus::Bus* DBusThreadManager::GetSystemBus() {
return system_bus_.get();
}
AnomalyDetectorClient* DBusThreadManager::GetAnomalyDetectorClient() {
return clients_browser_ ? clients_browser_->anomaly_detector_client_.get()
: nullptr;
}
ArcAppfuseProviderClient* DBusThreadManager::GetArcAppfuseProviderClient() {
return clients_browser_ ? clients_browser_->arc_appfuse_provider_client_.get()
: nullptr;
......
......@@ -24,6 +24,7 @@ class Bus;
namespace chromeos {
// Style Note: Clients are sorted by names.
class AnomalyDetectorClient;
class ArcAppfuseProviderClient;
class ArcKeymasterClient;
class ArcMidisClient;
......@@ -115,6 +116,7 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusThreadManager {
// pointers after DBusThreadManager has been shut down.
// TODO(jamescook): Replace this with calls to FooClient::Get().
// http://crbug.com/647367
AnomalyDetectorClient* GetAnomalyDetectorClient();
ArcAppfuseProviderClient* GetArcAppfuseProviderClient();
ArcKeymasterClient* GetArcKeymasterClient();
ArcMidisClient* GetArcMidisClient();
......
......@@ -20,6 +20,7 @@ TEST(DBusThreadManagerTest, Initialize) {
EXPECT_TRUE(manager->IsUsingFakes());
// Clients were created.
EXPECT_TRUE(manager->GetAnomalyDetectorClient());
EXPECT_TRUE(manager->GetArcMidisClient());
EXPECT_TRUE(manager->GetArcObbMounterClient());
EXPECT_TRUE(manager->GetArcOemCryptoClient());
......@@ -63,6 +64,7 @@ TEST(DBusThreadManagerTest, InitializeForBrowser) {
EXPECT_TRUE(manager->GetUpdateEngineClient());
// Clients for the browser were created.
EXPECT_TRUE(manager->GetAnomalyDetectorClient());
EXPECT_TRUE(manager->GetArcMidisClient());
EXPECT_TRUE(manager->GetArcObbMounterClient());
EXPECT_TRUE(manager->GetArcOemCryptoClient());
......@@ -95,6 +97,7 @@ TEST(DBusThreadManagerTest, InitializeForAsh) {
EXPECT_TRUE(manager->GetSMSClient());
// Clients for other processes were not created.
EXPECT_FALSE(manager->GetAnomalyDetectorClient());
EXPECT_FALSE(manager->GetArcMidisClient());
EXPECT_FALSE(manager->GetArcObbMounterClient());
EXPECT_FALSE(manager->GetArcOemCryptoClient());
......
// Copyright 2019 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/fake_anomaly_detector_client.h"
namespace chromeos {
FakeAnomalyDetectorClient::FakeAnomalyDetectorClient() = default;
FakeAnomalyDetectorClient::~FakeAnomalyDetectorClient() = default;
void FakeAnomalyDetectorClient::Init(dbus::Bus* bus) {}
void FakeAnomalyDetectorClient::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void FakeAnomalyDetectorClient::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
bool FakeAnomalyDetectorClient::IsGuestFileCorruptionSignalConnected() {
return is_container_started_signal_connected_;
}
void FakeAnomalyDetectorClient::set_guest_file_corruption_signal_connected(
bool connected) {
is_container_started_signal_connected_ = connected;
}
void FakeAnomalyDetectorClient::NotifyGuestFileCorruption(
const anomaly_detector::GuestFileCorruptionSignal& signal) {
for (auto& observer : observer_list_) {
observer.OnGuestFileCorruption(signal);
}
}
} // namespace chromeos
// Copyright 2019 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 CHROMEOS_DBUS_FAKE_ANOMALY_DETECTOR_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_ANOMALY_DETECTOR_CLIENT_H_
#include "base/observer_list.h"
#include "chromeos/dbus/anomaly_detector_client.h"
namespace chromeos {
// FakeAnomalyDetectorClient is a fake implementation of AnomalyDetectorClient
// used for testing.
class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeAnomalyDetectorClient
: public AnomalyDetectorClient {
public:
FakeAnomalyDetectorClient();
FakeAnomalyDetectorClient(const FakeAnomalyDetectorClient&) = delete;
FakeAnomalyDetectorClient& operator=(const FakeAnomalyDetectorClient&) =
delete;
~FakeAnomalyDetectorClient() override;
// AnomalyDetectorClient:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
bool IsGuestFileCorruptionSignalConnected() override;
void set_guest_file_corruption_signal_connected(bool connected);
void NotifyGuestFileCorruption(
const anomaly_detector::GuestFileCorruptionSignal& signal);
protected:
void Init(dbus::Bus* bus) override;
private:
bool is_container_started_signal_connected_ = true;
base::ObserverList<Observer> observer_list_;
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_ANOMALY_DETECTOR_CLIENT_H_
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