1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_
6 #define ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/macros.h"
13 #include "base/observer_list.h"
14 #include "base/optional.h"
15 #include "base/timer/timer.h"
16 #include "chromeos/services/assistant/public/cpp/assistant_service.h"
17 
18 namespace ash {
19 
20 class CurrentInteractionSubscriber;
21 class LibassistantContractChecker;
22 
23 // A response issued when an Assistant interaction is started.
24 // Used both for text and voice interactions.  To build a response, simply
25 // chain calls to the provided |AddXYZ| methods.
26 //
27 // Example usage:
28 //     auto response = std::make_unique<InteractionResponse>();
29 //     response->AddTextResponse("The response text")
30 //             ->AddResolution(InteractionResponse::Resolution::kNormal);
31 //     assistant_service()->SetInteractionResponse(std::move(response));
32 class InteractionResponse {
33  public:
34   using Resolution = chromeos::assistant::AssistantInteractionResolution;
35   class Response;
36 
37   InteractionResponse();
38   ~InteractionResponse();
39 
40   // A simple textual response.
41   InteractionResponse* AddTextResponse(const std::string& text);
42   // A suggestion chip response.
43   InteractionResponse* AddSuggestionChip(const std::string& text);
44   // If used this will cause us to finish the interaction by passing the given
45   // |resolution| to |AssistantInteractionSubscriber::OnInteractionFinished|.
46   InteractionResponse* AddResolution(Resolution resolution);
47 
48   void SendTo(chromeos::assistant::AssistantInteractionSubscriber* receiver);
49 
50  private:
51   void AddResponse(std::unique_ptr<Response> responses);
52 
53   std::vector<std::unique_ptr<Response>> responses_;
54 
55   DISALLOW_COPY_AND_ASSIGN(InteractionResponse);
56 };
57 
58 // Fake implementation of the Assistant service.
59 // It behaves as if the Assistant service is up-and-running,
60 // and will inform the |AssistantInteractionSubscriber| instances when
61 // interactions start/stop.
62 // Note it is up to the test developer to assure the interactions are valid.
63 // The contract with LibAssistant specifies there is only one
64 // "conversation turn" (what we call "interaction") at any given time, so you
65 // must:
66 //    - Finish a conversation before starting a new one.
67 //    - Not send any responses (text, card, ...) before starting or after
68 //      finishing an interaction.
69 class TestAssistantService : public chromeos::assistant::Assistant {
70  public:
71   TestAssistantService();
72   ~TestAssistantService() override;
73 
74   // Set the response that will be invoked when the next interaction starts.
75   void SetInteractionResponse(std::unique_ptr<InteractionResponse> response);
76 
77   // Returns the current interaction.
78   base::Optional<chromeos::assistant::AssistantInteractionMetadata>
79   current_interaction();
80 
81   // Assistant overrides:
82   void StartEditReminderInteraction(const std::string& client_id) override;
83   void StartScreenContextInteraction(
84       ax::mojom::AssistantStructurePtr assistant_structure,
85       const std::vector<uint8_t>& assistant_screenshot) override;
86   void StartTextInteraction(const std::string& query,
87                             chromeos::assistant::AssistantQuerySource source,
88                             bool allow_tts) override;
89   void StartVoiceInteraction() override;
90   void StopActiveInteraction(bool cancel_conversation) override;
91   void AddAssistantInteractionSubscriber(
92       chromeos::assistant::AssistantInteractionSubscriber* subscriber) override;
93   void RemoveAssistantInteractionSubscriber(
94       chromeos::assistant::AssistantInteractionSubscriber* subscriber) override;
95   void RetrieveNotification(
96       const chromeos::assistant::AssistantNotification& notification,
97       int action_index) override;
98   void DismissNotification(
99       const chromeos::assistant::AssistantNotification& notification) override;
100   void OnAccessibilityStatusChanged(bool spoken_feedback_enabled) override;
101   void SendAssistantFeedback(
102       const chromeos::assistant::AssistantFeedback& feedback) override;
103   void NotifyEntryIntoAssistantUi(
104       chromeos::assistant::AssistantEntryPoint entry_point) override;
105   void AddTimeToTimer(const std::string& id, base::TimeDelta duration) override;
106   void PauseTimer(const std::string& id) override;
107   void RemoveAlarmOrTimer(const std::string& id) override;
108   void ResumeTimer(const std::string& id) override;
109 
110  private:
111   void StartInteraction(
112       chromeos::assistant::AssistantInteractionType type,
113       chromeos::assistant::AssistantQuerySource source =
114           chromeos::assistant::AssistantQuerySource::kUnspecified,
115       const std::string& query = std::string());
116   void SendInteractionResponse();
117 
118   std::unique_ptr<LibassistantContractChecker> libassistant_contract_checker_;
119   std::unique_ptr<CurrentInteractionSubscriber> current_interaction_subscriber_;
120   std::unique_ptr<InteractionResponse> interaction_response_;
121 
122   base::ObserverList<chromeos::assistant::AssistantInteractionSubscriber>
123       interaction_subscribers_;
124   bool running_active_interaction_ = false;
125 
126   DISALLOW_COPY_AND_ASSIGN(TestAssistantService);
127 };
128 
129 }  // namespace ash
130 
131 #endif  // ASH_ASSISTANT_TEST_TEST_ASSISTANT_SERVICE_H_
132