/* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef LOG_TAG #define LOG_TAG "LibSurfaceFlingerUnittests" #define LOG_NDEBUG 0 #include <inttypes.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <log/log.h> #include "AsyncCallRecorder.h" #include "Scheduler/DispSyncSource.h" #include "mock/MockDispSync.h" namespace android { namespace { using namespace std::chrono_literals; using testing::Return; class DispSyncSourceTest : public testing::Test, private VSyncSource::Callback { protected: DispSyncSourceTest(); ~DispSyncSourceTest() override; void createDispSync(); void createDispSyncSource(); void onVSyncEvent(nsecs_t when) override; std::unique_ptr<mock::DispSync> mDispSync; std::unique_ptr<DispSyncSource> mDispSyncSource; AsyncCallRecorder<void (*)(nsecs_t)> mVSyncEventCallRecorder; static constexpr std::chrono::nanoseconds mPhaseOffset = 6ms; static constexpr int mIterations = 100; }; DispSyncSourceTest::DispSyncSourceTest() { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); } DispSyncSourceTest::~DispSyncSourceTest() { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); } void DispSyncSourceTest::onVSyncEvent(nsecs_t when) { ALOGD("onVSyncEvent: %" PRId64, when); mVSyncEventCallRecorder.recordCall(when); } void DispSyncSourceTest::createDispSync() { mDispSync = std::make_unique<mock::DispSync>(); } void DispSyncSourceTest::createDispSyncSource() { createDispSync(); mDispSyncSource = std::make_unique<DispSyncSource>(mDispSync.get(), mPhaseOffset.count(), true, "DispSyncSourceTest"); mDispSyncSource->setCallback(this); } /* ------------------------------------------------------------------------ * Test cases */ TEST_F(DispSyncSourceTest, createDispSync) { createDispSync(); EXPECT_TRUE(mDispSync); } TEST_F(DispSyncSourceTest, createDispSyncSource) { createDispSyncSource(); EXPECT_TRUE(mDispSyncSource); } TEST_F(DispSyncSourceTest, noCallbackAfterInit) { createDispSyncSource(); EXPECT_TRUE(mDispSyncSource); // DispSyncSource starts with Vsync disabled mDispSync->triggerCallback(); EXPECT_FALSE(mVSyncEventCallRecorder.waitForUnexpectedCall().has_value()); } TEST_F(DispSyncSourceTest, waitForCallbacks) { createDispSyncSource(); EXPECT_TRUE(mDispSyncSource); mDispSyncSource->setVSyncEnabled(true); EXPECT_EQ(mDispSync->getCallbackPhase(), mPhaseOffset.count()); for (int i = 0; i < mIterations; i++) { mDispSync->triggerCallback(); EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value()); } } TEST_F(DispSyncSourceTest, waitForCallbacksWithPhaseChange) { createDispSyncSource(); EXPECT_TRUE(mDispSyncSource); mDispSyncSource->setVSyncEnabled(true); EXPECT_EQ(mDispSync->getCallbackPhase(), mPhaseOffset.count()); for (int i = 0; i < mIterations; i++) { mDispSync->triggerCallback(); EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value()); } EXPECT_CALL(*mDispSync, getPeriod()).Times(1).WillOnce(Return(16666666)); mDispSyncSource->setPhaseOffset((mPhaseOffset / 2).count()); EXPECT_EQ(mDispSync->getCallbackPhase(), (mPhaseOffset / 2).count()); for (int i = 0; i < mIterations; i++) { mDispSync->triggerCallback(); EXPECT_TRUE(mVSyncEventCallRecorder.waitForCall().has_value()); } } } // namespace } // namespace android