blob: 596aceeeb168992b25c0690985cc5389ab3db249 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/wake_lock/arc_wake_lock_bridge.h"
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "components/arc/common/power.mojom.h"
#include "components/arc/session/arc_bridge_service.h"
#include "components/arc/test/connection_holder_util.h"
#include "components/arc/test/fake_power_instance.h"
#include "components/arc/test/fake_wake_lock_instance.h"
#include "services/device/public/cpp/test/test_wake_lock_provider.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace arc {
using device::mojom::WakeLockType;
class ArcWakeLockBridgeTest : public testing::Test {
public:
ArcWakeLockBridgeTest()
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
wake_lock_provider_(
connector_factory_.RegisterInstance(device::mojom::kServiceName)) {
bridge_service_ = std::make_unique<ArcBridgeService>();
wake_lock_bridge_ =
std::make_unique<ArcWakeLockBridge>(nullptr, bridge_service_.get());
wake_lock_bridge_->set_connector_for_testing(
connector_factory_.GetDefaultConnector());
CreateWakeLockInstance();
}
~ArcWakeLockBridgeTest() override { DestroyWakeLockInstance(); }
protected:
// Returns true iff there is no failure acquiring a system wake lock.
bool AcquirePartialWakeLock() {
base::RunLoop loop;
bool result = false;
wake_lock_bridge_->AcquirePartialWakeLock(base::BindOnce(
[](bool* result_out, bool result) { *result_out = result; }, &result));
loop.RunUntilIdle();
wake_lock_bridge_->FlushWakeLocksForTesting();
return result;
}
// Returns true iff there is no failure releasing a system wake lock.
bool ReleasePartialWakeLock() {
base::RunLoop loop;
bool result = false;
wake_lock_bridge_->ReleasePartialWakeLock(base::BindOnce(
[](bool* result_out, bool result) { *result_out = result; }, &result));
loop.RunUntilIdle();
wake_lock_bridge_->FlushWakeLocksForTesting();
return result;
}
// Creates a FakeWakeLockInstance for |bridge_service_|. This results in
// ArcWakeLockBridge::OnInstanceReady() being called.
void CreateWakeLockInstance() {
instance_ = std::make_unique<FakeWakeLockInstance>();
bridge_service_->wake_lock()->SetInstance(instance_.get());
WaitForInstanceReady(bridge_service_->wake_lock());
}
// Destroys the FakeWakeLockInstance. This results in
// ArcWakeLockBridge::OnInstanceClosed() being called.
void DestroyWakeLockInstance() {
if (!instance_)
return;
bridge_service_->wake_lock()->CloseInstance(instance_.get());
instance_.reset();
}
// Returns the number of active wake locks of type |type|.
int GetActiveWakeLocks(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;
}
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
service_manager::TestConnectorFactory connector_factory_;
device::TestWakeLockProvider wake_lock_provider_;
std::unique_ptr<ArcBridgeService> bridge_service_;
std::unique_ptr<FakeWakeLockInstance> instance_;
std::unique_ptr<ArcWakeLockBridge> wake_lock_bridge_;
DISALLOW_COPY_AND_ASSIGN(ArcWakeLockBridgeTest);
};
TEST_F(ArcWakeLockBridgeTest, AcquireAndReleaseSinglePartialWakeLock) {
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
EXPECT_TRUE(ReleasePartialWakeLock());
EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
}
TEST_F(ArcWakeLockBridgeTest, AcquireAndReleaseMultiplePartialWakeLocks) {
// Taking multiple wake locks should result in only one active wake lock.
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
// Releasing two wake locks after acquiring three should not result in
// releasing a wake lock.
EXPECT_TRUE(ReleasePartialWakeLock());
EXPECT_TRUE(ReleasePartialWakeLock());
EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
// Releasing the remaining wake lock should result in the release of the wake
// lock.
EXPECT_TRUE(ReleasePartialWakeLock());
EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
}
TEST_F(ArcWakeLockBridgeTest, ReleaseWakeLockOnInstanceClosed) {
EXPECT_TRUE(AcquirePartialWakeLock());
ASSERT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
// If the instance is closed, all wake locks should be released.
base::RunLoop run_loop;
DestroyWakeLockInstance();
run_loop.RunUntilIdle();
EXPECT_EQ(0, GetActiveWakeLocks(WakeLockType::kPreventDisplaySleep));
// Check that wake locks can be requested after the instance becomes ready
// again.
CreateWakeLockInstance();
EXPECT_TRUE(AcquirePartialWakeLock());
EXPECT_EQ(1, GetActiveWakeLocks(WakeLockType::kPreventAppSuspension));
}
} // namespace arc