Commit 6354c8f4 authored by Meilin Wang's avatar Meilin Wang Committed by Commit Bot

Keep display awake when ambient shown.

Bug: 159382866
Test: covered by unittests.
Change-Id: I47295da3c1aacd00b649a5175d5f01eccd8c9e66
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2253363
Commit-Queue: Meilin Wang <meilinw@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarJeroen Dhollander <jeroendh@google.com>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781404}
parent 2039c961
...@@ -2579,6 +2579,7 @@ static_library("test_support") { ...@@ -2579,6 +2579,7 @@ static_library("test_support") {
"//components/user_manager:user_manager", "//components/user_manager:user_manager",
"//components/viz/test:test_support", "//components/viz/test:test_support",
"//device/bluetooth", "//device/bluetooth",
"//services/device/public/cpp:test_support",
"//services/device/public/mojom", "//services/device/public/mojom",
"//skia", "//skia",
"//testing/gtest", "//testing/gtest",
......
...@@ -45,6 +45,9 @@ namespace { ...@@ -45,6 +45,9 @@ namespace {
constexpr base::TimeDelta kAutoShowWaitTimeInterval = constexpr base::TimeDelta kAutoShowWaitTimeInterval =
base::TimeDelta::FromSeconds(15); base::TimeDelta::FromSeconds(15);
// Used by wake lock APIs.
constexpr char kWakeLockReason[] = "AmbientMode";
void CloseAssistantUi() { void CloseAssistantUi() {
DCHECK(AssistantUiController::Get()); DCHECK(AssistantUiController::Get());
AssistantUiController::Get()->CloseUi( AssistantUiController::Get()->CloseUi(
...@@ -163,10 +166,14 @@ void AmbientController::OnAmbientUiVisibilityChanged( ...@@ -163,10 +166,14 @@ void AmbientController::OnAmbientUiVisibilityChanged(
DCHECK(container_view_); DCHECK(container_view_);
// This will be no-op if the view is already visible. // This will be no-op if the view is already visible.
container_view_->SetVisible(true); container_view_->SetVisible(true);
AcquireWakeLock();
StartRefreshingImages(); StartRefreshingImages();
break; break;
case AmbientUiVisibility::kHidden: case AmbientUiVisibility::kHidden:
container_view_->GetWidget()->Hide(); container_view_->GetWidget()->Hide();
ReleaseWakeLock();
StopRefreshingImages(); StopRefreshingImages();
// Creates the monitor and starts the auto-show timer upon hidden. // Creates the monitor and starts the auto-show timer upon hidden.
...@@ -298,6 +305,29 @@ void AmbientController::UpdateUiMode(AmbientUiMode ui_mode) { ...@@ -298,6 +305,29 @@ void AmbientController::UpdateUiMode(AmbientUiMode ui_mode) {
ambient_ui_model_.SetUiMode(ui_mode); ambient_ui_model_.SetUiMode(ui_mode);
} }
void AmbientController::AcquireWakeLock() {
if (!wake_lock_) {
mojo::Remote<device::mojom::WakeLockProvider> provider;
AmbientClient::Get()->RequestWakeLockProvider(
provider.BindNewPipeAndPassReceiver());
provider->GetWakeLockWithoutContext(
device::mojom::WakeLockType::kPreventDisplaySleep,
device::mojom::WakeLockReason::kOther, kWakeLockReason,
wake_lock_.BindNewPipeAndPassReceiver());
}
DCHECK(wake_lock_);
wake_lock_->RequestWakeLock();
VLOG(1) << "Acquired wake lock";
}
void AmbientController::ReleaseWakeLock() {
DCHECK(wake_lock_);
wake_lock_->CancelWakeLock();
VLOG(1) << "Released wake lock";
}
void AmbientController::RequestAccessToken( void AmbientController::RequestAccessToken(
AmbientAccessTokenController::AccessTokenCallback callback) { AmbientAccessTokenController::AccessTokenCallback callback) {
access_token_controller_.RequestAccessToken(std::move(callback)); access_token_controller_.RequestAccessToken(std::move(callback));
...@@ -327,6 +357,8 @@ void AmbientController::CleanUpOnClosed() { ...@@ -327,6 +357,8 @@ void AmbientController::CleanUpOnClosed() {
// Invalidates the view pointer. // Invalidates the view pointer.
container_view_ = nullptr; container_view_ = nullptr;
inactivity_monitor_.reset(); inactivity_monitor_.reset();
// Should do nothing if the wake lock has already been released.
ReleaseWakeLock();
} }
void AmbientController::StartRefreshingImages() { void AmbientController::StartRefreshingImages() {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "ash/session/session_observer.h" #include "ash/session/session_observer.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
...@@ -100,6 +102,13 @@ class ASH_EXPORT AmbientController : public AmbientUiModelObserver, ...@@ -100,6 +102,13 @@ class ASH_EXPORT AmbientController : public AmbientUiModelObserver,
void set_backend_controller_for_testing( void set_backend_controller_for_testing(
std::unique_ptr<AmbientBackendController> photo_client); std::unique_ptr<AmbientBackendController> photo_client);
// Creates (if not created) and acquires |wake_lock_|. Called when ambient
// screen starts to show.
void AcquireWakeLock();
// Release |wake_lock_|. Called when ambient screen is hidden/closed.
void ReleaseWakeLock();
AmbientPhotoController* get_ambient_photo_controller_for_testing() { AmbientPhotoController* get_ambient_photo_controller_for_testing() {
return &ambient_photo_controller_; return &ambient_photo_controller_;
} }
...@@ -121,6 +130,9 @@ class ASH_EXPORT AmbientController : public AmbientUiModelObserver, ...@@ -121,6 +130,9 @@ class ASH_EXPORT AmbientController : public AmbientUiModelObserver,
// Monitors the device inactivity and controls the auto-show of ambient. // Monitors the device inactivity and controls the auto-show of ambient.
std::unique_ptr<InactivityMonitor> inactivity_monitor_; std::unique_ptr<InactivityMonitor> inactivity_monitor_;
// Lazily initialized on the first call of |AcquireWakeLock|.
mojo::Remote<device::mojom::WakeLock> wake_lock_;
base::WeakPtrFactory<AmbientController> weak_ptr_factory_{this}; base::WeakPtrFactory<AmbientController> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(AmbientController); DISALLOW_COPY_AND_ASSIGN(AmbientController);
}; };
......
...@@ -121,4 +121,26 @@ TEST_F(AmbientControllerTest, ShouldRefreshAccessTokenAfterFailure) { ...@@ -121,4 +121,26 @@ TEST_F(AmbientControllerTest, ShouldRefreshAccessTokenAfterFailure) {
EXPECT_TRUE(IsAccessTokenRequestPending()); EXPECT_TRUE(IsAccessTokenRequestPending());
} }
TEST_F(AmbientControllerTest, CheckAcquireAndReleaseWakeLock) {
// Simulates screen lock to show ambient mode, will result in acquiring a wake
// lock.
LockScreen();
// Run loop to ensure the request has reached the wake lock provider.
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(ambient_controller()->IsShown());
EXPECT_EQ(1, GetNumOfActiveWakeLocks(
device::mojom::WakeLockType::kPreventDisplaySleep));
// Simulates user logs in to close ambient mode, will result in releasing the
// wake lock.
UnlockScreen();
// Run loop to ensure the request has reached the wake lock provider.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(ambient_controller()->IsShown());
EXPECT_EQ(0, GetNumOfActiveWakeLocks(
device::mojom::WakeLockType::kPreventDisplaySleep));
}
} // namespace ash } // namespace ash
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/ambient/ui/ambient_container_view.h" #include "ash/ambient/ui/ambient_container_view.h"
#include "ash/ambient/ui/photo_view.h" #include "ash/ambient/ui/photo_view.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "base/run_loop.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
...@@ -25,7 +26,7 @@ void AmbientAshTestBase::SetUp() { ...@@ -25,7 +26,7 @@ void AmbientAshTestBase::SetUp() {
scoped_feature_list_.InitAndEnableFeature( scoped_feature_list_.InitAndEnableFeature(
chromeos::features::kAmbientModeFeature); chromeos::features::kAmbientModeFeature);
image_downloader_ = std::make_unique<TestImageDownloader>(); image_downloader_ = std::make_unique<TestImageDownloader>();
ambient_client_ = std::make_unique<TestAmbientClient>(); ambient_client_ = std::make_unique<TestAmbientClient>(&wake_lock_provider_);
AshTestBase::SetUp(); AshTestBase::SetUp();
...@@ -67,6 +68,21 @@ const gfx::ImageSkia& AmbientAshTestBase::GetImageInPhotoView() { ...@@ -67,6 +68,21 @@ const gfx::ImageSkia& AmbientAshTestBase::GetImageInPhotoView() {
->GetCurrentImagesForTesting(); ->GetCurrentImagesForTesting();
} }
int AmbientAshTestBase::GetNumOfActiveWakeLocks(
device::mojom::WakeLockType type) {
base::RunLoop run_loop;
int result_count = 0;
wake_lock_provider_.GetActiveWakeLocksForTests(
type, base::BindOnce(
[](base::RunLoop* run_loop, int* result_count, int32_t count) {
*result_count = count;
run_loop->Quit();
},
&run_loop, &result_count));
run_loop.Run();
return result_count;
}
void AmbientAshTestBase::IssueAccessToken(const std::string& token, void AmbientAshTestBase::IssueAccessToken(const std::string& token,
bool with_error) { bool with_error) {
ambient_client_->IssueAccessToken(token, with_error); ambient_client_->IssueAccessToken(token, with_error);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "ash/public/cpp/test/test_image_downloader.h" #include "ash/public/cpp/test/test_image_downloader.h"
#include "ash/test/ash_test_base.h" #include "ash/test/ash_test_base.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "services/device/public/cpp/test/test_wake_lock_provider.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace gfx { namespace gfx {
...@@ -48,6 +49,9 @@ class AmbientAshTestBase : public AshTestBase { ...@@ -48,6 +49,9 @@ class AmbientAshTestBase : public AshTestBase {
const gfx::ImageSkia& GetImageInPhotoView(); const gfx::ImageSkia& GetImageInPhotoView();
// Returns the number of active wake locks of type |type|.
int GetNumOfActiveWakeLocks(device::mojom::WakeLockType type);
// Simulate to issue an |access_token|. // Simulate to issue an |access_token|.
// If |with_error| is true, will return an empty access token. // If |with_error| is true, will return an empty access token.
void IssueAccessToken(const std::string& access_token, bool with_error); void IssueAccessToken(const std::string& access_token, bool with_error);
...@@ -64,6 +68,8 @@ class AmbientAshTestBase : public AshTestBase { ...@@ -64,6 +68,8 @@ class AmbientAshTestBase : public AshTestBase {
private: private:
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
std::unique_ptr<TestImageDownloader> image_downloader_; std::unique_ptr<TestImageDownloader> image_downloader_;
device::TestWakeLockProvider wake_lock_provider_;
std::unique_ptr<TestAmbientClient> ambient_client_; std::unique_ptr<TestAmbientClient> ambient_client_;
std::unique_ptr<views::Widget> widget_; std::unique_ptr<views::Widget> widget_;
}; };
......
...@@ -358,6 +358,7 @@ source_set("test_support") { ...@@ -358,6 +358,7 @@ source_set("test_support") {
deps = [ deps = [
":cpp", ":cpp",
"//base", "//base",
"//services/device/public/cpp:test_support",
"//services/network/public/cpp:cpp", "//services/network/public/cpp:cpp",
"//ui/aura", "//ui/aura",
"//ui/aura:test_support", "//ui/aura:test_support",
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "ash/public/cpp/ash_public_export.h" #include "ash/public/cpp/ash_public_export.h"
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
namespace base { namespace base {
class Time; class Time;
...@@ -43,6 +44,11 @@ class ASH_PUBLIC_EXPORT AmbientClient { ...@@ -43,6 +44,11 @@ class ASH_PUBLIC_EXPORT AmbientClient {
virtual scoped_refptr<network::SharedURLLoaderFactory> virtual scoped_refptr<network::SharedURLLoaderFactory>
GetURLLoaderFactory() = 0; GetURLLoaderFactory() = 0;
// Requests a connection to the device service's |WakeLockProvider|
// from the browser.
virtual void RequestWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) = 0;
protected: protected:
AmbientClient(); AmbientClient();
AmbientClient(const AmbientClient&) = delete; AmbientClient(const AmbientClient&) = delete;
......
...@@ -20,7 +20,9 @@ constexpr base::TimeDelta kDefaultTokenExpirationDelay = ...@@ -20,7 +20,9 @@ constexpr base::TimeDelta kDefaultTokenExpirationDelay =
} // namespace } // namespace
TestAmbientClient::TestAmbientClient() = default; TestAmbientClient::TestAmbientClient(
device::TestWakeLockProvider* wake_lock_provider)
: wake_lock_provider_(wake_lock_provider) {}
TestAmbientClient::~TestAmbientClient() = default; TestAmbientClient::~TestAmbientClient() = default;
...@@ -38,6 +40,11 @@ TestAmbientClient::GetURLLoaderFactory() { ...@@ -38,6 +40,11 @@ TestAmbientClient::GetURLLoaderFactory() {
return nullptr; return nullptr;
} }
void TestAmbientClient::RequestWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) {
wake_lock_provider_->BindReceiver(std::move(receiver));
}
void TestAmbientClient::IssueAccessToken(const std::string& access_token, void TestAmbientClient::IssueAccessToken(const std::string& access_token,
bool with_error) { bool with_error) {
if (!pending_callback_) if (!pending_callback_)
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ash/public/cpp/ambient/ambient_client.h" #include "ash/public/cpp/ambient/ambient_client.h"
#include "ash/public/cpp/ash_public_export.h" #include "ash/public/cpp/ash_public_export.h"
#include "base/callback.h" #include "base/callback.h"
#include "services/device/public/cpp/test/test_wake_lock_provider.h"
namespace ash { namespace ash {
...@@ -17,13 +18,15 @@ namespace ash { ...@@ -17,13 +18,15 @@ namespace ash {
// IsAmbientModeAllowedForProfile() returns true to run the unittests. // IsAmbientModeAllowedForProfile() returns true to run the unittests.
class ASH_PUBLIC_EXPORT TestAmbientClient : public AmbientClient { class ASH_PUBLIC_EXPORT TestAmbientClient : public AmbientClient {
public: public:
TestAmbientClient(); explicit TestAmbientClient(device::TestWakeLockProvider* wake_lock_provider);
~TestAmbientClient() override; ~TestAmbientClient() override;
// AmbientClient: // AmbientClient:
bool IsAmbientModeAllowedForActiveUser() override; bool IsAmbientModeAllowedForActiveUser() override;
void RequestAccessToken(GetAccessTokenCallback callback) override; void RequestAccessToken(GetAccessTokenCallback callback) override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
void RequestWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) override;
// Simulate to issue an |access_token|. // Simulate to issue an |access_token|.
// If |with_error| is true, will return an empty access token. // If |with_error| is true, will return an empty access token.
...@@ -33,6 +36,8 @@ class ASH_PUBLIC_EXPORT TestAmbientClient : public AmbientClient { ...@@ -33,6 +36,8 @@ class ASH_PUBLIC_EXPORT TestAmbientClient : public AmbientClient {
private: private:
GetAccessTokenCallback pending_callback_; GetAccessTokenCallback pending_callback_;
device::TestWakeLockProvider* const wake_lock_provider_;
}; };
} // namespace ash } // namespace ash
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "components/signin/public/identity_manager/scope_set.h" #include "components/signin/public/identity_manager/scope_set.h"
#include "components/user_manager/user.h" #include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/browser/device_service.h"
#include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/google_service_auth_error.h"
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
...@@ -95,6 +96,11 @@ AmbientClientImpl::GetURLLoaderFactory() { ...@@ -95,6 +96,11 @@ AmbientClientImpl::GetURLLoaderFactory() {
return profile->GetURLLoaderFactory(); return profile->GetURLLoaderFactory();
} }
void AmbientClientImpl::RequestWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) {
content::GetDeviceService().BindWakeLockProvider(std::move(receiver));
}
void AmbientClientImpl::GetAccessToken( void AmbientClientImpl::GetAccessToken(
GetAccessTokenCallback callback, GetAccessTokenCallback callback,
const std::string& gaia_id, const std::string& gaia_id,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_ASH_AMBIENT_AMBIENT_CLIENT_IMPL_H_ #define CHROME_BROWSER_UI_ASH_AMBIENT_AMBIENT_CLIENT_IMPL_H_
#include <memory> #include <memory>
#include <string>
#include "ash/public/cpp/ambient/ambient_client.h" #include "ash/public/cpp/ambient/ambient_client.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -27,6 +28,8 @@ class AmbientClientImpl : public ash::AmbientClient { ...@@ -27,6 +28,8 @@ class AmbientClientImpl : public ash::AmbientClient {
bool IsAmbientModeAllowedForActiveUser() override; bool IsAmbientModeAllowedForActiveUser() override;
void RequestAccessToken(GetAccessTokenCallback callback) override; void RequestAccessToken(GetAccessTokenCallback callback) override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
void RequestWakeLockProvider(
mojo::PendingReceiver<device::mojom::WakeLockProvider> receiver) override;
private: private:
void GetAccessToken(GetAccessTokenCallback callback, void GetAccessToken(GetAccessTokenCallback callback,
......
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