Skip to content

Commit

Permalink
Support video themes in AmbientController.
Browse files Browse the repository at this point in the history
Bug: b:271180547
Change-Id: I464ccdd071fd90954a86a72b35d3a6cf68b3cc16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4308337
Reviewed-by: Xiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: Tao Wu <wutao@chromium.org>
Commit-Queue: Eric Sum <esum@google.com>
Cr-Commit-Position: refs/heads/main@{#1118922}
  • Loading branch information
esum26 authored and Chromium LUCI CQ committed Mar 17, 2023
1 parent c3eec68 commit 2f03920
Show file tree
Hide file tree
Showing 11 changed files with 459 additions and 89 deletions.
2 changes: 2 additions & 0 deletions ash/BUILD.gn
Expand Up @@ -175,6 +175,8 @@ component("ash") {
"ambient/ambient_ui_launcher.h",
"ambient/ambient_ui_settings.cc",
"ambient/ambient_ui_settings.h",
"ambient/ambient_video_ui_launcher.cc",
"ambient/ambient_video_ui_launcher.h",
"ambient/ambient_view_delegate_impl.cc",
"ambient/ambient_view_delegate_impl.h",
"ambient/ambient_weather_controller.cc",
Expand Down
138 changes: 101 additions & 37 deletions ash/ambient/ambient_controller.cc
Expand Up @@ -13,6 +13,7 @@
#include "ash/ambient/ambient_managed_slideshow_ui_launcher.h"
#include "ash/ambient/ambient_ui_launcher.h"
#include "ash/ambient/ambient_ui_settings.h"
#include "ash/ambient/ambient_video_ui_launcher.h"
#include "ash/ambient/ambient_weather_controller.h"
#include "ash/ambient/metrics/ambient_multi_screen_metrics_recorder.h"
#include "ash/ambient/model/ambient_animation_photo_config.h"
Expand Down Expand Up @@ -340,7 +341,9 @@ void AmbientController::OnLockStateChanged(bool locked) {

// Reset image failures to allow retrying ambient mode after lock state
// changes.
GetAmbientBackendModel()->ResetImageFailures();
if (GetAmbientBackendModel()) {
GetAmbientBackendModel()->ResetImageFailures();
}

// We have 3 options to manage the token for lock screen. Here use option 1.
// 1. Request only one time after entering lock screen. We will use it once
Expand Down Expand Up @@ -429,7 +432,8 @@ void AmbientController::ScreenIdleStateChanged(
return;

// Do not show UI if loading images was unsuccessful.
if (GetAmbientBackendModel()->ImageLoadingFailed()) {
if (GetAmbientBackendModel() &&
GetAmbientBackendModel()->ImageLoadingFailed()) {
VLOG(1) << "Skipping ambient mode activation due to prior failure";
GetAmbientBackendModel()->ResetImageFailures();
return;
Expand Down Expand Up @@ -661,6 +665,10 @@ void AmbientController::CloseAllWidgets(bool immediately) {
void AmbientController::OnEnabledPrefChanged() {
if (IsAmbientModeEnabled()) {
DVLOG(1) << "Ambient mode enabled";
// TODO(b/274165045): Remove this temporary way of circulating the video
// theme throughout the system once the hub supports the video theme. This
// is just for experimentation purposes until then.
SetUiSettingsForExperimentation();

pref_change_registrar_->Add(
ambient::prefs::kAmbientModeLockScreenInactivityTimeoutSeconds,
Expand Down Expand Up @@ -696,27 +704,7 @@ void AmbientController::OnEnabledPrefChanged() {
OnPhotoRefreshIntervalPrefChanged();
OnAnimationPlaybackSpeedChanged();

if (ash::features::IsAmbientModeManagedScreensaverEnabled()) {
// TODO (b/269576509) : Integrate with managed screensaver policy
ambient_ui_launcher_ =
std::make_unique<AmbientManagedSlideshowUiLauncher>(&delegate_);

} else {
DCHECK(AmbientClient::Get());
ambient_photo_controller_ = std::make_unique<AmbientPhotoController>(
*AmbientClient::Get(), access_token_controller_, delegate_,
// The type of photo config specified here is actually irrelevant as
// it always gets reset with the correct configuration anyways in
// StartRefreshingImages() before ambient mode starts.
CreateAmbientSlideshowPhotoConfig());
// The new UiLauncher API adds backend model observers in its
// implementation and thus the observer is not required when using the new
// codepath.
// TODO(esum) Get rid the ambient_backend_model_observer_ and
// corresponding methods once other photo controllers are migrated to the
// new API.
ambient_backend_model_observer_.Observe(GetAmbientBackendModel());
}
CreateUiLauncher();

ambient_ui_model_observer_.Observe(&ambient_ui_model_);
auto* power_manager_client = chromeos::PowerManagerClient::Get();
Expand Down Expand Up @@ -746,15 +734,12 @@ void AmbientController::OnEnabledPrefChanged() {
}

ambient_ui_model_observer_.Reset();
ambient_backend_model_observer_.Reset();
power_manager_client_observer_.Reset();

ambient_ui_launcher_.reset();
DestroyUiLauncher();

if (fingerprint_observer_receiver_.is_bound())
fingerprint_observer_receiver_.reset();

ambient_photo_controller_.reset();
}
}

Expand Down Expand Up @@ -813,6 +798,10 @@ void AmbientController::OnAmbientUiSettingsChanged() {
LOG(WARNING) << "AmbientUiSettings changed while ambient mode pref is "
"disabled. Can't clear ambient photo cache.";
}

// The |AmbientUiLauncher| implementation to use is largely dependent on
// the current |AmbientUiSettings|, so this needs to be recreated.
CreateUiLauncher();
}

void AmbientController::OnAnimationPlaybackSpeedChanged() {
Expand Down Expand Up @@ -853,6 +842,11 @@ void AmbientController::DismissUI() {

AmbientBackendModel* AmbientController::GetAmbientBackendModel() {
if (ambient_ui_launcher_) {
// This can legitimately be null. Some ambient UIs do not use photos at all
// and hence, do not have an active |AmbientBackendModel|.
// TODO(b/274164306): Move |AmbientBackendModel| references completely out
// of |AmbientController|. The business logic should be migrated elsewhere
// (likely somewhere within an |AmbientUiLauncher| implementation).
return ambient_ui_launcher_->GetAmbientBackendModel();
}

Expand All @@ -876,13 +870,21 @@ void AmbientController::OnImagesFailed() {
std::unique_ptr<views::Widget> AmbientController::CreateWidget(
aura::Window* container) {
AmbientTheme current_theme = GetCurrentUiSettings().theme();
// TODO(esum) Call AmbientUiLauncher::CreateView() and pass it to the
// AmbientContainerView.
auto container_view = std::make_unique<AmbientContainerView>(
&delegate_, ambient_animation_progress_tracker_.get(),
AmbientAnimationStaticResources::Create(current_theme,
/*serializable=*/true),
multi_screen_metrics_recorder_.get(), frame_rate_controller_.get());
std::unique_ptr<AmbientContainerView> container_view;
if (ambient_ui_launcher_) {
container_view = std::make_unique<AmbientContainerView>(
current_theme, ambient_ui_launcher_->CreateView(),
multi_screen_metrics_recorder_.get());
} else {
// TODO(b/274164306): Everything should use
// |AmbientUiLauncher::CreateView()| when slideshow and animation themes
// are migrated to AmbientUiLauncher.
container_view = std::make_unique<AmbientContainerView>(
&delegate_, ambient_animation_progress_tracker_.get(),
AmbientAnimationStaticResources::Create(current_theme,
/*serializable=*/true),
multi_screen_metrics_recorder_.get(), frame_rate_controller_.get());
}
auto* widget_delegate = new AmbientWidgetDelegate();
widget_delegate->SetInitiallyFocusedView(container_view.get());

Expand Down Expand Up @@ -980,9 +982,7 @@ void AmbientController::StopScreensaver() {

void AmbientController::MaybeStartScreenSaver() {
// The screensaver may have already been started.
if ((ambient_ui_launcher_ && ambient_ui_launcher_->IsActive()) ||
(ambient_photo_controller_ &&
ambient_photo_controller_->IsScreenUpdateActive())) {
if (IsUiLauncherActive()) {
return;
}

Expand Down Expand Up @@ -1014,6 +1014,15 @@ AmbientUiSettings AmbientController::GetCurrentUiSettings() const {
return AmbientUiSettings::ReadFromPrefService(*GetPrimaryUserPrefService());
}

void AmbientController::SetUiSettingsForExperimentation() {
if (features::IsTimeOfDayScreenSaverEnabled()) {
CHECK(GetPrimaryUserPrefService());
AmbientUiSettings(AmbientTheme::kVideo,
features::kTimeOfDayScreenSaverVideo.Get())
.WriteToPrefService(*GetPrimaryUserPrefService());
}
}

void AmbientController::MaybeDismissUIOnMouseMove() {
// If the move was not an actual mouse move event or the screen saver widget
// is not shown yet (images are not downloaded), don't dismiss.
Expand All @@ -1032,4 +1041,59 @@ void AmbientController::MaybeDismissUIOnMouseMove() {
}
DismissUI();
}

void AmbientController::CreateUiLauncher() {
if (IsUiLauncherActive()) {
// There are no known use cases where the AmbientUiSettings selected by the
// user can change while in the middle of an ambient session, but this is
// handled gracefully just in case.
LOG(DFATAL) << "Cannot reset the AmbientUiLauncher while it is active";
return;
}

DestroyUiLauncher();

if (ash::features::IsAmbientModeManagedScreensaverEnabled()) {
// TODO (b/269576509) : Integrate with managed screensaver policy
ambient_ui_launcher_ =
std::make_unique<AmbientManagedSlideshowUiLauncher>(&delegate_);
} else if (GetCurrentUiSettings().theme() == AmbientTheme::kVideo) {
ambient_ui_launcher_ =
std::make_unique<AmbientVideoUiLauncher>(GetPrimaryUserPrefService());
} else {
// TODO(b/274164306): Remove when slideshow and animation themes are
// migrated to AmbientUiLauncher.
DCHECK(AmbientClient::Get());
ambient_photo_controller_ = std::make_unique<AmbientPhotoController>(
*AmbientClient::Get(), access_token_controller_, delegate_,
// The type of photo config specified here is actually irrelevant as
// it always gets reset with the correct configuration anyways in
// StartRefreshingImages() before ambient mode starts.
CreateAmbientSlideshowPhotoConfig());
// The new UiLauncher API adds backend model observers in its
// implementation and thus the observer is not required when using the new
// codepath.
// TODO(esum) Get rid the ambient_backend_model_observer_ and
// corresponding methods once other photo controllers are migrated to the
// new API.
ambient_backend_model_observer_.Observe(GetAmbientBackendModel());
}
}

void AmbientController::DestroyUiLauncher() {
ambient_ui_launcher_.reset();
// TODO(b/274164306): Remove when slideshow and animation themes are migrated
// to AmbientUiLauncher.
ambient_backend_model_observer_.Reset();
ambient_photo_controller_.reset();
}

bool AmbientController::IsUiLauncherActive() const {
return (ambient_ui_launcher_ && ambient_ui_launcher_->IsActive()) ||
// TODO(b/274164306): Remove when slideshow and animation themes are
// migrated to AmbientUiLauncher.
(ambient_photo_controller_ &&
ambient_photo_controller_->IsScreenUpdateActive());
}

} // namespace ash
5 changes: 5 additions & 0 deletions ash/ambient/ambient_controller.h
Expand Up @@ -197,6 +197,7 @@ class ASH_EXPORT AmbientController
void MaybeStartScreenSaver();
void MaybeDismissUIOnMouseMove();
AmbientUiSettings GetCurrentUiSettings() const;
void SetUiSettingsForExperimentation();

// Invoked when the auto-show timer in |InactivityMonitor| gets fired after
// device being inactive for a specific amount of time.
Expand All @@ -219,6 +220,10 @@ class ASH_EXPORT AmbientController
void OnAmbientUiSettingsChanged();
void OnAnimationPlaybackSpeedChanged();

void CreateUiLauncher();
void DestroyUiLauncher();
bool IsUiLauncherActive() const;

AmbientAccessTokenController* access_token_controller_for_testing() {
return &access_token_controller_;
}
Expand Down

0 comments on commit 2f03920

Please sign in to comment.