blob: 58818d16c36227e4e20f939921d38846b24ba0fe [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "src/ui/bin/root_presenter/factory_reset_manager.h"
#include <fuchsia/recovery/cpp/fidl_test_base.h>
#include <lib/async/time.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <zircon/status.h>
#include <gtest/gtest.h>
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
namespace root_presenter {
namespace testing {
class FakeFactoryReset : public fuchsia::recovery::testing::FactoryReset_TestBase {
public:
void NotImplemented_(const std::string& name) final {}
fidl::InterfaceRequestHandler<fuchsia::recovery::FactoryReset> GetHandler(
async_dispatcher_t* dispatcher = nullptr) {
return [this, dispatcher](fidl::InterfaceRequest<fuchsia::recovery::FactoryReset> request) {
bindings_.AddBinding(this, std::move(request), dispatcher);
};
}
void Reset(ResetCallback callback) override {
callback(ZX_OK);
triggered_ = true;
}
bool triggered() const { return triggered_; }
private:
bool triggered_ = false;
fidl::BindingSet<fuchsia::recovery::FactoryReset> bindings_;
};
class FactoryResetManagerTest : public gtest::TestLoopFixture {
public:
FactoryResetManagerTest() : factory_reset_manager_(*context_provider_.context()) {
context_provider_.service_directory_provider()->AddService(factory_reset_.GetHandler());
}
bool triggered() const { return factory_reset_.triggered(); }
protected:
sys::testing::ComponentContextProvider context_provider_;
FactoryResetManager factory_reset_manager_;
FakeFactoryReset factory_reset_;
};
TEST_F(FactoryResetManagerTest, FactoryResetButtonPressedAndReleased) {
EXPECT_FALSE(factory_reset_manager_.countdown_started());
fuchsia::ui::input::MediaButtonsReport report;
report.reset = true;
factory_reset_manager_.OnMediaButtonReport(report);
EXPECT_TRUE(factory_reset_manager_.countdown_started());
// Factory reset should cancel if the button is released.
report.reset = false;
factory_reset_manager_.OnMediaButtonReport(report);
EXPECT_FALSE(factory_reset_manager_.countdown_started());
RunLoopFor(kCountdownDuration);
RunLoopUntilIdle();
EXPECT_FALSE(triggered());
}
TEST_F(FactoryResetManagerTest, FactoryResetButtonHeldAndTrigger) {
EXPECT_FALSE(factory_reset_manager_.countdown_started());
fuchsia::ui::input::MediaButtonsReport report;
report.reset = true;
factory_reset_manager_.OnMediaButtonReport(report);
EXPECT_TRUE(factory_reset_manager_.countdown_started());
RunLoopFor(kCountdownDuration);
RunLoopUntilIdle();
EXPECT_TRUE(triggered());
}
TEST_F(FactoryResetManagerTest, WatchHandler) {
const int scheduled_reset_time = 200;
fuchsia::recovery::ui::FactoryResetCountdownState inputState;
fuchsia::recovery::ui::FactoryResetCountdownState outputState;
FactoryResetManager::WatchHandler watchHandler(inputState);
bool watchReturned = false;
auto watchCallback =
[&outputState, &watchReturned](fuchsia::recovery::ui::FactoryResetCountdownState newState) {
watchReturned = true;
newState.Clone(&outputState);
};
watchHandler.Watch(watchCallback);
// Initial watch should return immediately, with no scheduled reset.
EXPECT_TRUE(watchReturned);
EXPECT_FALSE(outputState.has_scheduled_reset_time());
watchReturned = false;
watchHandler.Watch(watchCallback);
// Subsequent watch should hang until state changes.
EXPECT_FALSE(watchReturned);
inputState.set_scheduled_reset_time(scheduled_reset_time);
watchHandler.OnStateChange(inputState);
// On the state change, the watch should return with the new scheduled reset time.
EXPECT_TRUE(watchReturned);
EXPECT_TRUE(outputState.has_scheduled_reset_time());
EXPECT_EQ(outputState.scheduled_reset_time(), scheduled_reset_time);
watchReturned = false;
inputState.clear_scheduled_reset_time();
watchHandler.OnStateChange(inputState);
watchHandler.Watch(watchCallback);
// When state changes before watch is called, watch should return immediately.
EXPECT_TRUE(watchReturned);
EXPECT_FALSE(outputState.has_scheduled_reset_time());
}
} // namespace testing
} // namespace root_presenter