blob: b73a85404fa588ef0ea54390a57dada9a92350f8 [file] [log] [blame]
// Copyright 2015 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 "platform/scheduler/renderer/render_widget_signals.h"
#include "base/macros.h"
#include "public/platform/scheduler/render_widget_scheduling_state.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::AnyNumber;
using testing::Mock;
using testing::_;
namespace blink {
namespace scheduler {
// To avoid symbol collisions in jumbo builds.
namespace render_widget_signals_unittest {
class MockObserver : public RenderWidgetSignals::Observer {
public:
MockObserver() = default;
virtual ~MockObserver() = default;
MOCK_METHOD1(SetAllRenderWidgetsHidden, void(bool hidden));
MOCK_METHOD1(SetHasVisibleRenderWidgetWithTouchHandler,
void(bool has_visible_render_widget_with_touch_handler));
private:
DISALLOW_COPY_AND_ASSIGN(MockObserver);
};
class RenderWidgetSignalsTest : public testing::Test {
public:
RenderWidgetSignalsTest() = default;
~RenderWidgetSignalsTest() override = default;
void SetUp() override {
mock_observer_.reset(new MockObserver());
render_widget_signals_.reset(new RenderWidgetSignals(mock_observer_.get()));
}
void IgnoreWidgetCreationCallbacks() {
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(false))
.Times(AnyNumber());
}
void IgnoreWidgetDestructionCallbacks() {
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true))
.Times(AnyNumber());
}
std::unique_ptr<MockObserver> mock_observer_;
std::unique_ptr<RenderWidgetSignals> render_widget_signals_;
};
TEST_F(RenderWidgetSignalsTest, RenderWidgetSchedulingStateLifeCycle) {
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(false)).Times(1);
std::unique_ptr<RenderWidgetSchedulingState> widget1_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true)).Times(1);
}
TEST_F(RenderWidgetSignalsTest, RenderWidget_Hidden) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget1_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true)).Times(1);
widget1_state->SetHidden(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest, RenderWidget_HiddenThreeTimesShownOnce) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget1_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true)).Times(1);
widget1_state->SetHidden(true);
widget1_state->SetHidden(true);
widget1_state->SetHidden(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(false)).Times(1);
widget1_state->SetHidden(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest, MultipleRenderWidgetsBecomeHiddenThenVisible) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget1_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
std::unique_ptr<RenderWidgetSchedulingState> widget2_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
std::unique_ptr<RenderWidgetSchedulingState> widget3_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
// Widgets are initially assumed to be visible so start hiding them, we should
// not get any calls to SetAllRenderWidgetsHidden till the last one is hidden.
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(_)).Times(0);
widget1_state->SetHidden(true);
widget2_state->SetHidden(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true)).Times(1);
widget3_state->SetHidden(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
// We should get a call back once the first widget is unhidden and no more
// after that.
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(false)).Times(1);
widget1_state->SetHidden(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(_)).Times(0);
widget2_state->SetHidden(false);
widget3_state->SetHidden(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest, TouchHandlerAddedAndRemoved_VisibleWidget) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(true))
.Times(1);
widget_state->SetHasTouchHandler(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(false))
.Times(1);
widget_state->SetHasTouchHandler(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest,
TouchHandlerAddedThriceAndRemovedOnce_VisibleWidget) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(true))
.Times(1);
widget_state->SetHasTouchHandler(true);
widget_state->SetHasTouchHandler(true);
widget_state->SetHasTouchHandler(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(false))
.Times(1);
widget_state->SetHasTouchHandler(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest, TouchHandlerAddedAndRemoved_HiddenWidget) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true)).Times(1);
widget_state->SetHidden(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(_))
.Times(0);
widget_state->SetHasTouchHandler(true);
widget_state->SetHasTouchHandler(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest,
MultipleTouchHandlerAddedAndRemoved_VisibleWidgets) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget1_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
std::unique_ptr<RenderWidgetSchedulingState> widget2_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
std::unique_ptr<RenderWidgetSchedulingState> widget3_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
// We should only get a callback for the first widget with a touch handler.
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(true))
.Times(1);
widget1_state->SetHasTouchHandler(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(_))
.Times(0);
widget2_state->SetHasTouchHandler(true);
widget3_state->SetHasTouchHandler(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
// We should only get a callback when the last touch handler is removed.
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(_))
.Times(0);
widget1_state->SetHasTouchHandler(false);
widget2_state->SetHasTouchHandler(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(false))
.Times(1);
widget3_state->SetHasTouchHandler(false);
Mock::VerifyAndClearExpectations(mock_observer_.get());
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest,
TouchHandlerAddedThenWigetDeleted_VisibleWidget) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(true))
.Times(1);
widget_state->SetHasTouchHandler(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(false))
.Times(1);
IgnoreWidgetDestructionCallbacks();
}
TEST_F(RenderWidgetSignalsTest,
TouchHandlerAddedThenWigetDeleted_HiddenWidget) {
IgnoreWidgetCreationCallbacks();
std::unique_ptr<RenderWidgetSchedulingState> widget_state =
render_widget_signals_->NewRenderWidgetSchedulingState();
EXPECT_CALL(*mock_observer_, SetAllRenderWidgetsHidden(true)).Times(1);
widget_state->SetHidden(true);
Mock::VerifyAndClearExpectations(mock_observer_.get());
EXPECT_CALL(*mock_observer_, SetHasVisibleRenderWidgetWithTouchHandler(_))
.Times(0);
IgnoreWidgetDestructionCallbacks();
}
} // namespace render_widget_signals_unittest
} // namespace scheduler
} // namespace blink