chromium/chromeos/ash/services/assistant/public/cpp/assistant_service.h

// Copyright 2020 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_ASSISTANT_PUBLIC_CPP_ASSISTANT_SERVICE_H_
#define CHROMEOS_ASH_SERVICES_ASSISTANT_PUBLIC_CPP_ASSISTANT_SERVICE_H_

#include <string>
#include <vector>

#include "base/component_export.h"
#include "base/observer_list_types.h"
#include "base/scoped_observation.h"
#include "chromeos/ash/services/assistant/public/cpp/assistant_enums.h"
#include "chromeos/ash/services/assistant/public/cpp/conversation_observer.h"
#include "chromeos/ash/services/libassistant/public/cpp/android_app_info.h"
#include "chromeos/ash/services/libassistant/public/cpp/assistant_interaction_metadata.h"
#include "chromeos/ash/services/libassistant/public/cpp/assistant_notification.h"
#include "chromeos/ash/services/libassistant/public/mojom/notification_delegate.mojom-forward.h"
#include "chromeos/ash/services/libassistant/public/mojom/notification_delegate.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "ui/accessibility/mojom/ax_assistant_structure.mojom.h"

namespace ash::assistant {

struct AssistantFeedback;

// Subscribes to Assistant's interaction event. These events are server driven
// in response to the user's direct interaction with the assistant. Responses
// from the assistant may contain untrusted third-party content. Subscriber
// implementations must be sure to handle the response data appropriately.
class COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) AssistantInteractionSubscriber
    : public base::CheckedObserver,
      public ConversationObserver {
 public:
  AssistantInteractionSubscriber() = default;
  AssistantInteractionSubscriber(const AssistantInteractionSubscriber&) =
      delete;
  AssistantInteractionSubscriber& operator=(
      const AssistantInteractionSubscriber&) = delete;
  ~AssistantInteractionSubscriber() override = default;

  // Assistant speech recognition has started.
  virtual void OnSpeechRecognitionStarted() {}

  // Assistant speech recognition intermediate result is available.
  virtual void OnSpeechRecognitionIntermediateResult(
      const std::string& high_confidence_text,
      const std::string& low_confidence_text) {}

  // Assistant speech recognition detected end of utterance.
  virtual void OnSpeechRecognitionEndOfUtterance() {}

  // Assistant speech recognition final result is available.
  virtual void OnSpeechRecognitionFinalResult(const std::string& final_result) {
  }

  // Assistant got an instantaneous speech level update in dB.
  virtual void OnSpeechLevelUpdated(float speech_level) {}
};

class COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) Assistant {
 public:
  Assistant() = default;
  Assistant(const Assistant&) = delete;
  Assistant& operator=(const Assistant&) = delete;
  virtual ~Assistant() = default;

  // Starts an interaction to edit the reminder uniquely identified by
  // |client_id|. In response to the request, LibAssistant will initiate
  // a user facing interaction with the context pre-populated with details
  // to edit the specified reminder.
  virtual void StartEditReminderInteraction(const std::string& client_id) = 0;

  // Starts a new Assistant text interaction. If |allow_tts| is true, the
  // result will contain TTS. Otherwise TTS will not be present in the
  // generated server response. Results will be returned through registered
  // |AssistantInteractionSubscriber|.
  virtual void StartTextInteraction(const std::string& query,
                                    AssistantQuerySource source,
                                    bool allow_tts) = 0;

  // Starts a new Assistant voice interaction.
  virtual void StartVoiceInteraction() = 0;

  // Stops the active Assistant interaction and cancel the conversation if
  // |cancel_conversation|. If there is no active interaction, this method
  // is a no-op.
  virtual void StopActiveInteraction(bool cancel_conversation) = 0;

  // Registers assistant interaction event subscriber. Subscribers'
  // implementation is responsible for selecting events of interest.
  virtual void AddAssistantInteractionSubscriber(
      AssistantInteractionSubscriber* subscriber) = 0;
  virtual void RemoveAssistantInteractionSubscriber(
      AssistantInteractionSubscriber* subscriber) = 0;
  virtual void AddRemoteConversationObserver(
      ConversationObserver* observer) = 0;

