Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afb45844 authored by Ana Krulec's avatar Ana Krulec
Browse files

SF: Adding testable Scheduler and updating tests.

This follows ag/6337080 for clearity

Test: updating tests.
Bug: 123998711
Change-Id: I8999b3a1f002a9f5fb705e7de61294e9bc094298
parent c2870424
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ protected:
            impl::EventThread::InterceptVSyncsCallback interceptCallback);

private:
    friend class TestableScheduler;

    // Creates a connection on the given EventThread and forwards the given callbacks.
    sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&);

+16 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "ColorLayer.h"
#include "Layer.h"

#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDispSync.h"
@@ -90,11 +91,9 @@ public:
                ::testing::UnitTest::GetInstance()->current_test_info();
        ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());

        mFlinger.mutableEventControlThread().reset(mEventControlThread);
        mFlinger.mutableEventThread().reset(mEventThread);
        mFlinger.mutableEventQueue().reset(mMessageQueue);
        setupScheduler();

        mFlinger.mutablePrimaryDispSync().reset(mPrimaryDispSync);
        EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
        EXPECT_CALL(*mPrimaryDispSync, getPeriod())
                .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
@@ -124,6 +123,18 @@ public:
        Mock::VerifyAndClear(mComposer);
    }

    void setupScheduler() {
        mScheduler = new TestableScheduler();
        mScheduler->mutableEventControlThread().reset(mEventControlThread);
        mScheduler->mutablePrimaryDispSync().reset(mPrimaryDispSync);
        EXPECT_CALL(*mEventThread.get(), registerDisplayEventConnection(_));
        sp<Scheduler::ConnectionHandle> connectionHandle =
                mScheduler->addConnection(std::move(mEventThread));
        mFlinger.mutableSfConnectionHandle() = std::move(connectionHandle);

        mFlinger.mutableScheduler().reset(mScheduler);
    }

    void setupForceGeometryDirty() {
        // TODO: This requires the visible region and other related
        // state to be set, and is problematic for BufferLayers since they are
@@ -145,6 +156,7 @@ public:

    std::unordered_set<HWC2::Capability> mDefaultCapabilities = {HWC2::Capability::SidebandStream};

    TestableScheduler* mScheduler;
    TestableSurfaceFlinger mFlinger;
    sp<DisplayDevice> mDisplay;
    sp<DisplayDevice> mExternalDisplay;
@@ -155,7 +167,7 @@ public:
    sp<GraphicBuffer> mBuffer = new GraphicBuffer();
    ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();

    mock::EventThread* mEventThread = new mock::EventThread();
    std::unique_ptr<mock::EventThread> mEventThread = std::make_unique<mock::EventThread>();
    mock::EventControlThread* mEventControlThread = new mock::EventControlThread();

    Hwc2::mock::Composer* mComposer = nullptr;
+26 −10
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <ui/DebugUtils.h>

#include "DisplayIdentificationTest.h"
#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDispSync.h"
@@ -94,6 +95,8 @@ public:
    DisplayTransactionTest();
    ~DisplayTransactionTest() override;

    void setupScheduler();

    // --------------------------------------------------------------------
    // Mock/Fake injection

@@ -116,6 +119,7 @@ public:
    // --------------------------------------------------------------------
    // Test instances

    TestableScheduler* mScheduler;
    TestableSurfaceFlinger mFlinger;
    mock::EventThread* mEventThread = new mock::EventThread();
    mock::EventThread* mSFEventThread = new mock::EventThread();
@@ -160,13 +164,10 @@ DisplayTransactionTest::DisplayTransactionTest() {
        return nullptr;
    });

    mFlinger.mutableEventControlThread().reset(mEventControlThread);
    mFlinger.mutableEventThread().reset(mEventThread);
    mFlinger.mutableSFEventThread().reset(mSFEventThread);
    setupScheduler();
    mFlinger.mutableEventQueue().reset(mMessageQueue);
    mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
    mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
    mFlinger.mutablePrimaryDispSync().reset(mPrimaryDispSync);

    injectMockComposer(0);
}
@@ -177,6 +178,22 @@ DisplayTransactionTest::~DisplayTransactionTest() {
    ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}

void DisplayTransactionTest::setupScheduler() {
    mScheduler = new TestableScheduler();
    mScheduler->mutableEventControlThread().reset(mEventControlThread);
    mScheduler->mutablePrimaryDispSync().reset(mPrimaryDispSync);
    EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_));
    EXPECT_CALL(*mSFEventThread, registerDisplayEventConnection(_));

    sp<Scheduler::ConnectionHandle> sfConnectionHandle =
            mScheduler->addConnection(std::unique_ptr<EventThread>(mSFEventThread));
    mFlinger.mutableSfConnectionHandle() = std::move(sfConnectionHandle);
    sp<Scheduler::ConnectionHandle> appConnectionHandle =
            mScheduler->addConnection(std::unique_ptr<EventThread>(mEventThread));
    mFlinger.mutableAppConnectionHandle() = std::move(appConnectionHandle);
    mFlinger.mutableScheduler().reset(mScheduler);
}

void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
    mComposer = new Hwc2::mock::Composer();
    EXPECT_CALL(*mComposer, getCapabilities())
@@ -1106,8 +1123,8 @@ TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
    // Preconditions

    // vsync is enabled and available
    mFlinger.mutablePrimaryHWVsyncEnabled() = true;
    mFlinger.mutableHWVsyncAvailable() = true;
    mScheduler->mutablePrimaryHWVsyncEnabled() = true;
    mScheduler->mutableHWVsyncAvailable() = true;

    // A display exists
    auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
