// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_
#define CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_
#include <memory>
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation_traits.h"
#include "chromeos/ash/services/libassistant/grpc/external_services/grpc_services_observer.h"
#include "chromeos/ash/services/libassistant/grpc/services_status_observer.h"
#include "chromeos/ash/services/libassistant/public/cpp/assistant_timer.h"
#include "chromeos/assistant/internal/proto/shared/proto/v2/device_state_event.pb.h"
namespace assistant {
namespace api {
class CancelSpeakerIdEnrollmentRequest;
class GetSpeakerIdEnrollmentInfoRequest;
class GetSpeakerIdEnrollmentInfoResponse;
class GetAssistantSettingsResponse;
class Interaction;
class OnAlarmTimerEventRequest;
class OnAssistantDisplayEventRequest;
class OnConversationStateEventRequest;
class OnDeviceStateEventRequest;
class OnDisplayRequestRequest;
class OnMediaActionFallbackEventRequest;
class OnSpeakerIdEnrollmentEventRequest;
class StartSpeakerIdEnrollmentRequest;
class UpdateAssistantSettingsResponse;
class VoicelessOptions;
namespace events {
class SpeakerIdEnrollmentEvent;
} // namespace events
} // namespace api
} // namespace assistant
namespace assistant {
namespace ui {
class SettingsUiSelector;
class SettingsUiUpdate;
} // namespace ui
} // namespace assistant
namespace assistant_client {
class ActionModule;
class AssistantManager;
class HttpConnectionFactory;
} // namespace assistant_client
namespace ash::libassistant {
// The Libassistant customer class which establishes a gRPC connection to
// Libassistant and provides an interface for interacting with gRPC Libassistant
// client. It helps to build request/response proto messages internally for each
// specific method below and call the appropriate gRPC (IPC) client method.
class AssistantClient {
public:
// Speaker Id Enrollment:
using CancelSpeakerIdEnrollmentRequest =
::assistant::api::CancelSpeakerIdEnrollmentRequest;
using GetSpeakerIdEnrollmentInfoRequest =
::assistant::api::GetSpeakerIdEnrollmentInfoRequest;
using GetSpeakerIdEnrollmentInfoResponse =
::assistant::api::GetSpeakerIdEnrollmentInfoResponse;
using StartSpeakerIdEnrollmentRequest =
::assistant::api::StartSpeakerIdEnrollmentRequest;
using SpeakerIdEnrollmentEvent =
::assistant::api::events::SpeakerIdEnrollmentEvent;
using OnSpeakerIdEnrollmentEventRequest =
::assistant::api::OnSpeakerIdEnrollmentEventRequest;
// Display:
using OnAssistantDisplayEventRequest =
::assistant::api::OnAssistantDisplayEventRequest;
using OnDisplayRequestRequest = ::assistant::api::OnDisplayRequestRequest;
// Media:
using MediaStatus = ::assistant::api::events::DeviceState::MediaStatus;
using OnDeviceStateEventRequest = ::assistant::api::OnDeviceStateEventRequest;
using OnMediaActionFallbackEventRequest =
::assistant::api::OnMediaActionFallbackEventRequest;
// Conversation:
using OnConversationStateEventRequest =
::assistant::api::OnConversationStateEventRequest;
// Each authentication token exists of a [gaia_id, access_token] tuple.
using AuthTokens = std::vector<std::pair<std::string, std::string>>;
AssistantClient(
std::unique_ptr<assistant_client::AssistantManager> assistant_manager);
AssistantClient(const AssistantClient&) = delete;
AssistantClient& operator=(const AssistantClient&) = delete;
virtual ~AssistantClient();
// Starts Libassistant services. |services_status_observer| will get notified
// on new status change.
virtual void StartServices(
ServicesStatusObserver* services_status_observer) = 0;
virtual void StartGrpcHttpConnectionClient(
assistant_client::HttpConnectionFactory*) = 0;
// 1. Start a gRPC server which hosts the services that Libassistant depends
// on (maybe called by Libassistant) or receive events from Libassistant.
// 2. Register this client as a customer of Libassistant by sending
// RegisterCustomerRequest to Libassistant periodically. All supported
// services should be registered first before calling this method.
virtual bool StartGrpcServices() = 0;
virtual void AddExperimentIds(const std::vector<std::string>& exp_ids) = 0;
// Speaker Id Enrollment methods.
virtual void AddSpeakerIdEnrollmentEventObserver(
GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) = 0;
virtual void RemoveSpeakerIdEnrollmentEventObserver(
GrpcServicesObserver<OnSpeakerIdEnrollmentEventRequest>* observer) = 0;
virtual void StartSpeakerIdEnrollment(
const StartSpeakerIdEnrollmentRequest& request) = 0;
virtual void CancelSpeakerIdEnrollment(
const CancelSpeakerIdEnrollmentRequest& request) = 0;
virtual void GetSpeakerIdEnrollmentInfo(
const GetSpeakerIdEnrollmentInfoRequest& request,
base::OnceCallback<void(bool user_model_exists)> on_done) = 0;
virtual void ResetAllDataAndShutdown() = 0;
// Display methods.
virtual void SendDisplayRequest(const OnDisplayRequestRequest& request) = 0;
virtual void AddDisplayEventObserver(
GrpcServicesObserver<OnAssistantDisplayEventRequest>* observer) = 0;
// Media methods.
virtual void ResumeCurrentStream() = 0;
virtual void PauseCurrentStream() = 0;
// Sets the current media status of media playing outside of libassistant.
// Setting external state will stop any internally playing media.
virtual void SetExternalPlaybackState(const MediaStatus& status_proto) = 0;
virtual void AddDeviceStateEventObserver(
GrpcServicesObserver<OnDeviceStateEventRequest>* observer) = 0;
virtual void AddMediaActionFallbackEventObserver(
GrpcServicesObserver<OnMediaActionFallbackEventRequest>* observer) = 0;
// Conversation methods.
virtual void SendVoicelessInteraction(
const ::assistant::api::Interaction& interaction,
const std::string& description,
const ::assistant::api::VoicelessOptions& options,
base::OnceCallback<void(bool)> on_done) = 0;
virtual void RegisterActionModule(
assistant_client::ActionModule* action_module) = 0;
virtual void StartVoiceInteraction() = 0;
virtual void StopAssistantInteraction(bool cancel_conversation) = 0;
virtual void AddConversationStateEventObserver(
GrpcServicesObserver<OnConversationStateEventRequest>* observer) = 0;
// Settings-related functionality during bootup:
virtual void SetAuthenticationInfo(const AuthTokens& tokens) = 0;
virtual void SetInternalOptions(const std::string& locale,
bool spoken_feedback_enabled) = 0;
// Settings-related functionality after fully started:
virtual void UpdateAssistantSettings(
const ::assistant::ui::SettingsUiUpdate& settings,
const std::string& user_id,
base::OnceCallback<
void(const ::assistant::api::UpdateAssistantSettingsResponse&)>
on_done) = 0;
virtual void GetAssistantSettings(
const ::assistant::ui::SettingsUiSelector& selector,
const std::string& user_id,
base::OnceCallback<void(
const ::assistant::api::GetAssistantSettingsResponse&)> on_done) = 0;
virtual void SetLocaleOverride(const std::string& locale) = 0;
virtual std::string GetDeviceId() = 0;
// Audio-related functionality:
// Enables or disables audio input pipeline.
virtual void EnableListening(bool listening_enabled) = 0;
// Alarm/timer-related functionality:
// Adds extra time to the timer.
virtual void AddTimeToTimer(const std::string& id,
const base::TimeDelta& duration) = 0;
// Pauses the specified timer. This will be a no-op if the |timer_id| is
// invalid.
virtual void PauseTimer(const std::string& timer_id) = 0;
// Removes and cancels the timer.
virtual void RemoveTimer(const std::string& timer_id) = 0;
// Resumes the specified timer (expected to be in paused state).
virtual void ResumeTimer(const std::string& timer_id) = 0;
// Returns the list of all currently scheduled, ringing or paused timers in
// the callback.
virtual void GetTimers(
base::OnceCallback<void(const std::vector<assistant::AssistantTimer>&)>
on_done) = 0;
// Registers |observer| to get notified on any alarm/timer status change.
virtual void AddAlarmTimerEventObserver(
GrpcServicesObserver<::assistant::api::OnAlarmTimerEventRequest>*
observer) = 0;
// Will not return nullptr.
assistant_client::AssistantManager* assistant_manager() {
return assistant_manager_.get();
}
// Creates an instance of AssistantClient.
static std::unique_ptr<AssistantClient> Create(
std::unique_ptr<assistant_client::AssistantManager> assistant_manager);
protected:
void ResetAssistantManager();
private:
std::unique_ptr<assistant_client::AssistantManager> assistant_manager_;
};
} // namespace ash::libassistant
namespace base {
template <>
struct ScopedObservationTraits<
ash::libassistant::AssistantClient,
ash::libassistant::GrpcServicesObserver<
::assistant::api::OnSpeakerIdEnrollmentEventRequest>> {
static void AddObserver(
ash::libassistant::AssistantClient* source,
ash::libassistant::GrpcServicesObserver<
::assistant::api::OnSpeakerIdEnrollmentEventRequest>* observer) {
source->AddSpeakerIdEnrollmentEventObserver(observer);
}
static void RemoveObserver(
ash::libassistant::AssistantClient* source,
ash::libassistant::GrpcServicesObserver<
::assistant::api::OnSpeakerIdEnrollmentEventRequest>* observer) {
source->RemoveSpeakerIdEnrollmentEventObserver(observer);
}
};
} // namespace base
#endif // CHROMEOS_ASH_SERVICES_LIBASSISTANT_GRPC_ASSISTANT_CLIENT_H_