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