@@ -1131,8 +1148,8 @@ TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
    // Postconditions

    // vsyncs should be off and not available.
    EXPECT_FALSE(mFlinger.mutablePrimaryHWVsyncEnabled());
    EXPECT_FALSE(mFlinger.mutableHWVsyncAvailable());
    EXPECT_FALSE(mScheduler->mutablePrimaryHWVsyncEnabled());
    EXPECT_FALSE(mScheduler->mutableHWVsyncAvailable());

    // The display should have been removed from the display map.
    EXPECT_FALSE(hasDisplayDevice(existing.token()));
@@ -1557,7 +1574,6 @@ void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessin
    Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);

    EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);

    expectHotplugReceived<Case, true>(mEventThread);
    expectHotplugReceived<Case, true>(mSFEventThread);
}
@@ -3008,7 +3024,7 @@ struct DisplayPowerCase {
    }

    static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
        test->mFlinger.mutablePrimaryHWVsyncEnabled() = enabled;
        test->mScheduler->mutablePrimaryHWVsyncEnabled() = enabled;
    }

    static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
+65 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#pragma once

#include <gmock/gmock.h>

#include "Scheduler/EventThread.h"
#include "Scheduler/Scheduler.h"

namespace android {

class TestableScheduler : public Scheduler {
public:
    TestableScheduler() : Scheduler([](bool) {}) {}

    // Creates EventThreadConnection with the given eventThread. Creates Scheduler::Connection
    // and adds it to the list of connectins. Returns the ConnectionHandle for the
    // Scheduler::Connection. This allows plugging in mock::EventThread.
    sp<Scheduler::ConnectionHandle> addConnection(std::unique_ptr<EventThread> eventThread) {
        sp<EventThreadConnection> eventThreadConnection =
                new EventThreadConnection(eventThread.get(), ResyncCallback(),
                                          ResetIdleTimerCallback());
        const int64_t id = sNextId++;
        mConnections.emplace(id,
                             std::make_unique<Scheduler::Connection>(new ConnectionHandle(id),
                                                                     eventThreadConnection,
                                                                     std::move(eventThread)));
        return mConnections[id]->handle;
    }

    /* ------------------------------------------------------------------------
     * Read-write access to private data to set up preconditions and assert
     * post-conditions.
     */
    auto& mutablePrimaryHWVsyncEnabled() { return mPrimaryHWVsyncEnabled; }
    auto& mutableEventControlThread() { return mEventControlThread; }
    auto& mutablePrimaryDispSync() { return mPrimaryDispSync; }
    auto& mutableHWVsyncAvailable() { return mHWVsyncAvailable; }

    ~TestableScheduler() {
        // All these pointer and container clears help ensure that GMock does
        // not report a leaked object, since the Scheduler instance may
        // still be referenced by something despite our best efforts to destroy
        // it after each test is done.
        mutableEventControlThread().reset();
        mutablePrimaryDispSync().reset();
        mConnections.clear();
    };
};

} // namespace android
+4 −11
Original line number Diff line number Diff line
@@ -299,7 +299,6 @@ public:

    const auto& getAnimFrameTracker() const { return mFlinger->mAnimFrameTracker; }
    const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; }
    const auto& getHWVsyncAvailable() const { return mFlinger->mHWVsyncAvailable; }
    const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; }
    auto& getHwComposer() const {
        return static_cast<impl::HWComposer&>(mFlinger->getHwComposer());
@@ -320,18 +319,12 @@ public:
    auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
    auto& mutableDisplays() { return mFlinger->mDisplays; }
    auto& mutableDrawingState() { return mFlinger->mDrawingState; }
    auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
    auto& mutableEventQueue() { return mFlinger->mEventQueue; }
    auto& mutableEventThread() { return mFlinger->mEventThread; }
    auto& mutableSFEventThread() { return mFlinger->mSFEventThread; }
    auto& mutableGeometryInvalid() { return mFlinger->mGeometryInvalid; }
    auto& mutableHWVsyncAvailable() { return mFlinger->mHWVsyncAvailable; }
    auto& mutableInterceptor() { return mFlinger->mInterceptor; }
    auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
    auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
    auto& mutablePhysicalDisplayTokens() { return mFlinger->mPhysicalDisplayTokens; }
    auto& mutablePrimaryDispSync() { return mFlinger->mPrimaryDispSync; }
    auto& mutablePrimaryHWVsyncEnabled() { return mFlinger->mPrimaryHWVsyncEnabled; }
    auto& mutableTexturePool() { return mFlinger->mTexturePool; }
    auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
    auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
@@ -341,6 +334,9 @@ public:
    auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
    auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; }
    auto& mutableExternalHwcDisplayId() { return getHwComposer().mExternalHwcDisplayId; }
    auto& mutableScheduler() { return mFlinger->mScheduler; }
    auto& mutableAppConnectionHandle() { return mFlinger->mAppConnectionHandle; }
    auto& mutableSfConnectionHandle() { return mFlinger->mSfConnectionHandle; }

    ~TestableSurfaceFlinger() {
        // All these pointer and container clears help ensure that GMock does
@@ -348,12 +344,9 @@ public:
        // still be referenced by something despite our best efforts to destroy
        // it after each test is done.
        mutableDisplays().clear();
        mutableEventControlThread().reset();
        mutableEventQueue().reset();
        mutableEventThread().reset();
        mutableSFEventThread().reset();
        mutableInterceptor().reset();
        mutablePrimaryDispSync().reset();
        mutableScheduler().reset();
        mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
        mFlinger->mCompositionEngine->setRenderEngine(
                std::unique_ptr<renderengine::RenderEngine>());