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 CHROMEOS_SERVICES_ASSISTANT_SERVICE_H_
6 #define CHROMEOS_SERVICES_ASSISTANT_SERVICE_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "ash/public/cpp/ambient/ambient_ui_model.h"
12 #include "ash/public/cpp/assistant/assistant_state.h"
13 #include "ash/public/cpp/session/session_activation_observer.h"
14 #include "base/callback.h"
15 #include "base/cancelable_callback.h"
16 #include "base/component_export.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/optional.h"
19 #include "base/scoped_observer.h"
20 #include "base/sequence_checker.h"
21 #include "base/single_thread_task_runner.h"
22 #include "base/time/time.h"
23 #include "chromeos/dbus/power/power_manager_client.h"
24 #include "chromeos/services/assistant/assistant_manager_service.h"
25 #include "chromeos/services/assistant/public/cpp/assistant_service.h"
26 #include "components/signin/public/identity_manager/account_info.h"
27 #include "mojo/public/cpp/bindings/remote.h"
28 
29 class GoogleServiceAuthError;
30 
31 namespace base {
32 class OneShotTimer;
33 }  // namespace base
34 
35 namespace network {
36 class PendingSharedURLLoaderFactory;
37 }  // namespace network
38 
39 namespace power_manager {
40 class PowerSupplyProperties;
41 }  // namespace power_manager
42 
43 namespace signin {
44 class AccessTokenFetcher;
45 struct AccessTokenInfo;
46 class IdentityManager;
47 }  // namespace signin
48 
49 namespace chromeos {
50 namespace assistant {
51 
52 class AssistantInteractionLogger;
53 class ScopedAshSessionObserver;
54 class ServiceContext;
55 
56 // |AssistantManagerService|'s state won't update if it's currently in the
57 // process of starting up. This is the delay before we will try to update
58 // |AssistantManagerService| again.
59 constexpr auto kUpdateAssistantManagerDelay = base::TimeDelta::FromSeconds(1);
60 
COMPONENT_EXPORT(ASSISTANT_SERVICE)61 class COMPONENT_EXPORT(ASSISTANT_SERVICE) Service
62     : public AssistantService,
63       public chromeos::PowerManagerClient::Observer,
64       public ash::SessionActivationObserver,
65       public ash::AssistantStateObserver,
66       public AssistantManagerService::CommunicationErrorObserver,
67       public AssistantManagerService::StateObserver,
68       public ash::AmbientUiModelObserver {
69  public:
70   Service(std::unique_ptr<network::PendingSharedURLLoaderFactory>
71               pending_url_loader_factory,
72           signin::IdentityManager* identity_manager);
73   ~Service() override;
74 
75   // Allows tests to override the S3 server URI used by the service.
76   // The caller must ensure the memory passed in remains valid.
77   // This override can be removed by passing in a nullptr.
78   // Note: This would look nicer if it was a class method and not static,
79   // but unfortunately this must be called before |Service| tries to create the
80   // |AssistantManagerService|, which happens really soon after the service
81   // itself is created, so we do not have time in our tests to grab a handle
82   // to |Service| and set this before it is too late.
83   static void OverrideS3ServerUriForTesting(const char* uri);
84   static void OverrideDeviceIdForTesting(const char* device_id);
85 
86   void SetAssistantManagerServiceForTesting(
87       std::unique_ptr<AssistantManagerService> assistant_manager_service);
88 
89   // AssistantService overrides:
90   void Init() override;
91   void Shutdown() override;
92   Assistant* GetAssistant() override;
93 
94  private:
95   friend class AssistantServiceTest;
96 
97   class Context;
98 
99   // chromeos::PowerManagerClient::Observer overrides:
100   void PowerChanged(const power_manager::PowerSupplyProperties& prop) override;
101   void SuspendDone(const base::TimeDelta& sleep_duration) override;
102 
103   // ash::SessionActivationObserver overrides:
104   void OnSessionActivated(bool activated) override;
105   void OnLockStateChanged(bool locked) override;
106 
107   // ash::AssistantStateObserver overrides:
108   void OnAssistantConsentStatusChanged(int consent_status) override;
109   void OnAssistantContextEnabled(bool enabled) override;
110   void OnAssistantHotwordAlwaysOn(bool hotword_always_on) override;
111   void OnAssistantSettingsEnabled(bool enabled) override;
112   void OnAssistantHotwordEnabled(bool enabled) override;
113   void OnLocaleChanged(const std::string& locale) override;
114   void OnArcPlayStoreEnabledChanged(bool enabled) override;
115   void OnLockedFullScreenStateChanged(bool enabled) override;
116 
117   // AssistantManagerService::CommunicationErrorObserver overrides:
118   void OnCommunicationError(
119       AssistantManagerService::CommunicationErrorType error_type) override;
120 
121   // AssistantManagerService::StateObserver overrides:
122   void OnStateChanged(AssistantManagerService::State new_state) override;
123 
124   // ash::AmbientUiModelObserver overrides:
125   void OnAmbientUiVisibilityChanged(
126       ash::AmbientUiVisibility visibility) override;
127 
128   void UpdateAssistantManagerState();
129 
130   CoreAccountInfo RetrievePrimaryAccountInfo() const;
131   void RequestAccessToken();
132   void GetAccessTokenCallback(GoogleServiceAuthError error,
133                               signin::AccessTokenInfo access_token_info);
134   void RetryRefreshToken();
135 
136   void CreateAssistantManagerService();
137   std::unique_ptr<AssistantManagerService>
138   CreateAndReturnAssistantManagerService();
139 
140   void FinalizeAssistantManagerService();
141 
142   void StopAssistantManagerService();
143 
144   void AddAshSessionObserver();
145 
146   void UpdateListeningState();
147 
148   base::Optional<AssistantManagerService::UserInfo> GetUserInfo() const;
149 
150   ServiceContext* context() { return context_.get(); }
151 
152   // Returns the "actual" hotword status. In addition to the hotword pref, this
153   // method also take power status into account if dsp support is not available
154   // for the device.
155   bool ShouldEnableHotword();
156 
157   signin::IdentityManager* const identity_manager_;
158   std::unique_ptr<ScopedAshSessionObserver> scoped_ash_session_observer_;
159   ScopedObserver<ash::AmbientUiModel, ash::AmbientUiModelObserver>
160       ambient_ui_model_observer_{this};
161   std::unique_ptr<AssistantManagerService> assistant_manager_service_;
162   std::unique_ptr<base::OneShotTimer> token_refresh_timer_;
163   int token_refresh_error_backoff_factor = 1;
164   scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
165   ScopedObserver<chromeos::PowerManagerClient,
166                  chromeos::PowerManagerClient::Observer>
167       power_manager_observer_{this};
168 
169   // Flag to guard the one-time mojom initialization.
170   bool is_assistant_manager_service_finalized_ = false;
171   // Whether the current user session is active.
172   bool session_active_ = false;
173   // Whether the lock screen is on.
174   bool locked_ = false;
175   // Whether the power source is connected.
176   bool power_source_connected_ = false;
177 
178   // The value passed into |SetAssistantManagerServiceForTesting|.
179   // Will be moved into |assistant_manager_service_| when the service is
180   // supposed to be created.
181   std::unique_ptr<AssistantManagerService>
182       assistant_manager_service_for_testing_ = nullptr;
183 
184   base::Optional<std::string> access_token_;
185 
186   // |ServiceContext| object passed to child classes so they can access some of
187   // our functionality without depending on us.
188   std::unique_ptr<ServiceContext> context_;
189 
190   // non-null until |assistant_manager_service_| is created.
191   std::unique_ptr<network::PendingSharedURLLoaderFactory>
192       pending_url_loader_factory_;
193 
194   base::CancelableOnceClosure update_assistant_manager_callback_;
195 
196   std::unique_ptr<signin::AccessTokenFetcher> access_token_fetcher_;
197 
198   std::unique_ptr<AssistantInteractionLogger> interaction_logger_;
199 
200   SEQUENCE_CHECKER(sequence_checker_);
201 
202   base::WeakPtrFactory<Service> weak_ptr_factory_{this};
203 
204   DISALLOW_COPY_AND_ASSIGN(Service);
205 };
206 
207 }  // namespace assistant
208 }  // namespace chromeos
209 
210 #endif  // CHROMEOS_SERVICES_ASSISTANT_SERVICE_H_
211