  virtual mojo::PendingReceiver<libassistant::mojom::NotificationDelegate>
  GetPendingNotificationDelegate() = 0;

  // Retrieves a notification. A voiceless interaction will be sent to server to
  // retrieve the notification of |action_index|, which can trigger other
  // Assistant events such as OnTextResponse to show the result in the UI. The
  // retrieved notification will be removed from the UI.
  // |action_index| is the index of the tapped action. The main UI in the
  // notification contains the top level action, which index is 0. The buttons
  // have the additional actions, which are indexed starting from 1.
  virtual void RetrieveNotification(const AssistantNotification& notification,
                                    int action_index) = 0;

  // Dismisses a notification.
  virtual void DismissNotification(
      const AssistantNotification& notification) = 0;

  // Invoked when accessibility status is changed. Note that though
  // accessibility status has changed, |spoken_feedback_enabled| may not have.
  virtual void OnAccessibilityStatusChanged(bool spoken_feedback_enabled) = 0;

  // Invoked when color mode (dark/light mode) status changed.
  virtual void OnColorModeChanged(bool dark_mode_enabled) = 0;

  // Send Assistant feedback to Assistant server.
  virtual void SendAssistantFeedback(const AssistantFeedback& feedback) = 0;

  // Alarm/Timer methods -------------------------------------------------------

  // Adds the specified |duration| to the timer identified by |id|.  Note that
  // this method is a no-op if there is no existing timer identified by |id|.
  virtual void AddTimeToTimer(const std::string& id,
                              base::TimeDelta duration) = 0;

  // Pauses the timer specified by |id|. Note that this method is a no-op if
  // there is no existing timer identified by |id| or if a timer does exist but
  // is already paused.
  virtual void PauseTimer(const std::string& id) = 0;

  // Remove the alarm/timer specified by |id|.
  // NOTE: this is a no-op if no such alarm/timer exists.
  virtual void RemoveAlarmOrTimer(const std::string& id) = 0;

  // Resumes the timer specified by |id|. Note that this method is a no-op if
  // there is no existing timer identified by |id| or if a timer does exist but
  // isn't currently paused.
  virtual void ResumeTimer(const std::string& id) = 0;
};

using ScopedAssistantInteractionSubscriber =
    base::ScopedObservation<Assistant, AssistantInteractionSubscriber>;

// Main interface between browser and |ash::assistant::Service|.
class COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) AssistantService {
 public:
  AssistantService();
  AssistantService(const AssistantService&) = delete;
  AssistantService& operator=(const AssistantService&) = delete;
  virtual ~AssistantService();

  static AssistantService* Get();

  // Initiates assistant service.
  virtual void Init() = 0;

  // Signals system shutdown, the service could start cleaning up if needed.
  virtual void Shutdown() = 0;

  // Get the main Assistant interface.
  virtual Assistant* GetAssistant() = 0;
};

}  // namespace ash::assistant

// TODO(b/258750971): remove when internal assistant codes are migrated to
// namespace ash.
namespace chromeos::assistant {
using ::ash::assistant::Assistant;
using ::ash::assistant::AssistantInteractionSubscriber;
using ::ash::assistant::AssistantService;
}  // namespace chromeos::assistant

namespace base {

template <>
struct ScopedObservationTraits<ash::assistant::Assistant,
                               ash::assistant::AssistantInteractionSubscriber> {
  static void AddObserver(
      ash::assistant::Assistant* source,
      ash::assistant::AssistantInteractionSubscriber* observer) {
    source->AddAssistantInteractionSubscriber(observer);
  }
  static void RemoveObserver(
      ash::assistant::Assistant* source,
      ash::assistant::AssistantInteractionSubscriber* observer) {
    source->RemoveAssistantInteractionSubscriber(observer);
  }
};

}  // namespace base

#endif  // CHROMEOS_ASH_SERVICES_ASSISTANT_PUBLIC_CPP_ASSISTANT_SERVICE_H_