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 #include "chromeos/services/assistant/service.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <utility>
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/assistant/controller/assistant_alarm_timer_controller.h"
14 #include "ash/public/cpp/assistant/controller/assistant_controller.h"
15 #include "ash/public/cpp/assistant/controller/assistant_notification_controller.h"
16 #include "ash/public/cpp/session/session_controller.h"
17 #include "base/bind.h"
18 #include "base/command_line.h"
19 #include "base/logging.h"
20 #include "base/optional.h"
21 #include "base/rand_util.h"
22 #include "base/single_thread_task_runner.h"
23 #include "base/time/time.h"
24 #include "base/timer/timer.h"
25 #include "build/buildflag.h"
26 #include "chromeos/assistant/buildflags.h"
27 #include "chromeos/audio/cras_audio_handler.h"
28 #include "chromeos/constants/chromeos_features.h"
29 #include "chromeos/constants/chromeos_switches.h"
30 #include "chromeos/dbus/dbus_thread_manager.h"
31 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
32 #include "chromeos/services/assistant/assistant_interaction_logger.h"
33 #include "chromeos/services/assistant/assistant_manager_service.h"
34 #include "chromeos/services/assistant/assistant_manager_service_delegate_impl.h"
35 #include "chromeos/services/assistant/fake_assistant_manager_service_impl.h"
36 #include "chromeos/services/assistant/fake_assistant_settings_impl.h"
37 #include "chromeos/services/assistant/public/cpp/assistant_client.h"
38 #include "chromeos/services/assistant/public/cpp/assistant_prefs.h"
39 #include "chromeos/services/assistant/public/cpp/device_actions.h"
40 #include "chromeos/services/assistant/public/cpp/features.h"
41 #include "chromeos/services/assistant/service_context.h"
42 #include "components/signin/public/identity_manager/access_token_fetcher.h"
43 #include "components/signin/public/identity_manager/access_token_info.h"
44 #include "components/signin/public/identity_manager/consent_level.h"
45 #include "components/signin/public/identity_manager/identity_manager.h"
46 #include "components/signin/public/identity_manager/scope_set.h"
47 #include "components/user_manager/known_user.h"
48 #include "google_apis/gaia/google_service_auth_error.h"
49 #include "services/network/public/cpp/shared_url_loader_factory.h"
50 
51 #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
52 #include "chromeos/assistant/internal/internal_constants.h"
53 #include "chromeos/services/assistant/assistant_manager_service_impl.h"
54 #include "chromeos/services/assistant/assistant_settings_impl.h"
55 #include "chromeos/services/assistant/utils.h"
56 #include "services/device/public/mojom/battery_monitor.mojom.h"
57 #endif
58 
59 namespace chromeos {
60 namespace assistant {
61 
62 namespace {
63 
64 using chromeos::assistant::features::IsAmbientAssistantEnabled;
65 using CommunicationErrorType = AssistantManagerService::CommunicationErrorType;
66 
67 constexpr char kScopeAuthGcm[] = "https://www.googleapis.com/auth/gcm";
68 constexpr char kScopeAssistant[] =
69     "https://www.googleapis.com/auth/assistant-sdk-prototype";
70 constexpr char kScopeGeller[] = "https://www.googleapis.com/auth/webhistory";
71 
72 constexpr base::TimeDelta kMinTokenRefreshDelay =
73     base::TimeDelta::FromMilliseconds(1000);
74 constexpr base::TimeDelta kMaxTokenRefreshDelay =
75     base::TimeDelta::FromMilliseconds(60 * 1000);
76 
77 // Testing override for the URI used to contact the s3 server.
78 const char* g_s3_server_uri_override = nullptr;
79 // Testing override for the device-id used by Libassistant to identify this
80 // device.
81 const char* g_device_id_override = nullptr;
82 
ToAssistantStatus(AssistantManagerService::State state)83 AssistantStatus ToAssistantStatus(AssistantManagerService::State state) {
84   using State = AssistantManagerService::State;
85 
86   switch (state) {
87     case State::STOPPED:
88     case State::STARTING:
89     case State::STARTED:
90       return AssistantStatus::NOT_READY;
91     case State::RUNNING:
92       return AssistantStatus::READY;
93   }
94 }
95 
96 #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
GetS3ServerUriOverride()97 base::Optional<std::string> GetS3ServerUriOverride() {
98   if (g_s3_server_uri_override)
99     return g_s3_server_uri_override;
100   return base::nullopt;
101 }
102 
GetDeviceIdOverride()103 base::Optional<std::string> GetDeviceIdOverride() {
104   if (g_device_id_override)
105     return g_device_id_override;
106   return base::nullopt;
107 }
108 #endif
109 
110 // Returns true if the system is currently in Ambient Mode (with ambient screen
111 // shown or hidden, but not closed).
InAmbientMode()112 bool InAmbientMode() {
113   DCHECK(chromeos::features::IsAmbientModeEnabled());
114   return ash::AmbientUiModel::Get()->ui_visibility() !=
115          ash::AmbientUiVisibility::kClosed;
116 }
117 
118 // In the signed-out mode, we are going to run Assistant service without
119 // using user's signed in account information.
IsSignedOutMode()120 bool IsSignedOutMode() {
121   // We will switch the Libassitsant mode to signed-out/signed-in when user
122   // enters/exits the ambient mode.
123   const bool entered_ambient_mode =
124       IsAmbientAssistantEnabled() && InAmbientMode();
125 
126   // Note that we shouldn't toggle the flag to true when exiting ambient
127   // mode if we have been using fake gaia login, e.g. in the Tast test.
128   return entered_ambient_mode ||
129          base::CommandLine::ForCurrentProcess()->HasSwitch(
130              chromeos::switches::kDisableGaiaServices);
131 }
132 
133 }  // namespace
134 
135 // Scoped observer that will subscribe |Service| as an Ash session observer,
136 // and will unsubscribe in its destructor.
137 class ScopedAshSessionObserver {
138  public:
ScopedAshSessionObserver(ash::SessionActivationObserver * observer,const AccountId & account_id)139   ScopedAshSessionObserver(ash::SessionActivationObserver* observer,
140                            const AccountId& account_id)
141       : observer_(observer), account_id_(account_id) {
142     DCHECK(account_id_.is_valid());
143     DCHECK(controller());
144     controller()->AddSessionActivationObserverForAccountId(account_id_,
145                                                            observer_);
146   }
147 
~ScopedAshSessionObserver()148   ~ScopedAshSessionObserver() {
149     if (controller())
150       controller()->RemoveSessionActivationObserverForAccountId(account_id_,
151                                                                 observer_);
152   }
153 
154  private:
controller() const155   ash::SessionController* controller() const {
156     return ash::SessionController::Get();
157   }
158 
159   ash::SessionActivationObserver* const observer_;
160   const AccountId account_id_;
161 };
162 
163 class Service::Context : public ServiceContext {
164  public:
Context(Service * parent)165   explicit Context(Service* parent) : parent_(parent) {}
166   ~Context() override = default;
167 
168   // ServiceContext:
assistant_alarm_timer_controller()169   ash::AssistantAlarmTimerController* assistant_alarm_timer_controller()
170       override {
171     return ash::AssistantAlarmTimerController::Get();
172   }
173 
assistant_controller()174   ash::AssistantController* assistant_controller() override {
175     return ash::AssistantController::Get();
176   }
177 
assistant_notification_controller()178   ash::AssistantNotificationController* assistant_notification_controller()
179       override {
180     return ash::AssistantNotificationController::Get();
181   }
182 
assistant_screen_context_controller()183   ash::AssistantScreenContextController* assistant_screen_context_controller()
184       override {
185     return ash::AssistantScreenContextController::Get();
186   }
187 
assistant_state()188   ash::AssistantStateBase* assistant_state() override {
189     return ash::AssistantState::Get();
190   }
191 
cras_audio_handler()192   CrasAudioHandler* cras_audio_handler() override {
193     return CrasAudioHandler::Get();
194   }
195 
device_actions()196   DeviceActions* device_actions() override { return DeviceActions::Get(); }
197 
main_task_runner()198   scoped_refptr<base::SequencedTaskRunner> main_task_runner() override {
199     return parent_->main_task_runner_;
200   }
201 
power_manager_client()202   PowerManagerClient* power_manager_client() override {
203     return PowerManagerClient::Get();
204   }
205 
primary_account_gaia_id()206   std::string primary_account_gaia_id() override {
207     return parent_->RetrievePrimaryAccountInfo().gaia;
208   }
209 
210  private:
211   Service* const parent_;  // |this| is owned by |parent_|.
212 
213   DISALLOW_COPY_AND_ASSIGN(Context);
214 };
215 
Service(std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_url_loader_factory,signin::IdentityManager * identity_manager)216 Service::Service(std::unique_ptr<network::PendingSharedURLLoaderFactory>
217                      pending_url_loader_factory,
218                  signin::IdentityManager* identity_manager)
219     : identity_manager_(identity_manager),
220       token_refresh_timer_(std::make_unique<base::OneShotTimer>()),
221       main_task_runner_(base::SequencedTaskRunnerHandle::Get()),
222       context_(std::make_unique<Context>(this)),
223       pending_url_loader_factory_(std::move(pending_url_loader_factory)) {
224   DCHECK(identity_manager_);
225   chromeos::PowerManagerClient* power_manager_client =
226       context_->power_manager_client();
227   power_manager_observer_.Add(power_manager_client);
228   power_manager_client->RequestStatusUpdate();
229 }
230 
~Service()231 Service::~Service() {
232   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
233   ash::AssistantState::Get()->RemoveObserver(this);
234   ash::AssistantController::Get()->SetAssistant(nullptr);
235 }
236 
237 // static
OverrideS3ServerUriForTesting(const char * uri)238 void Service::OverrideS3ServerUriForTesting(const char* uri) {
239   g_s3_server_uri_override = uri;
240 }
241 
242 // static
OverrideDeviceIdForTesting(const char * device_id)243 void Service::OverrideDeviceIdForTesting(const char* device_id) {
244   g_device_id_override = device_id;
245 }
246 
SetAssistantManagerServiceForTesting(std::unique_ptr<AssistantManagerService> assistant_manager_service)247 void Service::SetAssistantManagerServiceForTesting(
248     std::unique_ptr<AssistantManagerService> assistant_manager_service) {
249   DCHECK(assistant_manager_service_ == nullptr);
250   assistant_manager_service_for_testing_ = std::move(assistant_manager_service);
251 }
252 
Init()253 void Service::Init() {
254   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
255 
256   ash::AssistantState::Get()->AddObserver(this);
257 
258   if (IsAmbientAssistantEnabled())
259     ambient_ui_model_observer_.Add(ash::AmbientUiModel::Get());
260 
261   DCHECK(!assistant_manager_service_);
262 
263   RequestAccessToken();
264 }
265 
Shutdown()266 void Service::Shutdown() {
267   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
268 
269   if (assistant_manager_service_)
270     StopAssistantManagerService();
271 }
272 
GetAssistant()273 Assistant* Service::GetAssistant() {
274   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
275   DCHECK(assistant_manager_service_);
276   return assistant_manager_service_.get();
277 }
278 
PowerChanged(const power_manager::PowerSupplyProperties & prop)279 void Service::PowerChanged(const power_manager::PowerSupplyProperties& prop) {
280   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
281   const bool power_source_connected =
282       prop.external_power() == power_manager::PowerSupplyProperties::AC;
283   if (power_source_connected == power_source_connected_)
284     return;
285 
286   power_source_connected_ = power_source_connected;
287   UpdateAssistantManagerState();
288 }
289 
SuspendDone(const base::TimeDelta & sleep_duration)290 void Service::SuspendDone(const base::TimeDelta& sleep_duration) {
291   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
292   // |token_refresh_timer_| may become stale during sleeping, so we immediately
293   // request a new token to make sure it is fresh.
294   if (token_refresh_timer_->IsRunning()) {
295     token_refresh_timer_->AbandonAndStop();
296     RequestAccessToken();
297   }
298 }
299 
OnSessionActivated(bool activated)300 void Service::OnSessionActivated(bool activated) {
301   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
302   session_active_ = activated;
303 
304   AssistantClient::Get()->OnAssistantStatusChanged(
305       ToAssistantStatus(assistant_manager_service_->GetState()));
306   UpdateListeningState();
307 }
308 
OnLockStateChanged(bool locked)309 void Service::OnLockStateChanged(bool locked) {
310   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
311   locked_ = locked;
312   UpdateListeningState();
313 }
314 
OnAssistantConsentStatusChanged(int consent_status)315 void Service::OnAssistantConsentStatusChanged(int consent_status) {
316   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
317 
318   // Notify device apps status when user accepts activity control.
319   if (assistant_manager_service_ &&
320       assistant_manager_service_->GetState() ==
321           AssistantManagerService::State::RUNNING) {
322     assistant_manager_service_->SyncDeviceAppsStatus();
323   }
324 }
325 
OnAssistantContextEnabled(bool enabled)326 void Service::OnAssistantContextEnabled(bool enabled) {
327   UpdateAssistantManagerState();
328 }
329 
OnAssistantHotwordAlwaysOn(bool hotword_always_on)330 void Service::OnAssistantHotwordAlwaysOn(bool hotword_always_on) {
331   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
332   // No need to update hotword status if power source is connected.
333   if (power_source_connected_)
334     return;
335 
336   UpdateAssistantManagerState();
337 }
338 
OnAssistantSettingsEnabled(bool enabled)339 void Service::OnAssistantSettingsEnabled(bool enabled) {
340   UpdateAssistantManagerState();
341 }
342 
OnAssistantHotwordEnabled(bool enabled)343 void Service::OnAssistantHotwordEnabled(bool enabled) {
344   UpdateAssistantManagerState();
345 }
346 
OnLocaleChanged(const std::string & locale)347 void Service::OnLocaleChanged(const std::string& locale) {
348   UpdateAssistantManagerState();
349 }
350 
OnArcPlayStoreEnabledChanged(bool enabled)351 void Service::OnArcPlayStoreEnabledChanged(bool enabled) {
352   UpdateAssistantManagerState();
353 }
354 
OnLockedFullScreenStateChanged(bool enabled)355 void Service::OnLockedFullScreenStateChanged(bool enabled) {
356   UpdateListeningState();
357 }
358 
OnCommunicationError(CommunicationErrorType error_type)359 void Service::OnCommunicationError(CommunicationErrorType error_type) {
360   if (error_type == CommunicationErrorType::AuthenticationError)
361     RequestAccessToken();
362 }
363 
OnStateChanged(AssistantManagerService::State new_state)364 void Service::OnStateChanged(AssistantManagerService::State new_state) {
365   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
366 
367   if (new_state == AssistantManagerService::State::STARTED)
368     FinalizeAssistantManagerService();
369   if (new_state == AssistantManagerService::State::RUNNING)
370     DVLOG(1) << "Assistant is running";
371 
372   AssistantClient::Get()->OnAssistantStatusChanged(
373       ToAssistantStatus(new_state));
374   UpdateListeningState();
375 }
376 
OnAmbientUiVisibilityChanged(ash::AmbientUiVisibility visibility)377 void Service::OnAmbientUiVisibilityChanged(
378     ash::AmbientUiVisibility visibility) {
379   DCHECK(IsAmbientAssistantEnabled());
380 
381   if (IsSignedOutMode()) {
382     UpdateAssistantManagerState();
383   } else {
384     // Refresh the access_token before we switch back to signed-in mode in case
385     // that we don't have any auth_token cached before.
386     RequestAccessToken();
387   }
388 }
389 
UpdateAssistantManagerState()390 void Service::UpdateAssistantManagerState() {
391   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
392   auto* assistant_state = ash::AssistantState::Get();
393 
394   if (!assistant_state->hotword_enabled().has_value() ||
395       !assistant_state->settings_enabled().has_value() ||
396       !assistant_state->locale().has_value() ||
397       (!access_token_.has_value() && !IsSignedOutMode()) ||
398       !assistant_state->arc_play_store_enabled().has_value()) {
399     // Assistant state has not finished initialization, let's wait.
400     return;
401   }
402 
403   if (IsSignedOutMode()) {
404     // Clear |access_token_| in signed-out mode to keep it synced with what we
405     // will pass to the |assistant_manager_service_|.
406     access_token_ = base::nullopt;
407   }
408 
409   if (!assistant_manager_service_)
410     CreateAssistantManagerService();
411 
412   auto state = assistant_manager_service_->GetState();
413   switch (state) {
414     case AssistantManagerService::State::STOPPED:
415       if (assistant_state->settings_enabled().value()) {
416         assistant_manager_service_->Start(GetUserInfo(), ShouldEnableHotword());
417         DVLOG(1) << "Request Assistant start";
418       }
419       break;
420     case AssistantManagerService::State::STARTING:
421     case AssistantManagerService::State::STARTED:
422       // If the Assistant is disabled by domain policy, the libassistant will
423       // never becomes ready. Stop waiting for the state change and stop the
424       // service.
425       if (assistant_state->allowed_state() ==
426           AssistantAllowedState::DISALLOWED_BY_POLICY) {
427         StopAssistantManagerService();
428         return;
429       }
430       // Wait if |assistant_manager_service_| is not at a stable state.
431       update_assistant_manager_callback_.Cancel();
432       update_assistant_manager_callback_.Reset(
433           base::BindOnce(&Service::UpdateAssistantManagerState,
434                          weak_ptr_factory_.GetWeakPtr()));
435       main_task_runner_->PostDelayedTask(
436           FROM_HERE, update_assistant_manager_callback_.callback(),
437           kUpdateAssistantManagerDelay);
438       break;
439     case AssistantManagerService::State::RUNNING:
440       if (assistant_state->settings_enabled().value()) {
441         assistant_manager_service_->SetUser(GetUserInfo());
442         if (IsAmbientAssistantEnabled())
443           assistant_manager_service_->EnableAmbientMode(InAmbientMode());
444         assistant_manager_service_->EnableHotword(ShouldEnableHotword());
445         assistant_manager_service_->SetArcPlayStoreEnabled(
446             assistant_state->arc_play_store_enabled().value());
447         assistant_manager_service_->SetAssistantContextEnabled(
448             assistant_state->IsScreenContextAllowed());
449       } else {
450         StopAssistantManagerService();
451       }
452       break;
453   }
454 }
455 
RetrievePrimaryAccountInfo() const456 CoreAccountInfo Service::RetrievePrimaryAccountInfo() const {
457   CoreAccountInfo account_info = identity_manager_->GetPrimaryAccountInfo(
458       signin::ConsentLevel::kNotRequired);
459   CHECK(!account_info.account_id.empty());
460   CHECK(!account_info.gaia.empty());
461   return account_info;
462 }
463 
RequestAccessToken()464 void Service::RequestAccessToken() {
465   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
466 
467   // Bypass access token fetching when service is running in signed-out mode.
468   if (IsSignedOutMode()) {
469     VLOG(1) << "Signed out mode detected, bypass access token fetching.";
470     return;
471   }
472 
473   if (access_token_fetcher_) {
474     LOG(WARNING) << "Access token already requested.";
475     return;
476   }
477 
478   VLOG(1) << "Start requesting access token.";
479   CoreAccountInfo account_info = RetrievePrimaryAccountInfo();
480   if (!identity_manager_->HasAccountWithRefreshToken(account_info.account_id)) {
481     LOG(ERROR) << "Failed to retrieve primary account info. Retrying.";
482     RetryRefreshToken();
483     return;
484   }
485 
486   signin::ScopeSet scopes;
487   scopes.insert(kScopeAssistant);
488   scopes.insert(kScopeAuthGcm);
489   if (features::IsOnDeviceAssistantEnabled())
490     scopes.insert(kScopeGeller);
491 
492   access_token_fetcher_ = identity_manager_->CreateAccessTokenFetcherForAccount(
493       account_info.account_id, "cros_assistant", scopes,
494       base::BindOnce(&Service::GetAccessTokenCallback, base::Unretained(this)),
495       signin::AccessTokenFetcher::Mode::kImmediate);
496 }
497 
GetAccessTokenCallback(GoogleServiceAuthError error,signin::AccessTokenInfo access_token_info)498 void Service::GetAccessTokenCallback(
499     GoogleServiceAuthError error,
500     signin::AccessTokenInfo access_token_info) {
501   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
502 
503   // It's safe to delete AccessTokenFetcher from inside its own callback.
504   access_token_fetcher_.reset();
505 
506   if (error.state() != GoogleServiceAuthError::NONE) {
507     LOG(ERROR) << "Failed to retrieve token, error: " << error.ToString();
508     RetryRefreshToken();
509     return;
510   }
511 
512   access_token_ = access_token_info.token;
513   UpdateAssistantManagerState();
514   token_refresh_timer_->Start(
515       FROM_HERE, access_token_info.expiration_time - base::Time::Now(), this,
516       &Service::RequestAccessToken);
517 }
518 
RetryRefreshToken()519 void Service::RetryRefreshToken() {
520   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
521 
522   base::TimeDelta backoff_delay =
523       std::min(kMinTokenRefreshDelay *
524                    (1 << (token_refresh_error_backoff_factor - 1)),
525                kMaxTokenRefreshDelay) +
526       base::RandDouble() * kMinTokenRefreshDelay;
527   if (backoff_delay < kMaxTokenRefreshDelay)
528     ++token_refresh_error_backoff_factor;
529   token_refresh_timer_->Start(FROM_HERE, backoff_delay, this,
530                               &Service::RequestAccessToken);
531 }
532 
CreateAssistantManagerService()533 void Service::CreateAssistantManagerService() {
534   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
535 
536   assistant_manager_service_ = CreateAndReturnAssistantManagerService();
537   assistant_manager_service_->AddCommunicationErrorObserver(this);
538   assistant_manager_service_->AddAndFireStateObserver(this);
539 
540   if (AssistantInteractionLogger::IsLoggingEnabled()) {
541     interaction_logger_ = std::make_unique<AssistantInteractionLogger>();
542     assistant_manager_service_->AddAssistantInteractionSubscriber(
543         interaction_logger_.get());
544   }
545 }
546 
547 std::unique_ptr<AssistantManagerService>
CreateAndReturnAssistantManagerService()548 Service::CreateAndReturnAssistantManagerService() {
549   if (assistant_manager_service_for_testing_)
550     return std::move(assistant_manager_service_for_testing_);
551 
552 #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
553   mojo::PendingRemote<device::mojom::BatteryMonitor> battery_monitor;
554   AssistantClient::Get()->RequestBatteryMonitor(
555       battery_monitor.InitWithNewPipeAndPassReceiver());
556 
557   auto delegate = std::make_unique<AssistantManagerServiceDelegateImpl>(
558       std::move(battery_monitor), context());
559 
560   // |assistant_manager_service_| is only created once.
561   DCHECK(pending_url_loader_factory_);
562   return std::make_unique<AssistantManagerServiceImpl>(
563       context(), std::move(delegate), std::move(pending_url_loader_factory_),
564       GetS3ServerUriOverride(), GetDeviceIdOverride());
565 #else
566   return std::make_unique<FakeAssistantManagerServiceImpl>();
567 #endif
568 }
569 
FinalizeAssistantManagerService()570 void Service::FinalizeAssistantManagerService() {
571   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
572   DCHECK(assistant_manager_service_->GetState() ==
573              AssistantManagerService::STARTED ||
574          assistant_manager_service_->GetState() ==
575              AssistantManagerService::RUNNING);
576 
577   // Ensure one-time mojom initialization.
578   if (is_assistant_manager_service_finalized_)
579     return;
580   is_assistant_manager_service_finalized_ = true;
581 
582   AddAshSessionObserver();
583 
584   ash::AssistantController::Get()->SetAssistant(
585       assistant_manager_service_.get());
586 }
587 
StopAssistantManagerService()588 void Service::StopAssistantManagerService() {
589   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
590 
591   assistant_manager_service_->Stop();
592   weak_ptr_factory_.InvalidateWeakPtrs();
593   AssistantClient::Get()->OnAssistantStatusChanged(AssistantStatus::NOT_READY);
594 }
595 
AddAshSessionObserver()596 void Service::AddAshSessionObserver() {
597   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
598 
599   // No session controller in unittest.
600   if (ash::SessionController::Get()) {
601     // Note that this account can either be a regular account using real gaia,
602     // or a fake gaia account.
603     CoreAccountInfo account_info = RetrievePrimaryAccountInfo();
604     AccountId account_id = user_manager::known_user::GetAccountId(
605         account_info.email, account_info.gaia, AccountType::GOOGLE);
606     scoped_ash_session_observer_ =
607         std::make_unique<ScopedAshSessionObserver>(this, account_id);
608   }
609 }
610 
UpdateListeningState()611 void Service::UpdateListeningState() {
612   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
613 
614   bool should_listen =
615       !locked_ &&
616       !ash::AssistantState::Get()->locked_full_screen_enabled().value_or(
617           false) &&
618       session_active_;
619   DVLOG(1) << "Update assistant listening state: " << should_listen;
620   assistant_manager_service_->EnableListening(should_listen);
621   assistant_manager_service_->EnableHotword(should_listen &&
622                                             ShouldEnableHotword());
623 }
624 
GetUserInfo() const625 base::Optional<AssistantManagerService::UserInfo> Service::GetUserInfo() const {
626   if (access_token_) {
627     return AssistantManagerService::UserInfo(RetrievePrimaryAccountInfo().gaia,
628                                              access_token_.value());
629   }
630   return base::nullopt;
631 }
632 
ShouldEnableHotword()633 bool Service::ShouldEnableHotword() {
634   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
635 
636   bool dsp_available = context()->cras_audio_handler()->HasHotwordDevice();
637   auto* assistant_state = ash::AssistantState::Get();
638 
639   // Disable hotword if hotword is not set to always on and power source is not
640   // connected.
641   if (!dsp_available && !assistant_state->hotword_always_on().value_or(false) &&
642       !power_source_connected_) {
643     return false;
644   }
645 
646   return assistant_state->hotword_enabled().value();
647 }
648 
649 }  // namespace assistant
650 }  // namespace chromeos
651