blob: 4e4766a9798cbfe9ad5fbd7899d257827964b4c5 [file] [log] [blame]
// Copyright 2018 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 DIAGNOSTICS_DIAGNOSTICSD_DIAGNOSTICSD_CORE_H_
#define DIAGNOSTICS_DIAGNOSTICSD_DIAGNOSTICSD_CORE_H_
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/strings/string_piece.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <brillo/dbus/dbus_object.h>
#include <dbus/bus.h>
#include <mojo/public/cpp/bindings/binding.h>
#include "diagnostics/diagnosticsd/diagnosticsd_dbus_service.h"
#include "diagnostics/diagnosticsd/diagnosticsd_ec_event_service.h"
#include "diagnostics/diagnosticsd/diagnosticsd_grpc_service.h"
#include "diagnostics/diagnosticsd/diagnosticsd_mojo_service.h"
#include "diagnostics/grpc_async_adapter/async_grpc_client.h"
#include "diagnostics/grpc_async_adapter/async_grpc_server.h"
#include "diagnostics_processor.grpc.pb.h" // NOLINT(build/include)
#include "diagnosticsd.grpc.pb.h" // NOLINT(build/include)
#include "mojo/diagnosticsd.mojom.h"
namespace diagnostics {
// Integrates together all pieces which implement separate IPC services exposed
// by the diagnosticsd daemon and IPC clients.
class DiagnosticsdCore final
: public DiagnosticsdDBusService::Delegate,
public DiagnosticsdEcEventService::Delegate,
public DiagnosticsdGrpcService::Delegate,
public DiagnosticsdMojoService::Delegate,
public chromeos::diagnosticsd::mojom::DiagnosticsdServiceFactory {
public:
class Delegate {
public:
using MojomDiagnosticsdServiceFactory =
chromeos::diagnosticsd::mojom::DiagnosticsdServiceFactory;
virtual ~Delegate() = default;
// Binds the given |mojo_service_factory| to the Mojo message pipe that
// works via the given |mojo_pipe_fd|. On success, returns the created Mojo
// binding, otherwise returns nullptr.
//
// In production this method must be called no more than once during the
// lifetime of the daemon, since Mojo EDK gives no guarantee to support
// repeated initialization with different parent handles.
virtual std::unique_ptr<mojo::Binding<MojomDiagnosticsdServiceFactory>>
BindDiagnosticsdMojoServiceFactory(
MojomDiagnosticsdServiceFactory* mojo_service_factory,
base::ScopedFD mojo_pipe_fd) = 0;
// Begins the graceful shutdown of the diagnosticsd daemon.
virtual void BeginDaemonShutdown() = 0;
};
// |grpc_service_uri| is the URI on which the gRPC interface exposed by the
// diagnosticsd daemon will be listening.
// |ui_message_receiver_diagnostics_processor_grpc_uri| is the URI which is
// used for making requests to the gRPC interface exposed by the
// diagnostics_processor daemon which is explicitly eligible to receive
// messages from UI extension (hosted by browser), no other gRPC client
// recieves messages from UI extension.
// |diagnostics_processor_grpc_uris| is the list of URI's which are used for
// making requests to the gRPC interface exposed by the diagnostics_processor
// daemons. Should not contain the URI equal to
// |ui_message_receiver_diagnostics_processor_grpc_uri|.
DiagnosticsdCore(
const std::string& grpc_service_uri,
const std::string& ui_message_receiver_diagnostics_processor_grpc_uri,
const std::vector<std::string>& diagnostics_processor_grpc_uris,
Delegate* delegate);
~DiagnosticsdCore() override;
// Overrides the file system root directory for file operations in tests.
void set_root_dir_for_testing(const base::FilePath& root_dir) {
ec_event_service_.set_root_dir_for_testing(root_dir);
grpc_service_.set_root_dir_for_testing(root_dir);
}
// Overrides EC event fd events for |poll()| function in |ec_event_service_|
// service in tests.
void set_ec_event_service_fd_events_for_testing(int16_t events) {
ec_event_service_.set_event_fd_events_for_testing(events);
}
// Starts gRPC servers, gRPC clients and EC event service.
bool Start();
// Performs asynchronous shutdown and cleanup of gRPC servers, gRPC clients
// and EC event service.
// This must be used before deleting this instance in case Start() was
// called and returned success - in that case, the instance must be
// destroyed only after |on_shutdown| has been called.
void ShutDown(const base::Closure& on_shutdown);
// Register the D-Bus object that the diagnosticsd daemon exposes and tie
// methods exposed by this object with the actual implementation.
void RegisterDBusObjectsAsync(
const scoped_refptr<dbus::Bus>& bus,
brillo::dbus_utils::AsyncEventSequencer* sequencer);
private:
using MojomDiagnosticsdClientPtr =
chromeos::diagnosticsd::mojom::DiagnosticsdClientPtr;
using MojomDiagnosticsdServiceRequest =
chromeos::diagnosticsd::mojom::DiagnosticsdServiceRequest;
// DiagnosticsdDBusService::Delegate overrides:
bool StartMojoServiceFactory(base::ScopedFD mojo_pipe_fd,
std::string* error_message) override;
// Shuts down the self instance after a Mojo fatal error happens.
void ShutDownDueToMojoError(const std::string& debug_reason);
// DiagnosticsdEcEventService::Delegate overrides:
void SendGrpcEcEventToDiagnosticsProcessor(
const DiagnosticsdEcEventService::EcEvent& ec_event) override;
// DiagnosticsdGrpcService::Delegate overrides:
void PerformWebRequestToBrowser(
WebRequestHttpMethod http_method,
const std::string& url,
const std::vector<std::string>& headers,
const std::string& request_body,
const PerformWebRequestToBrowserCallback& callback) override;
// DiagnosticsdMojoService::Delegate overrides:
void SendGrpcUiMessageToDiagnosticsProcessor(
base::StringPiece json_message,
const SendGrpcUiMessageToDiagnosticsProcessorCallback& callback) override;
// chromeos::diagnosticsd::mojom::DiagnosticsdServiceFactory overrides:
void GetService(MojomDiagnosticsdServiceRequest service,
MojomDiagnosticsdClientPtr client,
const GetServiceCallback& callback) override;
// Unowned. The delegate should outlive this instance.
Delegate* const delegate_;
// gRPC-related members:
// gRPC URI on which the |grpc_server_| is listening for incoming requests.
const std::string grpc_service_uri_;
// gRPC URI which is used by
// |ui_message_receiver_diagnostics_processor_grpc_client_| for sending UI
// messages and EC notifications over the gRPC interface.
const std::string ui_message_receiver_diagnostics_processor_grpc_uri_;
// gRPC URIs which are used by |diagnostics_processor_grpc_clients_| for
// accessing the gRPC interface exposed by the diagnostics_processor daemons.
const std::vector<std::string> diagnostics_processor_grpc_uris_;
// Implementation of the gRPC interface exposed by the diagnosticsd daemon.
DiagnosticsdGrpcService grpc_service_{this /* delegate */};
// Connects |grpc_service_| with the gRPC server that listens for incoming
// requests.
AsyncGrpcServer<grpc_api::Diagnosticsd::AsyncService> grpc_server_;
// Allows to make outgoing requests to the gRPC interfaces exposed by the
// diagnostics_processor daemons.
std::vector<std::unique_ptr<AsyncGrpcClient<grpc_api::DiagnosticsProcessor>>>
diagnostics_processor_grpc_clients_;
// The pre-defined gRPC client that is allowed to respond to UI messages.
// Owned by |diagnostics_processor_grpc_clients_|.
AsyncGrpcClient<grpc_api::DiagnosticsProcessor>*
ui_message_receiver_diagnostics_processor_grpc_client_;
// D-Bus-related members:
// Implementation of the D-Bus interface exposed by the diagnosticsd daemon.
DiagnosticsdDBusService dbus_service_{this /* delegate */};
// Connects |dbus_service_| with the methods of the D-Bus object exposed by
// the diagnosticsd daemon.
std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_;
// Mojo-related members:
// Binding that connects this instance (which is an implementation of
// chromeos::diagnosticsd::mojom::DiagnosticsdServiceFactory) with the message
// pipe set up on top of the received file descriptor.
//
// Gets created after the BootstrapMojoConnection D-Bus method is called.
std::unique_ptr<mojo::Binding<DiagnosticsdServiceFactory>>
mojo_service_factory_binding_;
// Implementation of the Mojo interface exposed by the diagnosticsd daemon and
// a proxy that allows sending outgoing Mojo requests.
//
// Gets created after the GetService() Mojo method is called.
std::unique_ptr<DiagnosticsdMojoService> mojo_service_;
// Whether binding of the Mojo service was attempted.
//
// This flag is needed for detecting repeated Mojo bootstrapping attempts
// (alternative ways, like checking |mojo_service_factory_binding_|, are
// unreliable during shutdown).
bool mojo_service_bind_attempted_ = false;
// EcEvent-related members:
DiagnosticsdEcEventService ec_event_service_{this /* delegate */};
DISALLOW_COPY_AND_ASSIGN(DiagnosticsdCore);
};
} // namespace diagnostics
#endif // DIAGNOSTICS_DIAGNOSTICSD_DIAGNOSTICSD_CORE_H_