Commit 29736b94 authored by Xiaohui Chen's avatar Xiaohui Chen Committed by Commit Bot

ambient: handle suspend case better

Previously ambient mode will trigger lockscreen on screen dimm and then
rely on lock screen idle to show screen saver. This works in some cases,
but in suspend case the time between screen dim and cpu suspend is too
short. Screen saver was not able to enguage. The reason we have the set
up is because the screen saver was sharing the same window constainer as
the lock screen, it cannot show before lock screen is ready.

Now screen saver has its own window container, we changed the flow to
show ambient mode immediately when idle. This will prevent cpu suspend
because screen saver will take a wake lock if charging. Screen saver
will still lock the screen in the back if user reference indicated
lockscreen after wake.

Bug: b:169442907
Test: unitests and manual tests
Change-Id: I1a5df2c58c976bba492c709e0a61dd5a6314d084
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2435334Reviewed-by: default avatarTao Wu <wutao@chromium.org>
Commit-Queue: Xiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812397}
parent 97f51122
...@@ -28,6 +28,9 @@ constexpr base::TimeDelta kPhotoRefreshInterval = ...@@ -28,6 +28,9 @@ constexpr base::TimeDelta kPhotoRefreshInterval =
constexpr base::TimeDelta kWeatherRefreshInterval = constexpr base::TimeDelta kWeatherRefreshInterval =
base::TimeDelta::FromMinutes(5); base::TimeDelta::FromMinutes(5);
// The delay between ambient mode starts and enabling lock screen.
constexpr base::TimeDelta kLockScreenDelay = base::TimeDelta::FromSeconds(5);
// The batch size of topics to fetch in one request. // The batch size of topics to fetch in one request.
// Magic number 2 is based on experiments that no curation on Google Photos. // Magic number 2 is based on experiments that no curation on Google Photos.
constexpr int kTopicsBatchSize = 2; constexpr int kTopicsBatchSize = 2;
......
...@@ -96,10 +96,6 @@ bool IsUiHidden(AmbientUiVisibility visibility) { ...@@ -96,10 +96,6 @@ bool IsUiHidden(AmbientUiVisibility visibility) {
return visibility == AmbientUiVisibility::kHidden; return visibility == AmbientUiVisibility::kHidden;
} }
bool IsLockScreenUi(AmbientUiMode mode) {
return mode == AmbientUiMode::kLockScreenUi;
}
bool IsAmbientModeEnabled() { bool IsAmbientModeEnabled() {
if (!AmbientClient::Get()->IsAmbientModeAllowed()) if (!AmbientClient::Get()->IsAmbientModeAllowed())
return false; return false;
...@@ -204,7 +200,8 @@ void AmbientController::OnAmbientUiVisibilityChanged( ...@@ -204,7 +200,8 @@ void AmbientController::OnAmbientUiVisibilityChanged(
// Record metrics on ambient mode usage. // Record metrics on ambient mode usage.
ambient::RecordAmbientModeActivation( ambient::RecordAmbientModeActivation(
/*ui_mode=*/ambient_ui_model_.ui_mode(), /*ui_mode=*/LockScreen::HasInstance() ? AmbientUiMode::kLockScreenUi
: AmbientUiMode::kInSessionUi,
/*tablet_mode=*/Shell::Get()->IsInTabletMode()); /*tablet_mode=*/Shell::Get()->IsInTabletMode());
DCHECK(!start_time_); DCHECK(!start_time_);
...@@ -319,7 +316,11 @@ void AmbientController::OnLockStateChanged(bool locked) { ...@@ -319,7 +316,11 @@ void AmbientController::OnLockStateChanged(bool locked) {
// wait. // wait.
RequestAccessToken(base::DoNothing(), /*may_refresh_token_on_lock=*/true); RequestAccessToken(base::DoNothing(), /*may_refresh_token_on_lock=*/true);
ShowUi(AmbientUiMode::kLockScreenUi); if (!IsShown()) {
// When lock screen starts, we don't immediately show the UI. The Ui is
// hidden and will show after a delay.
ShowHiddenUi();
}
} else { } else {
// Ambient screen will be destroyed along with the lock screen when user // Ambient screen will be destroyed along with the lock screen when user
// logs in. // logs in.
...@@ -374,7 +375,7 @@ void AmbientController::ScreenBrightnessChanged( ...@@ -374,7 +375,7 @@ void AmbientController::ScreenBrightnessChanged(
is_screen_off_ = false; is_screen_off_ = false;
// If screen is back on, turn on ambient mode for lock screen. // If screen is back on, turn on ambient mode for lock screen.
if (LockScreen::HasInstance()) if (LockScreen::HasInstance())
ShowUi(AmbientUiMode::kLockScreenUi); ShowHiddenUi();
} }
void AmbientController::ScreenIdleStateChanged( void AmbientController::ScreenIdleStateChanged(
...@@ -392,16 +393,7 @@ void AmbientController::ScreenIdleStateChanged( ...@@ -392,16 +393,7 @@ void AmbientController::ScreenIdleStateChanged(
if (!idle_state.dimmed()) if (!idle_state.dimmed())
return; return;
auto* session_controller = Shell::Get()->session_controller(); ShowUi();
if (session_controller->CanLockScreen() &&
session_controller->ShouldLockScreenAutomatically()) {
if (!session_controller->IsScreenLocked()) {
// TODO(b/161469136): revise this behavior after further discussion.
Shell::Get()->session_controller()->LockScreen();
}
} else {
ShowUi(AmbientUiMode::kInSessionUi);
}
} }
void AmbientController::AddAmbientViewDelegateObserver( void AmbientController::AddAmbientViewDelegateObserver(
...@@ -414,8 +406,8 @@ void AmbientController::RemoveAmbientViewDelegateObserver( ...@@ -414,8 +406,8 @@ void AmbientController::RemoveAmbientViewDelegateObserver(
delegate_.RemoveObserver(observer); delegate_.RemoveObserver(observer);
} }
void AmbientController::ShowUi(AmbientUiMode mode) { void AmbientController::ShowUi() {
DVLOG(1) << "ShowUi: " << mode; DVLOG(1) << __func__;
// TODO(meilinw): move the eligibility check to the idle entry point once // TODO(meilinw): move the eligibility check to the idle entry point once
// implemented: b/149246117. // implemented: b/149246117.
...@@ -424,30 +416,24 @@ void AmbientController::ShowUi(AmbientUiMode mode) { ...@@ -424,30 +416,24 @@ void AmbientController::ShowUi(AmbientUiMode mode) {
return; return;
} }
ambient_ui_model_.SetUiMode(mode); ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kShown);
switch (mode) {
case AmbientUiMode::kInSessionUi:
ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kShown);
break;
case AmbientUiMode::kLockScreenUi:
ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kHidden);
break;
}
} }
void AmbientController::CloseUi() { void AmbientController::ShowHiddenUi() {
ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kClosed); DVLOG(1) << __func__;
ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kHidden);
} }
void AmbientController::HideLockScreenUi() { void AmbientController::CloseUi() {
DCHECK(IsLockScreenUi(ambient_ui_model_.ui_mode())); DVLOG(1) << __func__;
ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kHidden); ambient_ui_model_.SetUiVisibility(AmbientUiVisibility::kClosed);
} }
void AmbientController::ToggleInSessionUi() { void AmbientController::ToggleInSessionUi() {
if (!container_view_) if (ambient_ui_model_.ui_visibility() == AmbientUiVisibility::kClosed)
ShowUi(AmbientUiMode::kInSessionUi); ShowUi();
else else
CloseUi(); CloseUi();
} }
...@@ -458,16 +444,12 @@ bool AmbientController::IsShown() const { ...@@ -458,16 +444,12 @@ bool AmbientController::IsShown() const {
void AmbientController::OnBackgroundPhotoEvents() { void AmbientController::OnBackgroundPhotoEvents() {
// Dismisses the ambient screen when user interacts with the background photo. // Dismisses the ambient screen when user interacts with the background photo.
if (IsLockScreenUi(ambient_ui_model_.ui_mode())) if (LockScreen::HasInstance())
HideLockScreenUi(); ShowHiddenUi();
else else
CloseUi(); CloseUi();
} }
void AmbientController::UpdateUiMode(AmbientUiMode ui_mode) {
ambient_ui_model_.SetUiMode(ui_mode);
}
void AmbientController::AcquireWakeLock() { void AmbientController::AcquireWakeLock() {
if (!wake_lock_) { if (!wake_lock_) {
mojo::Remote<device::mojom::WakeLockProvider> provider; mojo::Remote<device::mojom::WakeLockProvider> provider;
...@@ -482,6 +464,17 @@ void AmbientController::AcquireWakeLock() { ...@@ -482,6 +464,17 @@ void AmbientController::AcquireWakeLock() {
DCHECK(wake_lock_); DCHECK(wake_lock_);
wake_lock_->RequestWakeLock(); wake_lock_->RequestWakeLock();
VLOG(1) << "Acquired wake lock"; VLOG(1) << "Acquired wake lock";
auto* session_controller = Shell::Get()->session_controller();
if (session_controller->CanLockScreen() &&
session_controller->ShouldLockScreenAutomatically()) {
if (!session_controller->IsScreenLocked()) {
delayed_lock_timer_.Start(
FROM_HERE, kLockScreenDelay, base::BindOnce([]() {
Shell::Get()->session_controller()->LockScreen();
}));
}
}
} }
void AmbientController::ReleaseWakeLock() { void AmbientController::ReleaseWakeLock() {
...@@ -490,6 +483,8 @@ void AmbientController::ReleaseWakeLock() { ...@@ -490,6 +483,8 @@ void AmbientController::ReleaseWakeLock() {
wake_lock_->CancelWakeLock(); wake_lock_->CancelWakeLock();
VLOG(1) << "Released wake lock"; VLOG(1) << "Released wake lock";
delayed_lock_timer_.Stop();
} }
void AmbientController::CloseWidget(bool immediately) { void AmbientController::CloseWidget(bool immediately) {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "base/timer/timer.h"
#include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power/power_manager_client.h"
#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
...@@ -74,12 +75,12 @@ class ASH_EXPORT AmbientController ...@@ -74,12 +75,12 @@ class ASH_EXPORT AmbientController
void AddAmbientViewDelegateObserver(AmbientViewDelegateObserver* observer); void AddAmbientViewDelegateObserver(AmbientViewDelegateObserver* observer);
void RemoveAmbientViewDelegateObserver(AmbientViewDelegateObserver* observer); void RemoveAmbientViewDelegateObserver(AmbientViewDelegateObserver* observer);
// Invoked to show/close ambient UI in |mode|. void ShowUi();
void ShowUi(AmbientUiMode mode); // Ui will be enabled but not shown immediately. If there is no user activity
// Ui will be shown after a short delay.
void ShowHiddenUi();
void CloseUi(); void CloseUi();
void HideLockScreenUi();
void ToggleInSessionUi(); void ToggleInSessionUi();
// Returns true if the |container_view_| is currently visible. // Returns true if the |container_view_| is currently visible.
...@@ -88,8 +89,6 @@ class ASH_EXPORT AmbientController ...@@ -88,8 +89,6 @@ class ASH_EXPORT AmbientController
// Handles events on the background photo. // Handles events on the background photo.
void OnBackgroundPhotoEvents(); void OnBackgroundPhotoEvents();
void UpdateUiMode(AmbientUiMode ui_mode);
void RequestAccessToken( void RequestAccessToken(
AmbientAccessTokenController::AccessTokenCallback callback, AmbientAccessTokenController::AccessTokenCallback callback,
bool may_refresh_token_on_lock = false); bool may_refresh_token_on_lock = false);
...@@ -190,6 +189,8 @@ class ASH_EXPORT AmbientController ...@@ -190,6 +189,8 @@ class ASH_EXPORT AmbientController
// Used to record Ambient mode engagement metrics. // Used to record Ambient mode engagement metrics.
base::Optional<base::Time> start_time_ = base::nullopt; base::Optional<base::Time> start_time_ = base::nullopt;
base::OneShotTimer delayed_lock_timer_;
base::WeakPtrFactory<AmbientController> weak_ptr_factory_{this}; base::WeakPtrFactory<AmbientController> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(AmbientController); DISALLOW_COPY_AND_ASSIGN(AmbientController);
}; };
......
...@@ -43,7 +43,7 @@ TEST_F(AmbientControllerTest, ShowAmbientScreenUponLock) { ...@@ -43,7 +43,7 @@ TEST_F(AmbientControllerTest, ShowAmbientScreenUponLock) {
// Ambient mode will show after inacivity and successfully loading first // Ambient mode will show after inacivity and successfully loading first
// image. // image.
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()); EXPECT_TRUE(container_view());
EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
...@@ -65,7 +65,7 @@ TEST_F(AmbientControllerTest, NotShowAmbientWhenPrefNotEnabled) { ...@@ -65,7 +65,7 @@ TEST_F(AmbientControllerTest, NotShowAmbientWhenPrefNotEnabled) {
// Ambient mode will not show after inacivity and successfully loading first // Ambient mode will not show after inacivity and successfully loading first
// image. // image.
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_FALSE(container_view()); EXPECT_FALSE(container_view());
EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
...@@ -80,7 +80,7 @@ TEST_F(AmbientControllerTest, NotShowAmbientWhenPrefNotEnabled) { ...@@ -80,7 +80,7 @@ TEST_F(AmbientControllerTest, NotShowAmbientWhenPrefNotEnabled) {
TEST_F(AmbientControllerTest, HideAmbientScreen) { TEST_F(AmbientControllerTest, HideAmbientScreen) {
LockScreen(); LockScreen();
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()); EXPECT_TRUE(container_view());
EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
...@@ -101,7 +101,7 @@ TEST_F(AmbientControllerTest, HideAmbientScreen) { ...@@ -101,7 +101,7 @@ TEST_F(AmbientControllerTest, HideAmbientScreen) {
TEST_F(AmbientControllerTest, CloseAmbientScreenUponUnlock) { TEST_F(AmbientControllerTest, CloseAmbientScreenUponUnlock) {
LockScreen(); LockScreen();
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()); EXPECT_TRUE(container_view());
EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
...@@ -294,16 +294,13 @@ TEST_F(AmbientControllerTest, ShouldRetryRefreshAccessTokenOnlyThreeTimes) { ...@@ -294,16 +294,13 @@ TEST_F(AmbientControllerTest, ShouldRetryRefreshAccessTokenOnlyThreeTimes) {
TEST_F(AmbientControllerTest, TEST_F(AmbientControllerTest,
CheckAcquireAndReleaseWakeLockWhenBatteryIsCharging) { CheckAcquireAndReleaseWakeLockWhenBatteryIsCharging) {
// Simulate a device being connected to a charger initially. // Simulate a device being connected to a charger initially.
power_manager::PowerSupplyProperties proto; SetPowerStateCharging();
proto.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_CHARGING);
PowerStatus::Get()->SetProtoForTesting(proto);
// Lock screen to start ambient mode, and flush the loop to ensure // Lock screen to start ambient mode, and flush the loop to ensure
// the acquire wake lock request has reached the wake lock provider. // the acquire wake lock request has reached the wake lock provider.
LockScreen(); LockScreen();
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_EQ(1, GetNumOfActiveWakeLocks( EXPECT_EQ(1, GetNumOfActiveWakeLocks(
device::mojom::WakeLockType::kPreventDisplaySleep)); device::mojom::WakeLockType::kPreventDisplaySleep));
...@@ -330,17 +327,11 @@ TEST_F(AmbientControllerTest, ...@@ -330,17 +327,11 @@ TEST_F(AmbientControllerTest,
TEST_F(AmbientControllerTest, TEST_F(AmbientControllerTest,
CheckAcquireAndReleaseWakeLockWhenBatteryStateChanged) { CheckAcquireAndReleaseWakeLockWhenBatteryStateChanged) {
// Simulate a device being disconnected with a charger initially. SetPowerStateDischarging();
power_manager::PowerSupplyProperties proto;
proto.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_DISCHARGING);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
PowerStatus::Get()->SetProtoForTesting(proto);
// Lock screen to start ambient mode. // Lock screen to start ambient mode.
LockScreen(); LockScreen();
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(ambient_controller()->IsShown()); EXPECT_TRUE(ambient_controller()->IsShown());
// Should not acquire wake lock when device is not charging. // Should not acquire wake lock when device is not charging.
...@@ -348,14 +339,7 @@ TEST_F(AmbientControllerTest, ...@@ -348,14 +339,7 @@ TEST_F(AmbientControllerTest,
device::mojom::WakeLockType::kPreventDisplaySleep)); device::mojom::WakeLockType::kPreventDisplaySleep));
// Connect the device with a charger. // Connect the device with a charger.
proto.set_battery_state( SetPowerStateCharging();
power_manager::PowerSupplyProperties_BatteryState_CHARGING);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_AC);
PowerStatus::Get()->SetProtoForTesting(proto);
// Notify the controller about the power status change, and flush the loop to
// ensure the wake lock request has reached the wake lock provider.
ambient_controller()->OnPowerStatusChanged();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// Should acquire the wake lock when battery is charging. // Should acquire the wake lock when battery is charging.
...@@ -363,24 +347,14 @@ TEST_F(AmbientControllerTest, ...@@ -363,24 +347,14 @@ TEST_F(AmbientControllerTest,
device::mojom::WakeLockType::kPreventDisplaySleep)); device::mojom::WakeLockType::kPreventDisplaySleep));
// Simulates a full battery. // Simulates a full battery.
proto.set_battery_state( SetPowerStateFull();
power_manager::PowerSupplyProperties_BatteryState_FULL);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_AC);
PowerStatus::Get()->SetProtoForTesting(proto);
ambient_controller()->OnPowerStatusChanged();
// Should keep the wake lock as the charger is still connected. // Should keep the wake lock as the charger is still connected.
EXPECT_EQ(1, GetNumOfActiveWakeLocks( EXPECT_EQ(1, GetNumOfActiveWakeLocks(
device::mojom::WakeLockType::kPreventDisplaySleep)); device::mojom::WakeLockType::kPreventDisplaySleep));
// Disconnects the charger again. // Disconnects the charger again.
proto.set_battery_state( SetPowerStateDischarging();
power_manager::PowerSupplyProperties_BatteryState_DISCHARGING);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
PowerStatus::Get()->SetProtoForTesting(proto);
ambient_controller()->OnPowerStatusChanged();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// Should release the wake lock when battery is not charging. // Should release the wake lock when battery is not charging.
...@@ -395,7 +369,7 @@ TEST_F(AmbientControllerTest, ...@@ -395,7 +369,7 @@ TEST_F(AmbientControllerTest,
TEST_F(AmbientControllerTest, ShouldDismissContainerViewWhenKeyPressed) { TEST_F(AmbientControllerTest, ShouldDismissContainerViewWhenKeyPressed) {
ShowAmbientScreen(); ShowAmbientScreen();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); EXPECT_TRUE(container_view()->GetWidget()->IsVisible());
// Simulates a random keyboard press event. // Simulates a random keyboard press event.
...@@ -409,7 +383,7 @@ TEST_F(AmbientControllerTest, ShouldDismissContainerViewWhenKeyPressed) { ...@@ -409,7 +383,7 @@ TEST_F(AmbientControllerTest, ShouldDismissContainerViewWhenKeyPressed) {
TEST_F(AmbientControllerTest, ShouldDismissContainerViewOnRealMouseMove) { TEST_F(AmbientControllerTest, ShouldDismissContainerViewOnRealMouseMove) {
ShowAmbientScreen(); ShowAmbientScreen();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); EXPECT_TRUE(container_view()->GetWidget()->IsVisible());
// Simulates a tiny mouse move within the threshold, which should be ignored. // Simulates a tiny mouse move within the threshold, which should be ignored.
...@@ -425,29 +399,34 @@ TEST_F(AmbientControllerTest, ShouldDismissContainerViewOnRealMouseMove) { ...@@ -425,29 +399,34 @@ TEST_F(AmbientControllerTest, ShouldDismissContainerViewOnRealMouseMove) {
TEST_F(AmbientControllerTest, ShouldDismissAndThenComesBack) { TEST_F(AmbientControllerTest, ShouldDismissAndThenComesBack) {
LockScreen(); LockScreen();
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); EXPECT_TRUE(container_view()->GetWidget()->IsVisible());
GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_1, ui::EF_NONE); GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_1, ui::EF_NONE);
EXPECT_FALSE(container_view()); EXPECT_FALSE(container_view());
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()->GetWidget()->IsVisible()); EXPECT_TRUE(container_view()->GetWidget()->IsVisible());
} }
TEST_F(AmbientControllerTest, TEST_F(AmbientControllerTest,
ShouldShowAmbientScreenWithLockscreenWhenScreenIsDimmed) { ShouldShowAmbientScreenWithLockscreenWhenScreenIsDimmed) {
GetSessionControllerClient()->SetShouldLockScreenAutomatically(true); GetSessionControllerClient()->SetShouldLockScreenAutomatically(true);
SetPowerStateCharging();
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
// Should lock the device and enter ambient mode when the screen is dimmed. // Should enter ambient mode when the screen is dimmed.
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false);
EXPECT_TRUE(IsLocked()); EXPECT_FALSE(IsLocked());
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
FastForwardToInactivity(); FastForwardTiny();
FastForwardToNextImage(); EXPECT_TRUE(ambient_controller()->IsShown());
FastForwardToLockScreen();
EXPECT_TRUE(IsLocked());
// Should not disrupt ongoing ambient mode.
EXPECT_TRUE(ambient_controller()->IsShown()); EXPECT_TRUE(ambient_controller()->IsShown());
// Closes ambient for clean-up. // Closes ambient for clean-up.
...@@ -455,8 +434,35 @@ TEST_F(AmbientControllerTest, ...@@ -455,8 +434,35 @@ TEST_F(AmbientControllerTest,
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
} }
TEST_F(AmbientControllerTest,
ShouldShowAmbientScreenWithoutLockscreenWhenScreenIsDimmed) {
GetSessionControllerClient()->SetShouldLockScreenAutomatically(true);
// When power is discharging, we do not lock the screen with ambient
// mode since we do not prevent the device go to sleep which will natually
// lock the device.
SetPowerStateDischarging();
EXPECT_FALSE(ambient_controller()->IsShown());
// Should not lock the device and enter ambient mode when the screen is
// dimmed.
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false);
EXPECT_FALSE(IsLocked());
EXPECT_FALSE(ambient_controller()->IsShown());
FastForwardToInactivity();
FastForwardTiny();
EXPECT_TRUE(ambient_controller()->IsShown());
FastForwardToLockScreen();
EXPECT_FALSE(IsLocked());
// Closes ambient for clean-up.
CloseAmbientScreen();
}
TEST_F(AmbientControllerTest, ShouldShowAmbientScreenWhenScreenIsDimmed) { TEST_F(AmbientControllerTest, ShouldShowAmbientScreenWhenScreenIsDimmed) {
GetSessionControllerClient()->SetShouldLockScreenAutomatically(false); GetSessionControllerClient()->SetShouldLockScreenAutomatically(false);
SetPowerStateCharging();
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
// Should not lock the device but enter ambient mode when the screen is // Should not lock the device but enter ambient mode when the screen is
...@@ -464,9 +470,12 @@ TEST_F(AmbientControllerTest, ShouldShowAmbientScreenWhenScreenIsDimmed) { ...@@ -464,9 +470,12 @@ TEST_F(AmbientControllerTest, ShouldShowAmbientScreenWhenScreenIsDimmed) {
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false);
EXPECT_FALSE(IsLocked()); EXPECT_FALSE(IsLocked());
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(ambient_controller()->IsShown()); EXPECT_TRUE(ambient_controller()->IsShown());
FastForwardToLockScreen();
EXPECT_FALSE(IsLocked());
// Closes ambient for clean-up. // Closes ambient for clean-up.
CloseAmbientScreen(); CloseAmbientScreen();
} }
...@@ -481,42 +490,46 @@ TEST_F(AmbientControllerTest, ShouldHideAmbientScreenWhenDisplayIsOff) { ...@@ -481,42 +490,46 @@ TEST_F(AmbientControllerTest, ShouldHideAmbientScreenWhenDisplayIsOff) {
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false);
EXPECT_FALSE(IsLocked()); EXPECT_FALSE(IsLocked());
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(ambient_controller()->IsShown()); EXPECT_TRUE(ambient_controller()->IsShown());
// Should dismiss ambient mode screen. // Should dismiss ambient mode screen.
SetScreenBrightnessAndWait(/*percent=*/0); SetScreenBrightnessAndWait(/*percent=*/0);
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/true); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/true);
FastForwardToNextImage(); FastForwardTiny();
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
// Screen back on again, should not have ambient screen. // Screen back on again, should not have ambient screen.
SetScreenBrightnessAndWait(/*percent=*/50); SetScreenBrightnessAndWait(/*percent=*/50);
SetScreenIdleStateAndWait(/*dimmed=*/false, /*off=*/false); SetScreenIdleStateAndWait(/*dimmed=*/false, /*off=*/false);
FastForwardToNextImage(); FastForwardTiny();
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
} }
TEST_F(AmbientControllerTest, TEST_F(AmbientControllerTest,
ShouldHideAmbientScreenWhenDisplayIsOffThenComesBackWithLockScreen) { ShouldHideAmbientScreenWhenDisplayIsOffThenComesBackWithLockScreen) {
GetSessionControllerClient()->SetShouldLockScreenAutomatically(true); GetSessionControllerClient()->SetShouldLockScreenAutomatically(true);
SetPowerStateCharging();
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
// Should not lock the device and enter ambient mode when the screen is // Should not lock the device and enter ambient mode when the screen is
// dimmed. // dimmed.
SetScreenBrightnessAndWait(/*percent=*/50); SetScreenBrightnessAndWait(/*percent=*/50);
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/false);
EXPECT_TRUE(IsLocked()); EXPECT_FALSE(IsLocked());
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(ambient_controller()->IsShown()); EXPECT_TRUE(ambient_controller()->IsShown());
FastForwardToLockScreen();
EXPECT_TRUE(IsLocked());
// Should dismiss ambient mode screen. // Should dismiss ambient mode screen.
SetScreenBrightnessAndWait(/*percent=*/0); SetScreenBrightnessAndWait(/*percent=*/0);
SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/true); SetScreenIdleStateAndWait(/*dimmed=*/true, /*off=*/true);
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
// Screen back on again, should not have ambient screen, but still has lock // Screen back on again, should not have ambient screen, but still has lock
...@@ -527,7 +540,7 @@ TEST_F(AmbientControllerTest, ...@@ -527,7 +540,7 @@ TEST_F(AmbientControllerTest,
EXPECT_FALSE(ambient_controller()->IsShown()); EXPECT_FALSE(ambient_controller()->IsShown());
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(ambient_controller()->IsShown()); EXPECT_TRUE(ambient_controller()->IsShown());
} }
...@@ -539,7 +552,7 @@ TEST_F(AmbientControllerTest, HideCursor) { ...@@ -539,7 +552,7 @@ TEST_F(AmbientControllerTest, HideCursor) {
EXPECT_TRUE(cursor_manager->IsCursorVisible()); EXPECT_TRUE(cursor_manager->IsCursorVisible());
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardToNextImage(); FastForwardTiny();
EXPECT_TRUE(container_view()); EXPECT_TRUE(container_view());
EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(), EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
namespace ash { namespace ash {
namespace {
constexpr float kFastForwardFactor = 1.0001;
} // namespace
class TestAmbientURLLoaderImpl : public AmbientURLLoader { class TestAmbientURLLoaderImpl : public AmbientURLLoader {
public: public:
...@@ -141,7 +144,7 @@ void AmbientAshTestBase::SetAmbientModeEnabled(bool enabled) { ...@@ -141,7 +144,7 @@ void AmbientAshTestBase::SetAmbientModeEnabled(bool enabled) {
void AmbientAshTestBase::ShowAmbientScreen() { void AmbientAshTestBase::ShowAmbientScreen() {
// The widget will be destroyed in |AshTestBase::TearDown()|. // The widget will be destroyed in |AshTestBase::TearDown()|.
ambient_controller()->ShowUi(AmbientUiMode::kInSessionUi); ambient_controller()->ShowUi();
// The UI only shows when images are downloaded to avoid showing blank screen. // The UI only shows when images are downloaded to avoid showing blank screen.
FastForwardToNextImage(); FastForwardToNextImage();
// Flush the message loop to finish all async calls. // Flush the message loop to finish all async calls.
...@@ -149,12 +152,11 @@ void AmbientAshTestBase::ShowAmbientScreen() { ...@@ -149,12 +152,11 @@ void AmbientAshTestBase::ShowAmbientScreen() {
} }
void AmbientAshTestBase::HideAmbientScreen() { void AmbientAshTestBase::HideAmbientScreen() {
ambient_controller()->HideLockScreenUi(); ambient_controller()->ShowHiddenUi();
} }
void AmbientAshTestBase::CloseAmbientScreen() { void AmbientAshTestBase::CloseAmbientScreen() {
ambient_controller()->ambient_ui_model()->SetUiVisibility( ambient_controller()->CloseUi();
AmbientUiVisibility::kClosed);
} }
void AmbientAshTestBase::LockScreen() { void AmbientAshTestBase::LockScreen() {
...@@ -242,11 +244,51 @@ MediaStringView* AmbientAshTestBase::GetMediaStringView() { ...@@ -242,11 +244,51 @@ MediaStringView* AmbientAshTestBase::GetMediaStringView() {
void AmbientAshTestBase::FastForwardToInactivity() { void AmbientAshTestBase::FastForwardToInactivity() {
task_environment()->FastForwardBy( task_environment()->FastForwardBy(
2 * AmbientController::kAutoShowWaitTimeInterval); kFastForwardFactor * AmbientController::kAutoShowWaitTimeInterval);
} }
void AmbientAshTestBase::FastForwardToNextImage() { void AmbientAshTestBase::FastForwardToNextImage() {
task_environment()->FastForwardBy(1.2 * kPhotoRefreshInterval); task_environment()->FastForwardBy(kFastForwardFactor * kPhotoRefreshInterval);
}
void AmbientAshTestBase::FastForwardTiny() {
// `TestAmbientURLLoaderImpl` has a small delay (1ms) to fake download delay,
// here we fake plenty of time to download the image.
task_environment()->FastForwardBy(base::TimeDelta::FromMilliseconds(10));
}
void AmbientAshTestBase::FastForwardToLockScreen() {
task_environment()->FastForwardBy(kFastForwardFactor * kLockScreenDelay);
}
void AmbientAshTestBase::SetPowerStateCharging() {
power_manager::PowerSupplyProperties proto;
proto.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_CHARGING);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_AC);
PowerStatus::Get()->SetProtoForTesting(proto);
ambient_controller()->OnPowerStatusChanged();
}
void AmbientAshTestBase::SetPowerStateDischarging() {
power_manager::PowerSupplyProperties proto;
proto.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_DISCHARGING);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
PowerStatus::Get()->SetProtoForTesting(proto);
ambient_controller()->OnPowerStatusChanged();
}
void AmbientAshTestBase::SetPowerStateFull() {
power_manager::PowerSupplyProperties proto;
proto.set_battery_state(
power_manager::PowerSupplyProperties_BatteryState_FULL);
proto.set_external_power(
power_manager::PowerSupplyProperties_ExternalPower_AC);
PowerStatus::Get()->SetProtoForTesting(proto);
ambient_controller()->OnPowerStatusChanged();
} }
void AmbientAshTestBase::FastForwardToRefreshWeather() { void AmbientAshTestBase::FastForwardToRefreshWeather() {
......
...@@ -96,9 +96,20 @@ class AmbientAshTestBase : public AshTestBase { ...@@ -96,9 +96,20 @@ class AmbientAshTestBase : public AshTestBase {
// Advance the task environment timer to load the next photo. // Advance the task environment timer to load the next photo.
void FastForwardToNextImage(); void FastForwardToNextImage();
// Advance the task environment timer a tiny amount. This is intended to
// trigger any pending async operations.
void FastForwardTiny();
// Advance the task environment timer to load the weather info. // Advance the task environment timer to load the weather info.
void FastForwardToRefreshWeather(); void FastForwardToRefreshWeather();
// Advance the task environment timer to ambient mode lock screen delay.
void FastForwardToLockScreen();
void SetPowerStateCharging();
void SetPowerStateDischarging();
void SetPowerStateFull();
// Returns the number of active wake locks of type |type|. // Returns the number of active wake locks of type |type|.
int GetNumOfActiveWakeLocks(device::mojom::WakeLockType type); int GetNumOfActiveWakeLocks(device::mojom::WakeLockType type);
......
...@@ -360,6 +360,7 @@ TEST_F(MediaStringViewTest, DoNotShowOnLockScreenIfPrefIsDisabled) { ...@@ -360,6 +360,7 @@ TEST_F(MediaStringViewTest, DoNotShowOnLockScreenIfPrefIsDisabled) {
// Simulates Ambient Mode shown on lock-screen. // Simulates Ambient Mode shown on lock-screen.
LockScreen(); LockScreen();
FastForwardToInactivity(); FastForwardToInactivity();
FastForwardTiny();
// Simulates active and playing media session. // Simulates active and playing media session.
SimulateMediaPlaybackStateChanged( SimulateMediaPlaybackStateChanged(
......
...@@ -44,13 +44,6 @@ void AmbientUiModel::SetUiVisibility(AmbientUiVisibility visibility) { ...@@ -44,13 +44,6 @@ void AmbientUiModel::SetUiVisibility(AmbientUiVisibility visibility) {
NotifyAmbientUiVisibilityChanged(); NotifyAmbientUiVisibilityChanged();
} }
void AmbientUiModel::SetUiMode(AmbientUiMode ui_mode) {
if (ui_mode_ == ui_mode)
return;
ui_mode_ = ui_mode;
}
void AmbientUiModel::NotifyAmbientUiVisibilityChanged() { void AmbientUiModel::NotifyAmbientUiVisibilityChanged() {
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnAmbientUiVisibilityChanged(ui_visibility_); observer.OnAmbientUiVisibilityChanged(ui_visibility_);
...@@ -68,4 +61,19 @@ std::ostream& operator<<(std::ostream& out, AmbientUiMode mode) { ...@@ -68,4 +61,19 @@ std::ostream& operator<<(std::ostream& out, AmbientUiMode mode) {
return out; return out;
} }
std::ostream& operator<<(std::ostream& out, AmbientUiVisibility visibility) {
switch (visibility) {
case AmbientUiVisibility::kShown:
out << "kShown";
break;
case AmbientUiVisibility::kHidden:
out << "kHidden";
break;
case AmbientUiVisibility::kClosed:
out << "kClosed";
break;
}
return out;
}
} // namespace ash } // namespace ash
...@@ -51,18 +51,12 @@ class ASH_PUBLIC_EXPORT AmbientUiModel { ...@@ -51,18 +51,12 @@ class ASH_PUBLIC_EXPORT AmbientUiModel {
// Updates current UI visibility and notifies all subscribers. // Updates current UI visibility and notifies all subscribers.
void SetUiVisibility(AmbientUiVisibility visibility); void SetUiVisibility(AmbientUiVisibility visibility);
// Updates current UI mode.
void SetUiMode(AmbientUiMode ui_mode);
AmbientUiVisibility ui_visibility() const { return ui_visibility_; } AmbientUiVisibility ui_visibility() const { return ui_visibility_; }
AmbientUiMode ui_mode() const { return ui_mode_; }
private: private:
void NotifyAmbientUiVisibilityChanged(); void NotifyAmbientUiVisibilityChanged();
AmbientUiVisibility ui_visibility_ = AmbientUiVisibility::kClosed; AmbientUiVisibility ui_visibility_ = AmbientUiVisibility::kClosed;
AmbientUiMode ui_mode_ = AmbientUiMode::kLockScreenUi;
base::ObserverList<AmbientUiModelObserver> observers_; base::ObserverList<AmbientUiModelObserver> observers_;
}; };
...@@ -70,6 +64,9 @@ class ASH_PUBLIC_EXPORT AmbientUiModel { ...@@ -70,6 +64,9 @@ class ASH_PUBLIC_EXPORT AmbientUiModel {
ASH_PUBLIC_EXPORT std::ostream& operator<<(std::ostream& out, ASH_PUBLIC_EXPORT std::ostream& operator<<(std::ostream& out,
AmbientUiMode mode); AmbientUiMode mode);
ASH_PUBLIC_EXPORT std::ostream& operator<<(std::ostream& out,
AmbientUiVisibility visibility);
} // namespace ash } // namespace ash
#endif // ASH_PUBLIC_CPP_AMBIENT_AMBIENT_UI_MODEL_H_ #endif // ASH_PUBLIC_CPP_AMBIENT_AMBIENT_UI_MODEL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment