diff options
25 files changed, 0 insertions, 4012 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 694bc5af5b..81b4d3d85f 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -2237,18 +2237,6 @@ status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token, // ---------------------------------------------------------------------------- -status_t SurfaceComposerClient::enableVSyncInjections(bool enable) { - sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService()); - binder::Status status = sf->enableVSyncInjections(enable); - return statusTFromBinderStatus(status); -} - -status_t SurfaceComposerClient::injectVSync(nsecs_t when) { - sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService()); - binder::Status status = sf->injectVSync(when); - return statusTFromBinderStatus(status); -} - status_t SurfaceComposerClient::getDisplayState(const sp<IBinder>& display, ui::DisplayState* state) { gui::DisplayState ds; diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index ac1442b73e..ca0b97f8db 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -224,10 +224,6 @@ interface ISurfaceComposer { */ PullAtomData onPullAtom(int atomId); - oneway void enableVSyncInjections(boolean enable); - - oneway void injectVSync(long when); - /** * Gets the list of active layers in Z order for debugging purposes * diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h index 433b04469b..315b92503f 100644 --- a/libs/gui/fuzzer/libgui_fuzzer_utils.h +++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h @@ -102,8 +102,6 @@ public: MOCK_METHOD(binder::Status, overrideHdrTypes, (const sp<IBinder>&, const std::vector<int32_t>&), (override)); MOCK_METHOD(binder::Status, onPullAtom, (int32_t, gui::PullAtomData*), (override)); - MOCK_METHOD(binder::Status, enableVSyncInjections, (bool), (override)); - MOCK_METHOD(binder::Status, injectVSync, (int64_t), (override)); MOCK_METHOD(binder::Status, getLayerDebugInfo, (std::vector<gui::LayerDebugInfo>*), (override)); MOCK_METHOD(binder::Status, getColorManagement, (bool*), (override)); MOCK_METHOD(binder::Status, getCompositionPreference, (gui::CompositionPreference*), diff --git a/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp b/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp index 5bd65316dd..eecbe0fe21 100644 --- a/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp +++ b/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp @@ -271,10 +271,6 @@ void SurfaceComposerClientFuzzer::invokeSurfaceComposerClient() { sp<Surface> surfaceParent( new Surface(producer, mFdp.ConsumeBool() /*controlledByApp*/, handle)); - SurfaceComposerClient::enableVSyncInjections(mFdp.ConsumeBool() /*secure*/); - nsecs_t when = mFdp.ConsumeIntegral<uint32_t>(); - SurfaceComposerClient::injectVSync(when); - fuzzOnPullAtom(); SurfaceComposerClient::setDisplayContentSamplingEnabled(displayToken, mFdp.ConsumeBool() /*enable*/, diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 04d3ab252d..d138d6832b 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -358,10 +358,6 @@ public: //! Get token for a physical display given its stable ID static sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId); - static status_t enableVSyncInjections(bool enable); - - static status_t injectVSync(nsecs_t when); - struct SCHash { std::size_t operator()(const sp<SurfaceControl>& sc) const { return std::hash<SurfaceControl *>{}(sc.get()); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index d5cc55f7fd..72d76ee99c 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -851,10 +851,6 @@ public: return binder::Status::ok(); } - binder::Status enableVSyncInjections(bool /*enable*/) override { return binder::Status::ok(); } - - binder::Status injectVSync(int64_t /*when*/) override { return binder::Status::ok(); } - binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* /*outLayers*/) override { return binder::Status::ok(); } diff --git a/services/surfaceflinger/Scheduler/InjectVSyncSource.h b/services/surfaceflinger/Scheduler/InjectVSyncSource.h deleted file mode 100644 index 760a4ee886..0000000000 --- a/services/surfaceflinger/Scheduler/InjectVSyncSource.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2018 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 <mutex> - -#include "EventThread.h" - -namespace android { - -/** - * VSync signals used during SurfaceFlinger trace playback (traces we captured - * with SurfaceInterceptor). - */ -class InjectVSyncSource final : public VSyncSource { -public: - ~InjectVSyncSource() override = default; - - void setCallback(VSyncSource::Callback* callback) override { - std::lock_guard<std::mutex> lock(mCallbackMutex); - mCallback = callback; - } - - void onInjectSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp, - nsecs_t deadlineTimestamp) { - std::lock_guard<std::mutex> lock(mCallbackMutex); - if (mCallback) { - mCallback->onVSyncEvent(when, {expectedVSyncTimestamp, deadlineTimestamp}); - } - } - - const char* getName() const override { return "inject"; } - void setVSyncEnabled(bool) override {} - void setDuration(std::chrono::nanoseconds, std::chrono::nanoseconds) override {} - VSyncData getLatestVSyncData() const override { return {}; } - void dump(std::string&) const override {} - -private: - std::mutex mCallbackMutex; - VSyncSource::Callback* mCallback GUARDED_BY(mCallbackMutex) = nullptr; -}; - -} // namespace android diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp index e4e65b4828..ae10ff4989 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.cpp +++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp @@ -57,37 +57,6 @@ MessageQueue::MessageQueue(ICompositor& compositor, sp<Handler> handler) mLooper(sp<Looper>::make(kAllowNonCallbacks)), mHandler(std::move(handler)) {} -// TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly -// and remove the EventThread from MessageQueue -void MessageQueue::setInjector(sp<EventThreadConnection> connection) { - auto& tube = mInjector.tube; - - if (const int fd = tube.getFd(); fd >= 0) { - mLooper->removeFd(fd); - } - - if (connection) { - // The EventThreadConnection is retained when disabling injection, so avoid subsequently - // stealing invalid FDs. Note that the stolen FDs are kept open. - if (tube.getFd() < 0) { - connection->stealReceiveChannel(&tube); - } else { - ALOGW("Recycling channel for VSYNC injection."); - } - - mLooper->addFd( - tube.getFd(), 0, Looper::EVENT_INPUT, - [](int, int, void* data) { - reinterpret_cast<MessageQueue*>(data)->injectorCallback(); - return 1; // Keep registration. - }, - this); - } - - std::lock_guard lock(mInjector.mutex); - mInjector.connection = std::move(connection); -} - void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) { ATRACE_CALL(); // Trace VSYNC-sf @@ -174,15 +143,6 @@ void MessageQueue::scheduleConfigure() { void MessageQueue::scheduleFrame() { ATRACE_CALL(); - { - std::lock_guard lock(mInjector.mutex); - if (CC_UNLIKELY(mInjector.connection)) { - ALOGD("%s while injecting VSYNC", __func__); - mInjector.connection->requestNextVsync(); - return; - } - } - std::lock_guard lock(mVsync.mutex); mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), @@ -190,22 +150,6 @@ void MessageQueue::scheduleFrame() { .earliestVsync = mVsync.lastCallbackTime.ns()}); } -void MessageQueue::injectorCallback() { - ssize_t n; - DisplayEventReceiver::Event buffer[8]; - while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) { - for (int i = 0; i < n; i++) { - if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { - auto& vsync = buffer[i].vsync.vsyncData; - mHandler->dispatchFrame(VsyncId{vsync.preferredVsyncId()}, - TimePoint::fromNs( - vsync.preferredExpectedPresentationTime())); - break; - } - } - } -} - auto MessageQueue::getScheduledFrameTime() const -> std::optional<Clock::time_point> { if (mHandler->isFramePending()) { return Clock::now(); diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h index 899233a151..04de492479 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.h +++ b/services/surfaceflinger/Scheduler/MessageQueue.h @@ -76,7 +76,6 @@ public: virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) = 0; virtual void setDuration(std::chrono::nanoseconds workDuration) = 0; - virtual void setInjector(sp<EventThreadConnection>) = 0; virtual void waitMessage() = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; virtual void scheduleConfigure() = 0; @@ -132,16 +131,7 @@ private: TracedOrdinal<int> value = {"VSYNC-sf", 0}; }; - struct Injector { - gui::BitTube tube; - std::mutex mutex; - sp<EventThreadConnection> connection GUARDED_BY(mutex); - }; - Vsync mVsync; - Injector mInjector; - - void injectorCallback(); public: explicit MessageQueue(ICompositor&); @@ -149,7 +139,6 @@ public: void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) override; void setDuration(std::chrono::nanoseconds workDuration) override; - void setInjector(sp<EventThreadConnection>) override; void waitMessage() override; void postMessage(sp<MessageHandler>&&) override; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 72b65455b0..037ed8f689 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -43,7 +43,6 @@ #include "DispSyncSource.h" #include "EventThread.h" #include "FrameRateOverrideMappings.h" -#include "InjectVSyncSource.h" #include "OneShotTimer.h" #include "SurfaceFlingerProperties.h" #include "VSyncPredictor.h" @@ -403,43 +402,6 @@ void Scheduler::setDuration(ConnectionHandle handle, std::chrono::nanoseconds wo thread->setDuration(workDuration, readyDuration); } -ConnectionHandle Scheduler::enableVSyncInjection(bool enable) { - if (mInjectVSyncs == enable) { - return {}; - } - - ALOGV("%s VSYNC injection", enable ? "Enabling" : "Disabling"); - - if (!mInjectorConnectionHandle) { - auto vsyncSource = std::make_unique<InjectVSyncSource>(); - mVSyncInjector = vsyncSource.get(); - - auto eventThread = - std::make_unique<impl::EventThread>(std::move(vsyncSource), - /*tokenManager=*/nullptr, - impl::EventThread::ThrottleVsyncCallback(), - impl::EventThread::GetVsyncPeriodFunction()); - - // EventThread does not dispatch VSYNC unless the display is connected and powered on. - eventThread->onHotplugReceived(PhysicalDisplayId::fromPort(0), true); - eventThread->onScreenAcquired(); - - mInjectorConnectionHandle = createConnection(std::move(eventThread)); - } - - mInjectVSyncs = enable; - return mInjectorConnectionHandle; -} - -bool Scheduler::injectVSync(nsecs_t when, nsecs_t expectedVSyncTime, nsecs_t deadlineTimestamp) { - if (!mInjectVSyncs || !mVSyncInjector) { - return false; - } - - mVSyncInjector->onInjectSyncEvent(when, expectedVSyncTime, deadlineTimestamp); - return true; -} - void Scheduler::enableHardwareVsync() { std::lock_guard<std::mutex> lock(mHWVsyncLock); if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) { diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index 4c4956291d..609cebce08 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -78,7 +78,6 @@ struct hash<android::scheduler::ConnectionHandle> { namespace android { class FenceTime; -class InjectVSyncSource; namespace frametimeline { class TokenManager; @@ -144,7 +143,6 @@ public: void createVsyncSchedule(FeatureFlags); using Impl::initVsync; - using Impl::setInjector; using Impl::getScheduledFrameTime; using Impl::setDuration; @@ -182,10 +180,6 @@ public: void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration); - // Returns injector handle if injection has toggled, or an invalid handle otherwise. - ConnectionHandle enableVSyncInjection(bool enable); - // Returns false if injection is disabled. - bool injectVSync(nsecs_t when, nsecs_t expectedVSyncTime, nsecs_t deadlineTimestamp); void enableHardwareVsync(); void disableHardwareVsync(bool makeUnavailable); @@ -342,10 +336,6 @@ private: mutable std::mutex mConnectionsLock; std::unordered_map<ConnectionHandle, Connection> mConnections GUARDED_BY(mConnectionsLock); - bool mInjectVSyncs = false; - InjectVSyncSource* mVSyncInjector = nullptr; - ConnectionHandle mInjectorConnectionHandle; - mutable std::mutex mHWVsyncLock; bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock) = false; bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock) = false; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5466497008..6167378614 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1542,27 +1542,6 @@ status_t SurfaceFlinger::isWideColorDisplay(const sp<IBinder>& displayToken, return NO_ERROR; } -status_t SurfaceFlinger::enableVSyncInjections(bool enable) { - auto future = mScheduler->schedule([=] { - Mutex::Autolock lock(mStateLock); - - if (const auto handle = mScheduler->enableVSyncInjection(enable)) { - mScheduler->setInjector(enable ? mScheduler->getEventConnection(handle) : nullptr); - } - }); - - future.wait(); - return NO_ERROR; -} - -status_t SurfaceFlinger::injectVSync(nsecs_t when) { - Mutex::Autolock lock(mStateLock); - const nsecs_t expectedPresentTime = calculateExpectedPresentTime(TimePoint::fromNs(when)).ns(); - const nsecs_t deadlineTimestamp = expectedPresentTime; - return mScheduler->injectVSync(when, expectedPresentTime, deadlineTimestamp) ? NO_ERROR - : BAD_VALUE; -} - status_t SurfaceFlinger::getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) { outLayers->clear(); auto future = mScheduler->schedule([=] { @@ -7375,30 +7354,6 @@ binder::Status SurfaceComposerAIDL::onPullAtom(int32_t atomId, gui::PullAtomData return binderStatusFromStatusT(status); } -binder::Status SurfaceComposerAIDL::enableVSyncInjections(bool enable) { - if (!mFlinger->hasMockHwc()) { - return binderStatusFromStatusT(PERMISSION_DENIED); - } - - status_t status = checkAccessPermission(); - if (status == OK) { - status = mFlinger->enableVSyncInjections(enable); - } - return binderStatusFromStatusT(status); -} - -binder::Status SurfaceComposerAIDL::injectVSync(int64_t when) { - if (!mFlinger->hasMockHwc()) { - return binderStatusFromStatusT(PERMISSION_DENIED); - } - - status_t status = checkAccessPermission(); - if (status == OK) { - status = mFlinger->injectVSync(when); - } - return binderStatusFromStatusT(status); -} - binder::Status SurfaceComposerAIDL::getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) { if (!outLayers) { return binderStatusFromStatusT(UNEXPECTED_NULL); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 1bc45d9b76..c4c5b561db 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -530,8 +530,6 @@ private: status_t overrideHdrTypes(const sp<IBinder>& displayToken, const std::vector<ui::Hdr>& hdrTypes); status_t onPullAtom(const int32_t atomId, std::string* pulledData, bool* success); - status_t enableVSyncInjections(bool enable); - status_t injectVSync(nsecs_t when); status_t getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers); status_t getColorManagement(bool* outGetColorManagement) const; status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat, @@ -1262,8 +1260,6 @@ private: const std::string mHwcServiceName; - bool hasMockHwc() const { return mHwcServiceName == "mock"; } - /* * Scheduler */ @@ -1433,8 +1429,6 @@ public: binder::Status overrideHdrTypes(const sp<IBinder>& display, const std::vector<int32_t>& hdrTypes) override; binder::Status onPullAtom(int32_t atomId, gui::PullAtomData* outPullData) override; - binder::Status enableVSyncInjections(bool enable) override; - binder::Status injectVSync(int64_t when) override; binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) override; binder::Status getColorManagement(bool* outGetColorManagement) override; binder::Status getCompositionPreference(gui::CompositionPreference* outPref) override; diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h index 03630c9db5..ed2fe23669 100644 --- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h +++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h @@ -576,8 +576,6 @@ public: onPullAtom(&mFdp); - mFlinger->injectVSync(mFdp.ConsumeIntegral<nsecs_t>()); - getCompositionPreference(); getDisplayedContentSample(display, &mFdp); getDesiredDisplayModeSpecs(display); diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index 71b1c0eeb1..bd6367d672 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -126,7 +126,6 @@ cc_test { } subdirs = [ - "fakehwc", "hwc2", "unittests", "utils", diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp deleted file mode 100644 index 0d40e7085a..0000000000 --- a/services/surfaceflinger/tests/fakehwc/Android.bp +++ /dev/null @@ -1,64 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -cc_test { - name: "sffakehwc_test", - defaults: [ - "android.hardware.graphics.composer3-ndk_shared", - "surfaceflinger_defaults", - ], - test_suites: ["device-tests"], - srcs: [ - "FakeComposerClient.cpp", - "FakeComposerService.cpp", - "FakeComposerUtils.cpp", - "SFFakeHwc_test.cpp", - ], - require_root: true, - shared_libs: [ - "android.hardware.graphics.composer@2.1", - "android.hardware.graphics.composer@2.2", - "android.hardware.graphics.composer@2.3", - "android.hardware.graphics.composer@2.4", - "android.hardware.graphics.mapper@2.0", - "android.hardware.graphics.mapper@3.0", - "android.hardware.graphics.mapper@4.0", - "android.hardware.power@1.3", - "android.hardware.power-V2-cpp", - "libbase", - "libbinder", - "libbinder_ndk", - "libcutils", - "libfmq", - "libgui", - "libhidlbase", - "liblayers_proto", - "liblog", - "libnativewindow", - "libsync", - "libtimestats", - "libui", - "libutils", - ], - static_libs: [ - "android.hardware.graphics.composer@2.1-resources", - "libaidlcommonsupport", - "libcompositionengine", - "libgmock", - "libperfetto_client_experimental", - "librenderengine", - "libaidlcommonsupport", - ], - header_libs: [ - "android.hardware.graphics.composer@2.4-command-buffer", - "android.hardware.graphics.composer@2.4-hal", - "android.hardware.graphics.composer3-command-buffer", - "libsurfaceflinger_headers", - ], -} diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp deleted file mode 100644 index a5cca3597c..0000000000 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" - -//#define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "FakeComposer" - -#include "FakeComposerClient.h" - -#include <gui/SurfaceComposerClient.h> - -#include <log/log.h> - -#include <gtest/gtest.h> - -#include <inttypes.h> -#include <time.h> -#include <algorithm> -#include <condition_variable> -#include <iostream> -#include <mutex> -#include <set> -#include <thread> - -constexpr Config NULL_DISPLAY_CONFIG = static_cast<Config>(0); - -using namespace sftest; - -using android::Condition; -using android::Mutex; - -using Clock = std::chrono::steady_clock; -using TimePoint = std::chrono::time_point<Clock>; - -namespace { - -// Internal state of a layer in the HWC API. -class LayerImpl { -public: - LayerImpl() = default; - - bool mValid = true; - RenderState mRenderState; - uint32_t mZ = 0; -}; - -// Struct for storing per frame rectangle state. Contains the render -// state shared to the test case. Basically a snapshot and a subset of -// LayerImpl sufficient to re-create the pixels of a layer for the -// frame. -struct FrameRect { -public: - FrameRect(Layer layer_, const RenderState& state, uint32_t z_) - : layer(layer_), renderState(state), z(z_) {} - - const Layer layer; - const RenderState renderState; - const uint32_t z; -}; - -// Collection of FrameRects forming one rendered frame. Could store -// related fences and other data in the future. -class Frame { -public: - Frame() = default; - std::vector<std::unique_ptr<FrameRect>> rectangles; -}; - -class DelayedEventGenerator { -public: - explicit DelayedEventGenerator(std::function<void()> onTimerExpired) - : mOnTimerExpired(onTimerExpired) { - mThread = std::thread([this]() { loop(); }); - } - - ~DelayedEventGenerator() { - ALOGI("DelayedEventGenerator exiting."); - { - std::unique_lock<std::mutex> lock(mMutex); - mRunning = false; - mWakeups.clear(); - mCondition.notify_one(); - } - mThread.join(); - ALOGI("DelayedEventGenerator exited."); - } - - void wakeAfter(std::chrono::nanoseconds waitTime) { - std::unique_lock<std::mutex> lock(mMutex); - mWakeups.insert(Clock::now() + waitTime); - mCondition.notify_one(); - } - -private: - void loop() { - while (true) { - // Lock scope - { - std::unique_lock<std::mutex> lock(mMutex); - mCondition.wait(lock, [this]() { return !mRunning || !mWakeups.empty(); }); - if (!mRunning && mWakeups.empty()) { - // This thread should only exit once the destructor has been called and all - // wakeups have been processed - return; - } - - // At this point, mWakeups will not be empty - - TimePoint target = *(mWakeups.begin()); - auto status = mCondition.wait_until(lock, target); - while (status == std::cv_status::no_timeout) { - // This was either a spurious wakeup or another wakeup was added, so grab the - // oldest point and wait again - target = *(mWakeups.begin()); - status = mCondition.wait_until(lock, target); - } - - // status must have been timeout, so we can finally clear this point - mWakeups.erase(target); - } - // Callback *without* locks! - mOnTimerExpired(); - } - } - - std::function<void()> mOnTimerExpired; - std::thread mThread; - std::mutex mMutex; - std::condition_variable mCondition; - bool mRunning = true; - std::set<TimePoint> mWakeups; -}; - -} // namespace - -FakeComposerClient::FakeComposerClient() - : mEventCallback(nullptr), - mEventCallback_2_4(nullptr), - mCurrentConfig(NULL_DISPLAY_CONFIG), - mVsyncEnabled(false), - mLayers(), - mDelayedEventGenerator( - std::make_unique<DelayedEventGenerator>([this]() { this->requestVSync(); })), - mSurfaceComposer(nullptr) {} - -FakeComposerClient::~FakeComposerClient() {} - -bool FakeComposerClient::hasCapability(hwc2_capability_t /*capability*/) { - return false; -} - -std::string FakeComposerClient::dumpDebugInfo() { - return {}; -} - -void FakeComposerClient::registerEventCallback(EventCallback* callback) { - ALOGV("registerEventCallback"); - LOG_FATAL_IF(mEventCallback_2_4 != nullptr, - "already registered using registerEventCallback_2_4"); - - mEventCallback = callback; - if (mEventCallback) { - mEventCallback->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED); - } -} - -void FakeComposerClient::unregisterEventCallback() { - ALOGV("unregisterEventCallback"); - mEventCallback = nullptr; -} - -void FakeComposerClient::hotplugDisplay(Display display, IComposerCallback::Connection state) { - if (mEventCallback) { - mEventCallback->onHotplug(display, state); - } else if (mEventCallback_2_4) { - mEventCallback_2_4->onHotplug(display, state); - } -} - -void FakeComposerClient::refreshDisplay(Display display) { - if (mEventCallback) { - mEventCallback->onRefresh(display); - } else if (mEventCallback_2_4) { - mEventCallback_2_4->onRefresh(display); - } -} - -uint32_t FakeComposerClient::getMaxVirtualDisplayCount() { - ALOGV("getMaxVirtualDisplayCount"); - return 1; -} - -V2_1::Error FakeComposerClient::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/, - V1_0::PixelFormat* /*format*/, - Display* /*outDisplay*/) { - ALOGV("createVirtualDisplay"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::destroyVirtualDisplay(Display /*display*/) { - ALOGV("destroyVirtualDisplay"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::createLayer(Display /*display*/, Layer* outLayer) { - ALOGV("createLayer"); - *outLayer = mLayers.size(); - auto newLayer = std::make_unique<LayerImpl>(); - mLayers.push_back(std::move(newLayer)); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::destroyLayer(Display /*display*/, Layer layer) { - ALOGV("destroyLayer"); - mLayers[layer]->mValid = false; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getActiveConfig(Display display, Config* outConfig) { - ALOGV("getActiveConfig"); - if (mMockHal) { - return mMockHal->getActiveConfig(display, outConfig); - } - - // TODO Assert outConfig != nullptr - - // TODO This is my reading of the - // IComposerClient::getActiveConfig, but returning BAD_CONFIG - // seems to not fit SurfaceFlinger plans. See version 2 below. - // if (mCurrentConfig == NULL_DISPLAY_CONFIG) { - // return V2_1::Error::BAD_CONFIG; - // } - //*outConfig = mCurrentConfig; - *outConfig = 1; // Very special config for you my friend - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getClientTargetSupport(Display /*display*/, uint32_t /*width*/, - uint32_t /*height*/, - V1_0::PixelFormat /*format*/, - V1_0::Dataspace /*dataspace*/) { - ALOGV("getClientTargetSupport"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getColorModes(Display /*display*/, - hidl_vec<V1_0::ColorMode>* /*outModes*/) { - ALOGV("getColorModes"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getDisplayAttribute(Display display, Config config, - V2_1::IComposerClient::Attribute attribute, - int32_t* outValue) { - auto tmpError = - getDisplayAttribute_2_4(display, config, - static_cast<IComposerClient::Attribute>(attribute), outValue); - return static_cast<V2_1::Error>(tmpError); -} - -V2_1::Error FakeComposerClient::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) { - ALOGV("getDisplayConfigs"); - if (mMockHal) { - return mMockHal->getDisplayConfigs(display, outConfigs); - } - - // TODO assert display == 1, outConfigs != nullptr - - outConfigs->resize(1); - (*outConfigs)[0] = 1; - - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getDisplayName(Display /*display*/, hidl_string* /*outName*/) { - ALOGV("getDisplayName"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getDisplayType(Display /*display*/, - IComposerClient::DisplayType* outType) { - ALOGV("getDisplayType"); - // TODO: This setting nothing on the output had no effect on initial trials. Is first display - // assumed to be physical? - *outType = static_cast<IComposerClient::DisplayType>(HWC2_DISPLAY_TYPE_PHYSICAL); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getDozeSupport(Display /*display*/, bool* /*outSupport*/) { - ALOGV("getDozeSupport"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::getHdrCapabilities(Display /*display*/, - hidl_vec<V1_0::Hdr>* /*outTypes*/, - float* /*outMaxLuminance*/, - float* /*outMaxAverageLuminance*/, - float* /*outMinLuminance*/) { - ALOGV("getHdrCapabilities"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setActiveConfig(Display display, Config config) { - ALOGV("setActiveConfig"); - if (mMockHal) { - return mMockHal->setActiveConfig(display, config); - } - mCurrentConfig = config; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setColorMode(Display /*display*/, V1_0::ColorMode /*mode*/) { - ALOGV("setColorMode"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setPowerMode(Display /*display*/, - V2_1::IComposerClient::PowerMode /*mode*/) { - ALOGV("setPowerMode"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setVsyncEnabled(Display /*display*/, - IComposerClient::Vsync enabled) { - mVsyncEnabled = (enabled == IComposerClient::Vsync::ENABLE); - ALOGV("setVsyncEnabled(%s)", mVsyncEnabled ? "ENABLE" : "DISABLE"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setColorTransform(Display /*display*/, const float* /*matrix*/, - int32_t /*hint*/) { - ALOGV("setColorTransform"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setClientTarget(Display /*display*/, buffer_handle_t /*target*/, - int32_t /*acquireFence*/, int32_t /*dataspace*/, - const std::vector<hwc_rect_t>& /*damage*/) { - ALOGV("setClientTarget"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setOutputBuffer(Display /*display*/, buffer_handle_t /*buffer*/, - int32_t /*releaseFence*/) { - ALOGV("setOutputBuffer"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::validateDisplay( - Display /*display*/, std::vector<Layer>* /*outChangedLayers*/, - std::vector<IComposerClient::Composition>* /*outCompositionTypes*/, - uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/, - std::vector<uint32_t>* /*outRequestMasks*/) { - ALOGV("validateDisplay"); - // TODO: Assume touching nothing means All Korrekt! - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::acceptDisplayChanges(Display /*display*/) { - ALOGV("acceptDisplayChanges"); - // Didn't ask for changes because software is omnipotent. - return V2_1::Error::NONE; -} - -bool layerZOrdering(const std::unique_ptr<FrameRect>& a, const std::unique_ptr<FrameRect>& b) { - return a->z <= b->z; -} - -V2_1::Error FakeComposerClient::presentDisplay(Display /*display*/, int32_t* /*outPresentFence*/, - std::vector<Layer>* /*outLayers*/, - std::vector<int32_t>* /*outReleaseFences*/) { - ALOGV("presentDisplay"); - // TODO Leaving layers and their fences out for now. Doing so - // means that we've already processed everything. Important to - // test that the fences are respected, though. (How?) - - std::unique_ptr<Frame> newFrame(new Frame); - for (uint64_t layer = 0; layer < mLayers.size(); layer++) { - const LayerImpl& layerImpl = *mLayers[layer]; - - if (!layerImpl.mValid) continue; - - auto rect = std::make_unique<FrameRect>(layer, layerImpl.mRenderState, layerImpl.mZ); - newFrame->rectangles.push_back(std::move(rect)); - } - std::sort(newFrame->rectangles.begin(), newFrame->rectangles.end(), layerZOrdering); - { - Mutex::Autolock _l(mStateMutex); - mFrames.push_back(std::move(newFrame)); - mFramesAvailable.broadcast(); - } - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerCursorPosition(Display /*display*/, Layer /*layer*/, - int32_t /*x*/, int32_t /*y*/) { - ALOGV("setLayerCursorPosition"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerBuffer(Display /*display*/, Layer layer, - buffer_handle_t buffer, int32_t acquireFence) { - ALOGV("setLayerBuffer"); - LayerImpl& l = getLayerImpl(layer); - if (buffer != l.mRenderState.mBuffer) { - l.mRenderState.mSwapCount++; // TODO: Is setting to same value a swap or not? - } - l.mRenderState.mBuffer = buffer; - l.mRenderState.mAcquireFence = acquireFence; - - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerSurfaceDamage(Display /*display*/, Layer /*layer*/, - const std::vector<hwc_rect_t>& /*damage*/) { - ALOGV("setLayerSurfaceDamage"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerBlendMode(Display /*display*/, Layer layer, int32_t mode) { - ALOGV("setLayerBlendMode"); - getLayerImpl(layer).mRenderState.mBlendMode = static_cast<hwc2_blend_mode_t>(mode); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerColor(Display /*display*/, Layer layer, - IComposerClient::Color color) { - ALOGV("setLayerColor"); - getLayerImpl(layer).mRenderState.mLayerColor.r = color.r; - getLayerImpl(layer).mRenderState.mLayerColor.g = color.g; - getLayerImpl(layer).mRenderState.mLayerColor.b = color.b; - getLayerImpl(layer).mRenderState.mLayerColor.a = color.a; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerCompositionType(Display /*display*/, Layer /*layer*/, - int32_t /*type*/) { - ALOGV("setLayerCompositionType"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerDataspace(Display /*display*/, Layer /*layer*/, - int32_t /*dataspace*/) { - ALOGV("setLayerDataspace"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerDisplayFrame(Display /*display*/, Layer layer, - const hwc_rect_t& frame) { - ALOGV("setLayerDisplayFrame (%d, %d, %d, %d)", frame.left, frame.top, frame.right, - frame.bottom); - getLayerImpl(layer).mRenderState.mDisplayFrame = frame; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerPlaneAlpha(Display /*display*/, Layer layer, float alpha) { - ALOGV("setLayerPlaneAlpha"); - getLayerImpl(layer).mRenderState.mPlaneAlpha = alpha; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerSidebandStream(Display /*display*/, Layer /*layer*/, - buffer_handle_t /*stream*/) { - ALOGV("setLayerSidebandStream"); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerSourceCrop(Display /*display*/, Layer layer, - const hwc_frect_t& crop) { - ALOGV("setLayerSourceCrop"); - getLayerImpl(layer).mRenderState.mSourceCrop = crop; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerTransform(Display /*display*/, Layer layer, - int32_t transform) { - ALOGV("setLayerTransform"); - getLayerImpl(layer).mRenderState.mTransform = static_cast<hwc_transform_t>(transform); - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerVisibleRegion(Display /*display*/, Layer layer, - const std::vector<hwc_rect_t>& visible) { - ALOGV("setLayerVisibleRegion"); - getLayerImpl(layer).mRenderState.mVisibleRegion = visible; - return V2_1::Error::NONE; -} - -V2_1::Error FakeComposerClient::setLayerZOrder(Display /*display*/, Layer layer, uint32_t z) { - ALOGV("setLayerZOrder"); - getLayerImpl(layer).mZ = z; - return V2_1::Error::NONE; -} - -// Composer 2.2 -V2_1::Error FakeComposerClient::getPerFrameMetadataKeys( - Display /*display*/, std::vector<V2_2::IComposerClient::PerFrameMetadataKey>* /*outKeys*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setLayerPerFrameMetadata( - Display /*display*/, Layer /*layer*/, - const std::vector<V2_2::IComposerClient::PerFrameMetadata>& /*metadata*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getReadbackBufferAttributes( - Display /*display*/, graphics::common::V1_1::PixelFormat* /*outFormat*/, - graphics::common::V1_1::Dataspace* /*outDataspace*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setReadbackBuffer(Display /*display*/, - const native_handle_t* /*bufferHandle*/, - android::base::unique_fd /*fenceFd*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getReadbackBufferFence(Display /*display*/, - android::base::unique_fd* /*outFenceFd*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::createVirtualDisplay_2_2( - uint32_t /*width*/, uint32_t /*height*/, graphics::common::V1_1::PixelFormat* /*format*/, - Display* /*outDisplay*/) { - return V2_1::Error::UNSUPPORTED; -} -V2_1::Error FakeComposerClient::getClientTargetSupport_2_2( - Display /*display*/, uint32_t /*width*/, uint32_t /*height*/, - graphics::common::V1_1::PixelFormat /*format*/, - graphics::common::V1_1::Dataspace /*dataspace*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setPowerMode_2_2(Display /*display*/, - V2_2::IComposerClient::PowerMode /*mode*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setLayerFloatColor(Display /*display*/, Layer /*layer*/, - V2_2::IComposerClient::FloatColor /*color*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getColorModes_2_2( - Display /*display*/, hidl_vec<graphics::common::V1_1::ColorMode>* /*outModes*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getRenderIntents( - Display /*display*/, graphics::common::V1_1::ColorMode /*mode*/, - std::vector<graphics::common::V1_1::RenderIntent>* /*outIntents*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setColorMode_2_2(Display /*display*/, - graphics::common::V1_1::ColorMode /*mode*/, - graphics::common::V1_1::RenderIntent /*intent*/) { - return V2_1::Error::UNSUPPORTED; -} - -std::array<float, 16> FakeComposerClient::getDataspaceSaturationMatrix( - graphics::common::V1_1::Dataspace /*dataspace*/) { - return {}; -} - -// Composer 2.3 -V2_1::Error FakeComposerClient::getPerFrameMetadataKeys_2_3( - Display /*display*/, std::vector<V2_3::IComposerClient::PerFrameMetadataKey>* /*outKeys*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setColorMode_2_3(Display /*display*/, - graphics::common::V1_2::ColorMode /*mode*/, - graphics::common::V1_1::RenderIntent /*intent*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getRenderIntents_2_3( - Display /*display*/, graphics::common::V1_2::ColorMode /*mode*/, - std::vector<graphics::common::V1_1::RenderIntent>* /*outIntents*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getColorModes_2_3( - Display /*display*/, hidl_vec<graphics::common::V1_2::ColorMode>* /*outModes*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getClientTargetSupport_2_3( - Display /*display*/, uint32_t /*width*/, uint32_t /*height*/, - graphics::common::V1_2::PixelFormat /*format*/, - graphics::common::V1_2::Dataspace /*dataspace*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getReadbackBufferAttributes_2_3( - Display /*display*/, graphics::common::V1_2::PixelFormat* /*outFormat*/, - graphics::common::V1_2::Dataspace* /*outDataspace*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getHdrCapabilities_2_3( - Display /*display*/, hidl_vec<graphics::common::V1_2::Hdr>* /*outTypes*/, - float* /*outMaxLuminance*/, float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setLayerPerFrameMetadata_2_3( - Display /*display*/, Layer /*layer*/, - const std::vector<V2_3::IComposerClient::PerFrameMetadata>& /*metadata*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getDisplayIdentificationData(Display /*display*/, - uint8_t* /*outPort*/, - std::vector<uint8_t>* /*outData*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setLayerColorTransform(Display /*display*/, Layer /*layer*/, - const float* /*matrix*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getDisplayedContentSamplingAttributes( - uint64_t /*display*/, graphics::common::V1_2::PixelFormat& /*format*/, - graphics::common::V1_2::Dataspace& /*dataspace*/, - hidl_bitfield<V2_3::IComposerClient::FormatColorComponent>& /*componentMask*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setDisplayedContentSamplingEnabled( - uint64_t /*display*/, V2_3::IComposerClient::DisplayedContentSampling /*enable*/, - hidl_bitfield<V2_3::IComposerClient::FormatColorComponent> /*componentMask*/, - uint64_t /*maxFrames*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getDisplayedContentSample( - uint64_t /*display*/, uint64_t /*maxFrames*/, uint64_t /*timestamp*/, - uint64_t& /*frameCount*/, hidl_vec<uint64_t>& /*sampleComponent0*/, - hidl_vec<uint64_t>& /*sampleComponent1*/, hidl_vec<uint64_t>& /*sampleComponent2*/, - hidl_vec<uint64_t>& /*sampleComponent3*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getDisplayCapabilities( - Display /*display*/, - std::vector<V2_3::IComposerClient::DisplayCapability>* /*outCapabilities*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setLayerPerFrameMetadataBlobs( - Display /*display*/, Layer /*layer*/, - std::vector<V2_3::IComposerClient::PerFrameMetadataBlob>& /*blobs*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::getDisplayBrightnessSupport(Display /*display*/, - bool* /*outSupport*/) { - return V2_1::Error::UNSUPPORTED; -} - -V2_1::Error FakeComposerClient::setDisplayBrightness(Display /*display*/, float /*brightness*/) { - return V2_1::Error::UNSUPPORTED; -} - -// Composer 2.4 -void FakeComposerClient::registerEventCallback_2_4(EventCallback_2_4* callback) { - ALOGV("registerEventCallback_2_4"); - LOG_FATAL_IF(mEventCallback != nullptr, "already registered using registerEventCallback"); - - mEventCallback_2_4 = callback; - if (mEventCallback_2_4) { - mEventCallback_2_4->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED); - } -} - -void FakeComposerClient::unregisterEventCallback_2_4() { - ALOGV("unregisterEventCallback_2_4"); - mEventCallback_2_4 = nullptr; -} - -V2_4::Error FakeComposerClient::getDisplayCapabilities_2_4( - Display /*display*/, - std::vector<V2_4::IComposerClient::DisplayCapability>* /*outCapabilities*/) { - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::getDisplayConnectionType( - Display /*display*/, V2_4::IComposerClient::DisplayConnectionType* /*outType*/) { - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::getDisplayAttribute_2_4(Display display, Config config, - IComposerClient::Attribute attribute, - int32_t* outValue) { - ALOGV("getDisplayAttribute (%d, %d, %d, %p)", static_cast<int>(display), - static_cast<int>(config), static_cast<int>(attribute), outValue); - if (mMockHal) { - return mMockHal->getDisplayAttribute_2_4(display, config, attribute, outValue); - } - - // TODO: SOOO much fun to be had with these alone - switch (attribute) { - case IComposerClient::Attribute::WIDTH: - *outValue = 1920; - break; - case IComposerClient::Attribute::HEIGHT: - *outValue = 1080; - break; - case IComposerClient::Attribute::VSYNC_PERIOD: - *outValue = 1666666666; - break; // TOOD: Tests break down if lowered to 16ms? - case IComposerClient::Attribute::DPI_X: - *outValue = 240; - break; - case IComposerClient::Attribute::DPI_Y: - *outValue = 240; - break; - default: - LOG_ALWAYS_FATAL("Say what!?! New attribute"); - } - - return Error::NONE; -} - -V2_4::Error FakeComposerClient::getDisplayVsyncPeriod(Display display, - V2_4::VsyncPeriodNanos* outVsyncPeriod) { - ALOGV("getDisplayVsyncPeriod"); - if (mMockHal) { - return mMockHal->getDisplayVsyncPeriod(display, outVsyncPeriod); - } - - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::setActiveConfigWithConstraints( - Display display, Config config, - const V2_4::IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints, - VsyncPeriodChangeTimeline* timeline) { - ALOGV("setActiveConfigWithConstraints"); - if (mMockHal) { - return mMockHal->setActiveConfigWithConstraints(display, config, - vsyncPeriodChangeConstraints, timeline); - } - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::setAutoLowLatencyMode(Display, bool) { - ALOGV("setAutoLowLatencyMode"); - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::getSupportedContentTypes( - Display, std::vector<IComposerClient::ContentType>*) { - ALOGV("getSupportedContentTypes"); - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::setContentType(Display, IComposerClient::ContentType) { - ALOGV("setContentType"); - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::validateDisplay_2_4( - Display /*display*/, std::vector<Layer>* /*outChangedLayers*/, - std::vector<IComposerClient::Composition>* /*outCompositionTypes*/, - uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/, - std::vector<uint32_t>* /*outRequestMasks*/, - IComposerClient::ClientTargetProperty* /*outClientTargetProperty*/) { - return V2_4::Error::NONE; -} - -V2_4::Error FakeComposerClient::setLayerGenericMetadata(Display, Layer, const std::string&, bool, - const std::vector<uint8_t>&) { - ALOGV("setLayerGenericMetadata"); - return V2_4::Error::UNSUPPORTED; -} - -V2_4::Error FakeComposerClient::getLayerGenericMetadataKeys( - std::vector<IComposerClient::LayerGenericMetadataKey>*) { - ALOGV("getLayerGenericMetadataKeys"); - return V2_4::Error::UNSUPPORTED; -} - -////////////////////////////////////////////////////////////////// - -void FakeComposerClient::requestVSync(uint64_t vsyncTime) { - if (mEventCallback || mEventCallback_2_4) { - uint64_t timestamp = vsyncTime; - ALOGV("Vsync"); - if (timestamp == 0) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - timestamp = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; - } - if (mSurfaceComposer != nullptr) { - mSurfaceComposer->injectVSync(timestamp); - } else if (mEventCallback) { - mEventCallback->onVsync(PRIMARY_DISPLAY, timestamp); - } else { - mEventCallback_2_4->onVsync_2_4(PRIMARY_DISPLAY, timestamp, 16'666'666); - } - } -} - -void FakeComposerClient::runVSyncAfter(std::chrono::nanoseconds wait) { - mDelayedEventGenerator->wakeAfter(wait); -} - -LayerImpl& FakeComposerClient::getLayerImpl(Layer handle) { - // TODO Change these to an internal state check that can be - // invoked from the gtest? GTest macros do not seem all that safe - // when used outside the test class - EXPECT_GE(handle, static_cast<Layer>(0)); - EXPECT_LT(handle, mLayers.size()); - return *(mLayers[handle]); -} - -int FakeComposerClient::getFrameCount() const { - return mFrames.size(); -} - -static std::vector<RenderState> extractRenderState( - const std::vector<std::unique_ptr<FrameRect>>& internalRects) { - std::vector<RenderState> result; - result.reserve(internalRects.size()); - for (const std::unique_ptr<FrameRect>& rect : internalRects) { - result.push_back(rect->renderState); - } - return result; -} - -std::vector<RenderState> FakeComposerClient::getFrameRects(int frame) const { - Mutex::Autolock _l(mStateMutex); - return extractRenderState(mFrames[frame]->rectangles); -} - -std::vector<RenderState> FakeComposerClient::getLatestFrame() const { - Mutex::Autolock _l(mStateMutex); - return extractRenderState(mFrames[mFrames.size() - 1]->rectangles); -} - -void FakeComposerClient::runVSyncAndWait(std::chrono::nanoseconds maxWait) { - int currentFrame = 0; - { - Mutex::Autolock _l(mStateMutex); // I hope this is ok... - currentFrame = static_cast<int>(mFrames.size()); - requestVSync(); - } - waitUntilFrame(currentFrame + 1, maxWait); -} - -void FakeComposerClient::waitUntilFrame(int targetFrame, std::chrono::nanoseconds maxWait) const { - Mutex::Autolock _l(mStateMutex); - while (mFrames.size() < static_cast<size_t>(targetFrame)) { - android::status_t result = mFramesAvailable.waitRelative(mStateMutex, maxWait.count()); - if (result == android::TIMED_OUT) { - ALOGE("Waiting for frame %d (at frame %zu now) timed out after %lld ns", targetFrame, - mFrames.size(), maxWait.count()); - return; - } - } -} - -void FakeComposerClient::clearFrames() { - Mutex::Autolock _l(mStateMutex); - mFrames.clear(); - for (const std::unique_ptr<LayerImpl>& layer : mLayers) { - if (layer->mValid) { - layer->mRenderState.mSwapCount = 0; - } - } -} - -void FakeComposerClient::onSurfaceFlingerStart() { - mSurfaceComposer = nullptr; - do { - mSurfaceComposer = android::sp<android::SurfaceComposerClient>::make(); - android::status_t initResult = mSurfaceComposer->initCheck(); - if (initResult != android::NO_ERROR) { - ALOGD("Init result: %d", initResult); - mSurfaceComposer = nullptr; - std::this_thread::sleep_for(10ms); - } - } while (mSurfaceComposer == nullptr); - ALOGD("SurfaceComposerClient created"); - mSurfaceComposer->enableVSyncInjections(true); -} - -void FakeComposerClient::onSurfaceFlingerStop() { - mSurfaceComposer->enableVSyncInjections(false); - mSurfaceComposer->dispose(); - mSurfaceComposer.clear(); -} - -// Includes destroyed layers, stored in order of creation. -int FakeComposerClient::getLayerCount() const { - return mLayers.size(); -} - -Layer FakeComposerClient::getLayer(size_t index) const { - // NOTE: If/when passing calls through to actual implementation, - // this might get more involving. - return static_cast<Layer>(index); -} - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h deleted file mode 100644 index 600e765e9b..0000000000 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright 2017 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 <chrono> - -#include <composer-hal/2.1/ComposerClient.h> -#include <composer-hal/2.2/ComposerClient.h> -#include <composer-hal/2.3/ComposerClient.h> -#include <composer-hal/2.4/ComposerClient.h> -#include <utils/Condition.h> - -#include "MockComposerHal.h" -#include "RenderState.h" - -using namespace android::hardware::graphics::common; -using namespace android::hardware::graphics::composer; -using namespace android::hardware::graphics::composer::V2_4; -using namespace android::hardware::graphics::composer::V2_4::hal; -using namespace android::hardware; -using namespace std::chrono_literals; - -namespace { -class LayerImpl; -class Frame; -class DelayedEventGenerator; -} // namespace - -namespace android { -class SurfaceComposerClient; -} // namespace android - -namespace sftest { -// NOTE: The ID's need to be exactly these. VR composer and parts of -// the SurfaceFlinger assume the display IDs to have these values -// despite the enum being documented as a display type. -// TODO: Reference to actual documentation -constexpr Display PRIMARY_DISPLAY = static_cast<Display>(HWC_DISPLAY_PRIMARY); -constexpr Display EXTERNAL_DISPLAY = static_cast<Display>(HWC_DISPLAY_EXTERNAL); - -class FakeComposerClient : public ComposerHal { -public: - FakeComposerClient(); - virtual ~FakeComposerClient(); - - void setMockHal(MockComposerHal* mockHal) { mMockHal = mockHal; } - - bool hasCapability(hwc2_capability_t capability) override; - - std::string dumpDebugInfo() override; - void registerEventCallback(EventCallback* callback) override; - void unregisterEventCallback() override; - - uint32_t getMaxVirtualDisplayCount() override; - V2_1::Error createVirtualDisplay(uint32_t width, uint32_t height, V1_0::PixelFormat* format, - Display* outDisplay) override; - V2_1::Error destroyVirtualDisplay(Display display) override; - V2_1::Error createLayer(Display display, Layer* outLayer) override; - V2_1::Error destroyLayer(Display display, Layer layer) override; - - V2_1::Error getActiveConfig(Display display, Config* outConfig) override; - V2_1::Error getClientTargetSupport(Display display, uint32_t width, uint32_t height, - V1_0::PixelFormat format, - V1_0::Dataspace dataspace) override; - V2_1::Error getColorModes(Display display, hidl_vec<V1_0::ColorMode>* outModes) override; - V2_1::Error getDisplayAttribute(Display display, Config config, - V2_1::IComposerClient::Attribute attribute, - int32_t* outValue) override; - V2_1::Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override; - V2_1::Error getDisplayName(Display display, hidl_string* outName) override; - V2_1::Error getDisplayType(Display display, IComposerClient::DisplayType* outType) override; - V2_1::Error getDozeSupport(Display display, bool* outSupport) override; - V2_1::Error getHdrCapabilities(Display display, hidl_vec<V1_0::Hdr>* outTypes, - float* outMaxLuminance, float* outMaxAverageLuminance, - float* outMinLuminance) override; - - V2_1::Error setActiveConfig(Display display, Config config) override; - V2_1::Error setColorMode(Display display, V1_0::ColorMode mode) override; - V2_1::Error setPowerMode(Display display, V2_1::IComposerClient::PowerMode mode) override; - V2_1::Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override; - - V2_1::Error setColorTransform(Display display, const float* matrix, int32_t hint) override; - V2_1::Error setClientTarget(Display display, buffer_handle_t target, int32_t acquireFence, - int32_t dataspace, const std::vector<hwc_rect_t>& damage) override; - V2_1::Error setOutputBuffer(Display display, buffer_handle_t buffer, - int32_t releaseFence) override; - V2_1::Error validateDisplay(Display display, std::vector<Layer>* outChangedLayers, - std::vector<IComposerClient::Composition>* outCompositionTypes, - uint32_t* outDisplayRequestMask, - std::vector<Layer>* outRequestedLayers, - std::vector<uint32_t>* outRequestMasks) override; - V2_1::Error acceptDisplayChanges(Display display) override; - V2_1::Error presentDisplay(Display display, int32_t* outPresentFence, - std::vector<Layer>* outLayers, - std::vector<int32_t>* outReleaseFences) override; - - V2_1::Error setLayerCursorPosition(Display display, Layer layer, int32_t x, int32_t y) override; - V2_1::Error setLayerBuffer(Display display, Layer layer, buffer_handle_t buffer, - int32_t acquireFence) override; - V2_1::Error setLayerSurfaceDamage(Display display, Layer layer, - const std::vector<hwc_rect_t>& damage) override; - V2_1::Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override; - V2_1::Error setLayerColor(Display display, Layer layer, IComposerClient::Color color) override; - V2_1::Error setLayerCompositionType(Display display, Layer layer, int32_t type) override; - V2_1::Error setLayerDataspace(Display display, Layer layer, int32_t dataspace) override; - V2_1::Error setLayerDisplayFrame(Display display, Layer layer, - const hwc_rect_t& frame) override; - V2_1::Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override; - V2_1::Error setLayerSidebandStream(Display display, Layer layer, - buffer_handle_t stream) override; - V2_1::Error setLayerSourceCrop(Display display, Layer layer, const hwc_frect_t& crop) override; - V2_1::Error setLayerTransform(Display display, Layer layer, int32_t transform) override; - V2_1::Error setLayerVisibleRegion(Display display, Layer layer, - const std::vector<hwc_rect_t>& visible) override; - V2_1::Error setLayerZOrder(Display display, Layer layer, uint32_t z) override; - - // Composer 2.2 - V2_1::Error getPerFrameMetadataKeys( - Display display, - std::vector<V2_2::IComposerClient::PerFrameMetadataKey>* outKeys) override; - V2_1::Error setLayerPerFrameMetadata( - Display display, Layer layer, - const std::vector<V2_2::IComposerClient::PerFrameMetadata>& metadata) override; - - V2_1::Error getReadbackBufferAttributes( - Display display, graphics::common::V1_1::PixelFormat* outFormat, - graphics::common::V1_1::Dataspace* outDataspace) override; - V2_1::Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle, - android::base::unique_fd fenceFd) override; - V2_1::Error getReadbackBufferFence(Display display, - android::base::unique_fd* outFenceFd) override; - V2_1::Error createVirtualDisplay_2_2(uint32_t width, uint32_t height, - graphics::common::V1_1::PixelFormat* format, - Display* outDisplay) override; - V2_1::Error getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height, - graphics::common::V1_1::PixelFormat format, - graphics::common::V1_1::Dataspace dataspace) override; - V2_1::Error setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode) override; - - V2_1::Error setLayerFloatColor(Display display, Layer layer, - V2_2::IComposerClient::FloatColor color) override; - - V2_1::Error getColorModes_2_2(Display display, - hidl_vec<graphics::common::V1_1::ColorMode>* outModes) override; - V2_1::Error getRenderIntents( - Display display, graphics::common::V1_1::ColorMode mode, - std::vector<graphics::common::V1_1::RenderIntent>* outIntents) override; - V2_1::Error setColorMode_2_2(Display display, graphics::common::V1_1::ColorMode mode, - graphics::common::V1_1::RenderIntent intent) override; - - std::array<float, 16> getDataspaceSaturationMatrix( - graphics::common::V1_1::Dataspace dataspace) override; - - // Composer 2.3 - V2_1::Error getPerFrameMetadataKeys_2_3( - Display display, - std::vector<V2_3::IComposerClient::PerFrameMetadataKey>* outKeys) override; - - V2_1::Error setColorMode_2_3(Display display, graphics::common::V1_2::ColorMode mode, - graphics::common::V1_1::RenderIntent intent) override; - - V2_1::Error getRenderIntents_2_3( - Display display, graphics::common::V1_2::ColorMode mode, - std::vector<graphics::common::V1_1::RenderIntent>* outIntents) override; - - V2_1::Error getColorModes_2_3(Display display, - hidl_vec<graphics::common::V1_2::ColorMode>* outModes) override; - - V2_1::Error getClientTargetSupport_2_3(Display display, uint32_t width, uint32_t height, - graphics::common::V1_2::PixelFormat format, - graphics::common::V1_2::Dataspace dataspace) override; - V2_1::Error getReadbackBufferAttributes_2_3( - Display display, graphics::common::V1_2::PixelFormat* outFormat, - graphics::common::V1_2::Dataspace* outDataspace) override; - V2_1::Error getHdrCapabilities_2_3(Display display, - hidl_vec<graphics::common::V1_2::Hdr>* outTypes, - float* outMaxLuminance, float* outMaxAverageLuminance, - float* outMinLuminance) override; - V2_1::Error setLayerPerFrameMetadata_2_3( - Display display, Layer layer, - const std::vector<V2_3::IComposerClient::PerFrameMetadata>& metadata) override; - V2_1::Error getDisplayIdentificationData(Display display, uint8_t* outPort, - std::vector<uint8_t>* outData) override; - V2_1::Error setLayerColorTransform(Display display, Layer layer, const float* matrix) override; - V2_1::Error getDisplayedContentSamplingAttributes( - uint64_t display, graphics::common::V1_2::PixelFormat& format, - graphics::common::V1_2::Dataspace& dataspace, - hidl_bitfield<V2_3::IComposerClient::FormatColorComponent>& componentMask) override; - V2_1::Error setDisplayedContentSamplingEnabled( - uint64_t display, V2_3::IComposerClient::DisplayedContentSampling enable, - hidl_bitfield<V2_3::IComposerClient::FormatColorComponent> componentMask, - uint64_t maxFrames) override; - V2_1::Error getDisplayedContentSample(uint64_t display, uint64_t maxFrames, uint64_t timestamp, - uint64_t& frameCount, - hidl_vec<uint64_t>& sampleComponent0, - hidl_vec<uint64_t>& sampleComponent1, - hidl_vec<uint64_t>& sampleComponent2, - hidl_vec<uint64_t>& sampleComponent3) override; - V2_1::Error getDisplayCapabilities( - Display display, - std::vector<V2_3::IComposerClient::DisplayCapability>* outCapabilities) override; - V2_1::Error setLayerPerFrameMetadataBlobs( - Display display, Layer layer, - std::vector<V2_3::IComposerClient::PerFrameMetadataBlob>& blobs) override; - V2_1::Error getDisplayBrightnessSupport(Display display, bool* outSupport) override; - V2_1::Error setDisplayBrightness(Display display, float brightness) override; - - // Composer 2.4 - void registerEventCallback_2_4(EventCallback_2_4* callback) override; - - void unregisterEventCallback_2_4() override; - - V2_4::Error getDisplayCapabilities_2_4( - Display display, - std::vector<V2_4::IComposerClient::DisplayCapability>* outCapabilities) override; - V2_4::Error getDisplayConnectionType( - Display display, V2_4::IComposerClient::DisplayConnectionType* outType) override; - V2_4::Error getDisplayAttribute_2_4(Display display, Config config, - IComposerClient::Attribute attribute, - int32_t* outValue) override; - V2_4::Error getDisplayVsyncPeriod(Display display, - V2_4::VsyncPeriodNanos* outVsyncPeriod) override; - V2_4::Error setActiveConfigWithConstraints( - Display display, Config config, - const V2_4::IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints, - VsyncPeriodChangeTimeline* outTimeline) override; - V2_4::Error setAutoLowLatencyMode(Display display, bool on) override; - V2_4::Error getSupportedContentTypes( - Display display, - std::vector<IComposerClient::ContentType>* outSupportedContentTypes) override; - V2_4::Error setContentType(Display display, IComposerClient::ContentType type) override; - V2_4::Error validateDisplay_2_4( - Display display, std::vector<Layer>* outChangedLayers, - std::vector<IComposerClient::Composition>* outCompositionTypes, - uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers, - std::vector<uint32_t>* outRequestMasks, - IComposerClient::ClientTargetProperty* outClientTargetProperty) override; - V2_4::Error setLayerGenericMetadata(Display display, Layer layer, const std::string& key, - bool mandatory, const std::vector<uint8_t>& value) override; - V2_4::Error getLayerGenericMetadataKeys( - std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override; - - void setClient(ComposerClient* client); - - void requestVSync(uint64_t vsyncTime = 0); - // We don't want tests hanging, so always use a timeout. Remember - // to always check the number of frames with test ASSERT_! - // Wait until next frame is rendered after requesting vsync. - void runVSyncAndWait(std::chrono::nanoseconds maxWait = 100ms); - void runVSyncAfter(std::chrono::nanoseconds wait); - - int getFrameCount() const; - // We don't want tests hanging, so always use a timeout. Remember - // to always check the number of frames with test ASSERT_! - void waitUntilFrame(int targetFrame, std::chrono::nanoseconds maxWait = 100ms) const; - std::vector<RenderState> getFrameRects(int frame) const; - std::vector<RenderState> getLatestFrame() const; - void clearFrames(); - - void onSurfaceFlingerStart(); - void onSurfaceFlingerStop(); - - int getLayerCount() const; - Layer getLayer(size_t index) const; - - void hotplugDisplay(Display display, IComposerCallback::Connection state); - void refreshDisplay(Display display); - -private: - LayerImpl& getLayerImpl(Layer handle); - - EventCallback* mEventCallback; - EventCallback_2_4* mEventCallback_2_4; - Config mCurrentConfig; - bool mVsyncEnabled; - std::vector<std::unique_ptr<LayerImpl>> mLayers; - std::vector<std::unique_ptr<Frame>> mFrames; - // Using a pointer to hide the implementation into the CPP file. - std::unique_ptr<DelayedEventGenerator> mDelayedEventGenerator; - android::sp<android::SurfaceComposerClient> mSurfaceComposer; // For VSync injections - mutable android::Mutex mStateMutex; - mutable android::Condition mFramesAvailable; - - MockComposerHal* mMockHal = nullptr; -}; - -} // namespace sftest diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerService.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerService.cpp deleted file mode 100644 index c656eed0fb..0000000000 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerService.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" - -#define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "FakeHwcService" -#include <log/log.h> - -#include "FakeComposerService.h" - -using namespace android::hardware; -using namespace android::hardware::graphics::composer; - -namespace sftest { - -FakeComposerService_2_1::FakeComposerService_2_1(android::sp<ComposerClient>& client) - : mClient(client) {} - -FakeComposerService_2_1::~FakeComposerService_2_1() { - ALOGI("Maybe killing client %p", mClient.get()); - // Rely on sp to kill the client. -} - -Return<void> FakeComposerService_2_1::getCapabilities(getCapabilities_cb hidl_cb) { - ALOGI("FakeComposerService::getCapabilities"); - hidl_cb(hidl_vec<Capability>()); - return Void(); -} - -Return<void> FakeComposerService_2_1::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) { - ALOGI("FakeComposerService::dumpDebugInfo"); - hidl_cb(hidl_string()); - return Void(); -} - -Return<void> FakeComposerService_2_1::createClient(createClient_cb hidl_cb) { - ALOGI("FakeComposerService::createClient %p", mClient.get()); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_1::Error::NONE, mClient); - return Void(); -} - -FakeComposerService_2_2::FakeComposerService_2_2(android::sp<ComposerClient>& client) - : mClient(client) {} - -FakeComposerService_2_2::~FakeComposerService_2_2() { - ALOGI("Maybe killing client %p", mClient.get()); - // Rely on sp to kill the client. -} - -Return<void> FakeComposerService_2_2::getCapabilities(getCapabilities_cb hidl_cb) { - ALOGI("FakeComposerService::getCapabilities"); - hidl_cb(hidl_vec<Capability>()); - return Void(); -} - -Return<void> FakeComposerService_2_2::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) { - ALOGI("FakeComposerService::dumpDebugInfo"); - hidl_cb(hidl_string()); - return Void(); -} - -Return<void> FakeComposerService_2_2::createClient(createClient_cb hidl_cb) { - ALOGI("FakeComposerService::createClient %p", mClient.get()); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_1::Error::NONE, mClient); - return Void(); -} - -FakeComposerService_2_3::FakeComposerService_2_3(android::sp<ComposerClient>& client) - : mClient(client) {} - -FakeComposerService_2_3::~FakeComposerService_2_3() { - ALOGI("Maybe killing client %p", mClient.get()); - // Rely on sp to kill the client. -} - -Return<void> FakeComposerService_2_3::getCapabilities(getCapabilities_cb hidl_cb) { - ALOGI("FakeComposerService::getCapabilities"); - hidl_cb(hidl_vec<Capability>()); - return Void(); -} - -Return<void> FakeComposerService_2_3::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) { - ALOGI("FakeComposerService::dumpDebugInfo"); - hidl_cb(hidl_string()); - return Void(); -} - -Return<void> FakeComposerService_2_3::createClient(createClient_cb hidl_cb) { - LOG_ALWAYS_FATAL("createClient called on FakeComposerService_2_3"); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_1::Error::UNSUPPORTED, nullptr); - return Void(); -} - -Return<void> FakeComposerService_2_3::createClient_2_3(createClient_2_3_cb hidl_cb) { - ALOGI("FakeComposerService_2_3::createClient_2_3 %p", mClient.get()); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_1::Error::NONE, mClient); - return Void(); -} - -FakeComposerService_2_4::FakeComposerService_2_4(android::sp<ComposerClient>& client) - : mClient(client) {} - -FakeComposerService_2_4::~FakeComposerService_2_4() { - ALOGI("Maybe killing client %p", mClient.get()); - // Rely on sp to kill the client. -} - -Return<void> FakeComposerService_2_4::getCapabilities(getCapabilities_cb hidl_cb) { - ALOGI("FakeComposerService::getCapabilities"); - hidl_cb(hidl_vec<Capability>()); - return Void(); -} - -Return<void> FakeComposerService_2_4::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) { - ALOGI("FakeComposerService::dumpDebugInfo"); - hidl_cb(hidl_string()); - return Void(); -} - -Return<void> FakeComposerService_2_4::createClient(createClient_cb hidl_cb) { - LOG_ALWAYS_FATAL("createClient called on FakeComposerService_2_4"); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_1::Error::UNSUPPORTED, nullptr); - return Void(); -} - -Return<void> FakeComposerService_2_4::createClient_2_3(createClient_2_3_cb hidl_cb) { - LOG_ALWAYS_FATAL("createClient_2_3 called on FakeComposerService_2_4"); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_1::Error::UNSUPPORTED, nullptr); - return Void(); -} - -Return<void> FakeComposerService_2_4::createClient_2_4(createClient_2_4_cb hidl_cb) { - ALOGI("FakeComposerService_2_4::createClient_2_4 %p", mClient.get()); - if (!mClient->init()) { - LOG_ALWAYS_FATAL("failed to initialize ComposerClient"); - } - hidl_cb(V2_4::Error::NONE, mClient); - return Void(); -} - -} // namespace sftest - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerService.h b/services/surfaceflinger/tests/fakehwc/FakeComposerService.h deleted file mode 100644 index 47f970f5b2..0000000000 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerService.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2017 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 <android/hardware/graphics/composer/2.4/IComposer.h> -#include <composer-hal/2.1/ComposerClient.h> -#include <composer-hal/2.2/ComposerClient.h> -#include <composer-hal/2.3/ComposerClient.h> -#include <composer-hal/2.4/ComposerClient.h> - -using android::hardware::Return; - -using ComposerClient = android::hardware::graphics::composer::V2_4::hal::ComposerClient; - -namespace sftest { - -using IComposer_2_1 = android::hardware::graphics::composer::V2_1::IComposer; - -class FakeComposerService_2_1 : public IComposer_2_1 { -public: - explicit FakeComposerService_2_1(android::sp<ComposerClient>& client); - virtual ~FakeComposerService_2_1(); - - Return<void> getCapabilities(getCapabilities_cb hidl_cb) override; - Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override; - Return<void> createClient(createClient_cb hidl_cb) override; - -private: - android::sp<ComposerClient> mClient; -}; - -using IComposer_2_2 = android::hardware::graphics::composer::V2_2::IComposer; -class FakeComposerService_2_2 : public IComposer_2_2 { -public: - explicit FakeComposerService_2_2(android::sp<ComposerClient>& client); - virtual ~FakeComposerService_2_2(); - - Return<void> getCapabilities(getCapabilities_cb hidl_cb) override; - Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override; - Return<void> createClient(createClient_cb hidl_cb) override; - -private: - android::sp<ComposerClient> mClient; -}; - -using IComposer_2_3 = android::hardware::graphics::composer::V2_3::IComposer; -class FakeComposerService_2_3 : public IComposer_2_3 { -public: - explicit FakeComposerService_2_3(android::sp<ComposerClient>& client); - virtual ~FakeComposerService_2_3(); - - Return<void> getCapabilities(getCapabilities_cb hidl_cb) override; - Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override; - Return<void> createClient(createClient_cb hidl_cb) override; - Return<void> createClient_2_3(createClient_2_3_cb hidl_cb) override; - -private: - android::sp<ComposerClient> mClient; -}; - -using IComposer_2_4 = android::hardware::graphics::composer::V2_4::IComposer; - -class FakeComposerService_2_4 : public IComposer_2_4 { -public: - explicit FakeComposerService_2_4(android::sp<ComposerClient>& client); - virtual ~FakeComposerService_2_4(); - - Return<void> getCapabilities(getCapabilities_cb hidl_cb) override; - Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override; - Return<void> createClient(createClient_cb hidl_cb) override; - Return<void> createClient_2_3(createClient_2_3_cb hidl_cb) override; - Return<void> createClient_2_4(createClient_2_4_cb hidl_cb) override; - -private: - android::sp<ComposerClient> mClient; -}; - -} // namespace sftest diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp deleted file mode 100644 index 1cea25a80f..0000000000 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2017 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. - */ - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" - -#define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "FakeHwcUtil" -#include <log/log.h> - -#include "FakeComposerUtils.h" -#include "RenderState.h" - -#include "SurfaceFlinger.h" // Get the name of the service... - -#include <binder/IServiceManager.h> -#include <cutils/properties.h> -#include <hidl/ServiceManagement.h> - -#include <iomanip> -#include <thread> - -using android::String16; -using android::sp; -using namespace std::chrono_literals; -using namespace sftest; -using std::setw; - -namespace sftest { - -// clang-format off -inline void printSourceRectAligned(::std::ostream& os, const hwc_frect_t& sourceRect, int align) { - os << std::fixed << std::setprecision(1) << "(" - << setw(align) << sourceRect.left << setw(0) << "," - << setw(align) << sourceRect.top << setw(0) << "," - << setw(align) << sourceRect.right << setw(0) << "," - << setw(align) << sourceRect.bottom << setw(0) << ")"; -} - -inline void printDisplayRectAligned(::std::ostream& os, const hwc_rect_t& displayRect, int align) { - os << "(" - << setw(align) << displayRect.left << setw(0) << "," - << setw(align) << displayRect.top << setw(0) << "," - << setw(align) << displayRect.right << setw(0) << "," - << setw(align) << displayRect.bottom << setw(0) << ")"; -} -// clang-format on - -inline ::std::ostream& operator<<(::std::ostream& os, const sftest::RenderState& state) { - printSourceRectAligned(os, state.mSourceCrop, 7); - os << "->"; - printDisplayRectAligned(os, state.mDisplayFrame, 5); - return os << " Swaps:" << state.mSwapCount << " Alpha:" << std::setprecision(3) - << state.mPlaneAlpha << " Xform:" << state.mTransform; -} - -// Helper for verifying the parts of the RenderState -template <typename T> -bool valuesMatch(::testing::AssertionResult& message, const T& ref, const T& val, - const char* name) { - if (ref != val) { - message = message << "Expected " << name << ":" << ref << ", got:" << val << "."; - return false; - } - return true; -} - -::testing::AssertionResult rectsAreSame(const RenderState& ref, const RenderState& val) { - // TODO: Message could start as success and be assigned as failure. - // Only problem is that utility assumes it to be failure and just adds stuff. Would - // need still special case the initial failure in the utility? - // TODO: ... or would it be possible to break this back to gtest primitives? - ::testing::AssertionResult message = ::testing::AssertionFailure(); - bool passes = true; - - // The work here is mostly about providing good log strings for differences - passes &= valuesMatch(message, ref.mDisplayFrame, val.mDisplayFrame, "display frame"); - passes &= valuesMatch(message, ref.mPlaneAlpha, val.mPlaneAlpha, "alpha"); - passes &= valuesMatch(message, ref.mSwapCount, val.mSwapCount, "swap count"); - passes &= valuesMatch(message, ref.mSourceCrop, val.mSourceCrop, "source crop"); - // ... add more - if (passes) { - return ::testing::AssertionSuccess(); - } - return message; -} - -::testing::AssertionResult framesAreSame(const std::vector<RenderState>& ref, - const std::vector<RenderState>& val) { - ::testing::AssertionResult message = ::testing::AssertionFailure(); - bool passed = true; - if (ref.size() != val.size()) { - message << "Expected " << ref.size() << " rects, got " << val.size() << "."; - passed = false; - } - for (size_t rectIndex = 0; rectIndex < std::min(ref.size(), val.size()); rectIndex++) { - ::testing::AssertionResult rectResult = rectsAreSame(ref[rectIndex], val[rectIndex]); - if (rectResult == false) { - message << "First different rect at " << rectIndex << ": " << rectResult.message(); - passed = false; - break; - } - } - - if (passed) { - return ::testing::AssertionSuccess(); - } else { - message << "\nReference:"; - for (auto state = ref.begin(); state != ref.end(); ++state) { - message << "\n" << *state; - } - message << "\nActual:"; - for (auto state = val.begin(); state != val.end(); ++state) { - message << "\n" << *state; - } - } - return message; -} - -void startSurfaceFlinger() { - ALOGI("Start SurfaceFlinger"); - system("start surfaceflinger"); - - sp<android::IServiceManager> sm(android::defaultServiceManager()); - sp<android::IBinder> sf; - while (sf == nullptr) { - std::this_thread::sleep_for(10ms); - sf = sm->checkService(String16(android::SurfaceFlinger::getServiceName())); - } - ALOGV("SurfaceFlinger running"); -} - -void stopSurfaceFlinger() { - ALOGI("Stop SurfaceFlinger"); - system("stop surfaceflinger"); - sp<android::IServiceManager> sm(android::defaultServiceManager()); - sp<android::IBinder> sf; - while (sf != nullptr) { - std::this_thread::sleep_for(10ms); - sf = sm->checkService(String16(android::SurfaceFlinger::getServiceName())); - } - ALOGV("SurfaceFlinger stopped"); -} - -//////////////////////////////////////////////// - -void FakeHwcEnvironment::SetUp() { - ALOGI("Test env setup"); - system("setenforce 0"); - system("stop"); - property_set("debug.sf.nobootanimation", "1"); - { - char value[PROPERTY_VALUE_MAX]; - property_get("debug.sf.nobootanimation", value, "0"); - LOG_FATAL_IF(atoi(value) != 1, "boot skip not set"); - } - // TODO: Try registering the mock as the default service instead. - property_set("debug.sf.hwc_service_name", "mock"); - - // This allows tests/SF to register/load a HIDL service not listed in manifest files. - android::hardware::details::setTrebleTestingOverride(true); - property_set("debug.sf.treble_testing_override", "true"); -} - -void FakeHwcEnvironment::TearDown() { - ALOGI("Test env tear down"); - system("stop"); - // Wait for mock call signaling teardown? - property_set("debug.sf.nobootanimation", "0"); - property_set("debug.sf.hwc_service_name", "default"); - system("setenforce 1"); - ALOGI("Test env tear down - done"); -} - -} // namespace sftest - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h deleted file mode 100644 index 383a111859..0000000000 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2017 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 "FakeComposerClient.h" - -#include <gui/SurfaceComposerClient.h> -#include <log/log.h> -#include <gtest/gtest.h> - -// clang-format off -// Note: This needs to reside in the global namespace for the GTest to use it -inline ::std::ostream& operator<<(::std::ostream& os, const hwc_rect_t& rect) { - return os << "(" << rect.left << "," - << rect.top << "," - << rect.right << "," - << rect.bottom << ")"; -} - -inline ::std::ostream& operator<<(::std::ostream& os, const hwc_frect_t& rect) { - return os << "(" << rect.left << "," - << rect.top << "," - << rect.right << "," - << rect.bottom << ")"; -} -// clang-format on - -namespace sftest { - -class RenderState; - -// clang-format off -inline bool operator==(const hwc_rect_t& a, const hwc_rect_t& b) { - return a.top == b.top && - a.left == b.left && - a.bottom == b.bottom && - a.right == b.right; -} - -inline bool operator==(const hwc_frect_t& a, const hwc_frect_t& b) { - return a.top == b.top && - a.left == b.left && - a.bottom == b.bottom && - a.right == b.right; -} -// clang-format on - -inline bool operator!=(const hwc_rect_t& a, const hwc_rect_t& b) { - return !(a == b); -} - -inline bool operator!=(const hwc_frect_t& a, const hwc_frect_t& b) { - return !(a == b); -} - -::testing::AssertionResult rectsAreSame(const RenderState& ref, const RenderState& val); -::testing::AssertionResult framesAreSame(const std::vector<RenderState>& ref, - const std::vector<RenderState>& val); - -void startSurfaceFlinger(); -void stopSurfaceFlinger(); - -class FakeHwcEnvironment : public ::testing::Environment { -public: - virtual ~FakeHwcEnvironment() {} - void SetUp() override; - void TearDown() override; -}; - -/* - * All surface state changes are supposed to happen inside a global - * transaction. TransactionScope object at the beginning of - * scope automates the process. The resulting scope gives a visual cue - * on the span of the transaction as well. - * - * Closing the transaction is synchronous, i.e., it waits for - * SurfaceFlinger to composite one frame. Now, the FakeComposerClient - * is built to explicitly request vsyncs one at the time. A delayed - * request must be made before closing the transaction or the test - * thread stalls until SurfaceFlinger does an emergency vsync by - * itself. TransactionScope encapsulates this vsync magic. - */ -class TransactionScope : public android::SurfaceComposerClient::Transaction { -public: - explicit TransactionScope(FakeComposerClient& composer) : Transaction(), mComposer(composer) {} - - ~TransactionScope() { - int frameCount = mComposer.getFrameCount(); - mComposer.runVSyncAfter(1ms); - LOG_ALWAYS_FATAL_IF(android::NO_ERROR != apply()); - // Make sure that exactly one frame has been rendered. - mComposer.waitUntilFrame(frameCount + 1); - // LOG_ALWAYS_FATAL_IF(frameCount + 1 != mComposer.getFrameCount(), - // "Unexpected frame advance. Delta: %d", - // mComposer.getFrameCount() - frameCount); - } - - FakeComposerClient& mComposer; -}; - -} // namespace sftest diff --git a/services/surfaceflinger/tests/fakehwc/MockComposerHal.h b/services/surfaceflinger/tests/fakehwc/MockComposerHal.h deleted file mode 100644 index 5dc3778153..0000000000 --- a/services/surfaceflinger/tests/fakehwc/MockComposerHal.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 <composer-hal/2.4/ComposerClient.h> - -#include <gmock/gmock.h> - -using namespace android::hardware::graphics::common; -using namespace android::hardware::graphics::composer; -using namespace android::hardware::graphics::composer::V2_4; -using namespace android::hardware::graphics::composer::V2_4::hal; -using namespace android::hardware; -using namespace std::chrono_literals; - -namespace sftest { - -// Mock class for ComposerHal. Implements only the functions used in the test. -class MockComposerHal { -public: - MOCK_METHOD2(getActiveConfig, V2_1::Error(Display, Config*)); - MOCK_METHOD4(getDisplayAttribute_2_4, - V2_4::Error(Display, Config, V2_4::IComposerClient::Attribute, int32_t*)); - MOCK_METHOD2(getDisplayConfigs, V2_1::Error(Display, hidl_vec<Config>*)); - MOCK_METHOD2(setActiveConfig, V2_1::Error(Display, Config)); - MOCK_METHOD2(getDisplayVsyncPeriod, V2_4::Error(Display, V2_4::VsyncPeriodNanos*)); - MOCK_METHOD4(setActiveConfigWithConstraints, - V2_4::Error(Display, Config, - const V2_4::IComposerClient::VsyncPeriodChangeConstraints&, - VsyncPeriodChangeTimeline*)); -}; - -} // namespace sftest
\ No newline at end of file diff --git a/services/surfaceflinger/tests/fakehwc/RenderState.h b/services/surfaceflinger/tests/fakehwc/RenderState.h deleted file mode 100644 index 40193f237e..0000000000 --- a/services/surfaceflinger/tests/fakehwc/RenderState.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2017 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 <vector> - -namespace sftest { -// Description of a rendered rectangle. Should only contain -// instructions necessary to rasterize the rectangle. The full scene -// is given as a sorted list of rectangles, bottom layer at index 0. -class RenderState { -public: - RenderState() = default; - // Default copy-ctor - - hwc_rect_t mDisplayFrame = {0, 0, 0, 0}; - hwc_frect_t mSourceCrop = {0.f, 0.f, 0.f, 0.f}; - std::vector<hwc_rect_t> mVisibleRegion; - hwc2_blend_mode_t mBlendMode = HWC2_BLEND_MODE_NONE; - buffer_handle_t mBuffer = 0; - uint32_t mSwapCount = 0; // How many set buffer calls to the layer. - int32_t mAcquireFence = 0; // Probably should not be here. - float mPlaneAlpha = 0.f; - hwc_color_t mLayerColor = {0, 0, 0, 0}; - hwc_transform_t mTransform = static_cast<hwc_transform_t>(0); -}; - -} // namespace sftest diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp deleted file mode 100644 index 1d3401aa0f..0000000000 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ /dev/null @@ -1,1794 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wextra" - -// #define LOG_NDEBUG 0 -#undef LOG_TAG -#define LOG_TAG "FakeHwcTest" - -#include "FakeComposerClient.h" -#include "FakeComposerService.h" -#include "FakeComposerUtils.h" -#include "MockComposerHal.h" - -#include <binder/Parcel.h> -#include <gui/AidlStatusUtil.h> -#include <gui/DisplayEventReceiver.h> -#include <gui/ISurfaceComposer.h> -#include <gui/LayerDebugInfo.h> -#include <gui/LayerState.h> -#include <gui/Surface.h> -#include <gui/SurfaceComposerClient.h> - -#include <android/hidl/manager/1.0/IServiceManager.h> -#include <android/looper.h> -#include <android/native_window.h> -#include <binder/ProcessState.h> -#include <hwbinder/ProcessState.h> -#include <log/log.h> -#include <private/gui/ComposerService.h> -#include <private/gui/ComposerServiceAIDL.h> -#include <ui/DisplayMode.h> -#include <ui/DynamicDisplayInfo.h> -#include <utils/Looper.h> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <limits> -#include <thread> - -using namespace std::chrono_literals; - -using namespace android; -using namespace android::hardware; - -using namespace sftest; - -namespace { - -// Mock test helpers -using ::testing::_; -using ::testing::DoAll; -using ::testing::Return; -using ::testing::SetArgPointee; - -using Transaction = SurfaceComposerClient::Transaction; -using Attribute = V2_4::IComposerClient::Attribute; -using Display = V2_1::Display; - -/////////////////////////////////////////////// -constexpr PhysicalDisplayId physicalIdFromHwcDisplayId(Display hwcId) { - return PhysicalDisplayId::fromPort(hwcId); -} -constexpr PhysicalDisplayId kPrimaryDisplayId = physicalIdFromHwcDisplayId(PRIMARY_DISPLAY); -constexpr PhysicalDisplayId kExternalDisplayId = physicalIdFromHwcDisplayId(EXTERNAL_DISPLAY); - -struct TestColor { -public: - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; -}; - -constexpr static TestColor RED = {195, 63, 63, 255}; -constexpr static TestColor LIGHT_RED = {255, 177, 177, 255}; -constexpr static TestColor GREEN = {63, 195, 63, 255}; -constexpr static TestColor BLUE = {63, 63, 195, 255}; -constexpr static TestColor LIGHT_GRAY = {200, 200, 200, 255}; - -// Fill an RGBA_8888 formatted surface with a single color. -static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, const TestColor& color, - bool unlock = true) { - ANativeWindow_Buffer outBuffer; - sp<Surface> s = sc->getSurface(); - ASSERT_TRUE(s != nullptr); - ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr)); - uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits); - for (int y = 0; y < outBuffer.height; y++) { - for (int x = 0; x < outBuffer.width; x++) { - uint8_t* pixel = img + (4 * (y * outBuffer.stride + x)); - pixel[0] = color.r; - pixel[1] = color.g; - pixel[2] = color.b; - pixel[3] = color.a; - } - } - if (unlock) { - ASSERT_EQ(NO_ERROR, s->unlockAndPost()); - } -} - -inline RenderState makeSimpleRect(int left, int top, int right, int bottom) { - RenderState res; - res.mDisplayFrame = hwc_rect_t{left, top, right, bottom}; - res.mPlaneAlpha = 1.0f; - res.mSwapCount = 0; - res.mSourceCrop = hwc_frect_t{0.f, 0.f, static_cast<float>(right - left), - static_cast<float>(bottom - top)}; - return res; -} - -inline RenderState makeSimpleRect(unsigned int left, unsigned int top, unsigned int right, - unsigned int bottom) { - EXPECT_LE(left, static_cast<unsigned int>(INT_MAX)); - EXPECT_LE(top, static_cast<unsigned int>(INT_MAX)); - EXPECT_LE(right, static_cast<unsigned int>(INT_MAX)); - EXPECT_LE(bottom, static_cast<unsigned int>(INT_MAX)); - return makeSimpleRect(static_cast<int>(left), static_cast<int>(top), static_cast<int>(right), - static_cast<int>(bottom)); -} - -/////////////////////////////////////////////// -template <typename FakeComposerService> -class DisplayTest : public ::testing::Test { -protected: - struct TestConfig { - int32_t id; - int32_t w; - int32_t h; - int32_t vsyncPeriod; - int32_t group; - }; - - static int processDisplayEvents(int /*fd*/, int /*events*/, void* data) { - auto self = static_cast<DisplayTest*>(data); - - ssize_t n; - DisplayEventReceiver::Event buffer[1]; - - while ((n = self->mReceiver->getEvents(buffer, 1)) > 0) { - for (int i = 0; i < n; i++) { - self->mReceivedDisplayEvents.push_back(buffer[i]); - } - } - ALOGD_IF(n < 0, "Error reading events (%s)", strerror(-n)); - return 1; - } - - Error getDisplayAttributeNoMock(Display display, Config config, - V2_4::IComposerClient::Attribute attribute, int32_t* outValue) { - mFakeComposerClient->setMockHal(nullptr); - auto ret = - mFakeComposerClient->getDisplayAttribute_2_4(display, config, attribute, outValue); - mFakeComposerClient->setMockHal(mMockComposer.get()); - return ret; - } - - void setExpectationsForConfigs(Display display, std::vector<TestConfig> testConfigs, - Config activeConfig, V2_4::VsyncPeriodNanos defaultVsyncPeriod) { - std::vector<Config> configIds; - for (size_t i = 0; i < testConfigs.size(); i++) { - configIds.push_back(testConfigs[i].id); - - EXPECT_CALL(*mMockComposer, - getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::WIDTH, _)) - .WillRepeatedly(DoAll(SetArgPointee<3>(testConfigs[i].w), Return(Error::NONE))); - EXPECT_CALL(*mMockComposer, - getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::HEIGHT, _)) - .WillRepeatedly(DoAll(SetArgPointee<3>(testConfigs[i].h), Return(Error::NONE))); - EXPECT_CALL(*mMockComposer, - getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::VSYNC_PERIOD, - _)) - .WillRepeatedly(DoAll(SetArgPointee<3>(testConfigs[i].vsyncPeriod), - Return(Error::NONE))); - EXPECT_CALL(*mMockComposer, - getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::CONFIG_GROUP, - _)) - .WillRepeatedly( - DoAll(SetArgPointee<3>(testConfigs[i].group), Return(Error::NONE))); - EXPECT_CALL(*mMockComposer, - getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::DPI_X, _)) - .WillRepeatedly(Return(Error::UNSUPPORTED)); - EXPECT_CALL(*mMockComposer, - getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::DPI_Y, _)) - .WillRepeatedly(Return(Error::UNSUPPORTED)); - } - - EXPECT_CALL(*mMockComposer, getDisplayConfigs(display, _)) - .WillRepeatedly(DoAll(SetArgPointee<1>(hidl_vec<Config>(configIds)), - Return(V2_1::Error::NONE))); - - EXPECT_CALL(*mMockComposer, getActiveConfig(display, _)) - .WillRepeatedly(DoAll(SetArgPointee<1>(activeConfig), Return(V2_1::Error::NONE))); - - EXPECT_CALL(*mMockComposer, getDisplayVsyncPeriod(display, _)) - .WillRepeatedly( - DoAll(SetArgPointee<1>(defaultVsyncPeriod), Return(V2_4::Error::NONE))); - } - - void SetUp() override { - mMockComposer = std::make_unique<MockComposerHal>(); - mFakeComposerClient = new FakeComposerClient(); - mFakeComposerClient->setMockHal(mMockComposer.get()); - - auto client = sp<V2_4::hal::ComposerClient>::make(mFakeComposerClient); - mFakeService = sp<FakeComposerService>::make(client); - ASSERT_EQ(android::OK, mFakeService->registerAsService("mock")); - - android::hardware::ProcessState::self()->startThreadPool(); - android::ProcessState::self()->startThreadPool(); - - setExpectationsForConfigs(PRIMARY_DISPLAY, - {{ - .id = 1, - .w = 1920, - .h = 1024, - .vsyncPeriod = 16'666'666, - .group = 0, - }}, - 1, 16'666'666); - - startSurfaceFlinger(); - - // Fake composer wants to enable VSync injection - mFakeComposerClient->onSurfaceFlingerStart(); - - mComposerClient = sp<SurfaceComposerClient>::make(); - ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); - - mReceiver.reset( - new DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - gui::ISurfaceComposer::EventRegistration::modeChanged)); - mLooper = sp<Looper>::make(false); - mLooper->addFd(mReceiver->getFd(), 0, ALOOPER_EVENT_INPUT, processDisplayEvents, this); - } - - void TearDown() override { - mLooper = nullptr; - mReceiver = nullptr; - - mComposerClient->dispose(); - mComposerClient = nullptr; - - // Fake composer needs to release SurfaceComposerClient before the stop. - mFakeComposerClient->onSurfaceFlingerStop(); - stopSurfaceFlinger(); - - mFakeComposerClient->setMockHal(nullptr); - - mFakeService = nullptr; - // TODO: Currently deleted in FakeComposerClient::removeClient(). Devise better lifetime - // management. - mMockComposer = nullptr; - } - - void waitForDisplayTransaction(Display display) { - // Both a refresh and a vsync event are needed to apply pending display - // transactions. - mFakeComposerClient->refreshDisplay(display); - mFakeComposerClient->runVSyncAndWait(); - - // Extra vsync and wait to avoid a 10% flake due to a race. - mFakeComposerClient->runVSyncAndWait(); - } - - bool waitForHotplugEvent(Display displayId, bool connected) { - return waitForHotplugEvent(physicalIdFromHwcDisplayId(displayId), connected); - } - - bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) { - int waitCount = 20; - while (waitCount--) { - while (!mReceivedDisplayEvents.empty()) { - auto event = mReceivedDisplayEvents.front(); - mReceivedDisplayEvents.pop_front(); - - ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, - "event hotplug: displayId %s, connected %d", - to_string(event.header.displayId).c_str(), event.hotplug.connected); - - if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG && - event.header.displayId == displayId && event.hotplug.connected == connected) { - return true; - } - } - - mLooper->pollOnce(1); - } - return false; - } - - bool waitForModeChangedEvent(Display display, int32_t modeId) { - PhysicalDisplayId displayId = physicalIdFromHwcDisplayId(display); - int waitCount = 20; - while (waitCount--) { - while (!mReceivedDisplayEvents.empty()) { - auto event = mReceivedDisplayEvents.front(); - mReceivedDisplayEvents.pop_front(); - - ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, - "event mode: displayId %s, modeId %d", - to_string(event.header.displayId).c_str(), event.modeChange.modeId); - - if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE && - event.header.displayId == displayId && event.modeChange.modeId == modeId) { - return true; - } - } - - mLooper->pollOnce(1); - } - return false; - } - - void Test_HotplugOneConfig() { - ALOGD("DisplayTest::Test_Hotplug_oneConfig"); - - setExpectationsForConfigs(EXTERNAL_DISPLAY, - {{.id = 1, - .w = 200, - .h = 400, - .vsyncPeriod = 16'666'666, - .group = 0}}, - 1, 16'666'666); - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::CONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); - - { - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId); - EXPECT_FALSE(display == nullptr); - - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - const ui::Size& resolution = mode.resolution; - EXPECT_EQ(ui::Size(200, 400), resolution); - EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate); - - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::DISCONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - mFakeComposerClient->clearFrames(); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false)); - - { - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId); - EXPECT_TRUE(display == nullptr); - - ui::DisplayMode mode; - EXPECT_NE(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - } - } - - void Test_HotplugTwoSeparateConfigs() { - ALOGD("DisplayTest::Test_HotplugTwoSeparateConfigs"); - - setExpectationsForConfigs(EXTERNAL_DISPLAY, - {{.id = 1, - .w = 200, - .h = 400, - .vsyncPeriod = 16'666'666, - .group = 0}, - {.id = 2, - .w = 800, - .h = 1600, - .vsyncPeriod = 11'111'111, - .group = 1}}, - 1, 16'666'666); - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::CONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); - - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId); - EXPECT_FALSE(display == nullptr); - - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(200, 400), mode.resolution); - EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - ui::DynamicDisplayInfo info; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info)); - const auto& modes = info.supportedDisplayModes; - EXPECT_EQ(modes.size(), 2); - - // change active mode - - if (mIs2_4Client) { - EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 2, _, _)) - .WillOnce(Return(V2_4::Error::NONE)); - } else { - EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 2)) - .WillOnce(Return(V2_1::Error::NONE)); - } - - for (int i = 0; i < modes.size(); i++) { - const auto& mode = modes[i]; - if (mode.resolution.getWidth() == 800) { - EXPECT_EQ(NO_ERROR, - SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate)); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i)); - break; - } - } - - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::DISCONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - mFakeComposerClient->clearFrames(); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false)); - } - - void Test_HotplugTwoConfigsSameGroup() { - ALOGD("DisplayTest::Test_HotplugTwoConfigsSameGroup"); - - setExpectationsForConfigs(EXTERNAL_DISPLAY, - {{.id = 2, - .w = 800, - .h = 1600, - .vsyncPeriod = 16'666'666, - .group = 31}, - {.id = 3, - .w = 800, - .h = 1600, - .vsyncPeriod = 11'111'111, - .group = 31}}, - 2, 16'666'666); - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::CONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); - - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId); - EXPECT_FALSE(display == nullptr); - - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - ui::DynamicDisplayInfo info; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info)); - const auto& modes = info.supportedDisplayModes; - EXPECT_EQ(modes.size(), 2); - - // change active mode - if (mIs2_4Client) { - EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 3, _, _)) - .WillOnce(Return(V2_4::Error::NONE)); - } else { - EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 3)) - .WillOnce(Return(V2_1::Error::NONE)); - } - - for (int i = 0; i < modes.size(); i++) { - const auto& mode = modes[i]; - if (mode.refreshRate == 1e9f / 11'111'111) { - EXPECT_EQ(NO_ERROR, - SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate)); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i)); - break; - } - } - - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::DISCONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - mFakeComposerClient->clearFrames(); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false)); - } - - void Test_HotplugThreeConfigsMixedGroups() { - ALOGD("DisplayTest::Test_HotplugThreeConfigsMixedGroups"); - - setExpectationsForConfigs(EXTERNAL_DISPLAY, - {{.id = 2, - .w = 800, - .h = 1600, - .vsyncPeriod = 16'666'666, - .group = 0}, - {.id = 3, - .w = 800, - .h = 1600, - .vsyncPeriod = 11'111'111, - .group = 0}, - {.id = 4, - .w = 1600, - .h = 3200, - .vsyncPeriod = 8'333'333, - .group = 1}, - {.id = 5, - .w = 1600, - .h = 3200, - .vsyncPeriod = 11'111'111, - .group = 1}}, - 2, 16'666'666); - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::CONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); - - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId); - EXPECT_FALSE(display == nullptr); - - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - ui::DynamicDisplayInfo info; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info)); - const auto& modes = info.supportedDisplayModes; - EXPECT_EQ(modes.size(), 4); - - // change active mode to 800x1600@90Hz - if (mIs2_4Client) { - EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 3, _, _)) - .WillOnce(Return(V2_4::Error::NONE)); - } else { - EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 3)) - .WillOnce(Return(V2_1::Error::NONE)); - } - - for (size_t i = 0; i < modes.size(); i++) { - const auto& mode = modes[i]; - if (mode.resolution.getWidth() == 800 && mode.refreshRate == 1e9f / 11'111'111) { - EXPECT_EQ(NO_ERROR, - SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false, - modes[i].refreshRate, - modes[i].refreshRate, - modes[i].refreshRate, - modes[i].refreshRate)); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i)); - break; - } - } - - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - // change active mode to 1600x3200@120Hz - if (mIs2_4Client) { - EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 4, _, _)) - .WillOnce(Return(V2_4::Error::NONE)); - } else { - EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 4)) - .WillOnce(Return(V2_1::Error::NONE)); - } - - for (int i = 0; i < modes.size(); i++) { - const auto& mode = modes[i]; - if (mode.refreshRate == 1e9f / 8'333'333) { - EXPECT_EQ(NO_ERROR, - SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate)); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i)); - break; - } - } - - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(1600, 3200), mode.resolution); - EXPECT_EQ(1e9f / 8'333'333, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - // change active mode to 1600x3200@90Hz - if (mIs2_4Client) { - EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 5, _, _)) - .WillOnce(Return(V2_4::Error::NONE)); - } else { - EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 5)) - .WillOnce(Return(V2_1::Error::NONE)); - } - - for (int i = 0; i < modes.size(); i++) { - const auto& mode = modes[i]; - if (mode.resolution.getWidth() == 1600 && mode.refreshRate == 1e9f / 11'111'111) { - EXPECT_EQ(NO_ERROR, - SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate, - mode.refreshRate)); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i)); - break; - } - } - - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(1600, 3200), mode.resolution); - EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate); - - mFakeComposerClient->clearFrames(); - { - const ui::Size& resolution = mode.resolution; - auto surfaceControl = - mComposerClient->createSurface(String8("Display Test Surface Foo"), - resolution.getWidth(), resolution.getHeight(), - PIXEL_FORMAT_RGBA_8888, 0); - EXPECT_TRUE(surfaceControl != nullptr); - EXPECT_TRUE(surfaceControl->isValid()); - fillSurfaceRGBA8(surfaceControl, BLUE); - - { - TransactionScope ts(*mFakeComposerClient); - ts.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl); - } - } - - mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY, - V2_1::IComposerCallback::Connection::DISCONNECTED); - waitForDisplayTransaction(EXTERNAL_DISPLAY); - mFakeComposerClient->clearFrames(); - EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false)); - } - - void Test_HotplugPrimaryDisplay() { - ALOGD("DisplayTest::HotplugPrimaryDisplay"); - - mFakeComposerClient->hotplugDisplay(PRIMARY_DISPLAY, - V2_1::IComposerCallback::Connection::DISCONNECTED); - - waitForDisplayTransaction(PRIMARY_DISPLAY); - - EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, false)); - { - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kPrimaryDisplayId); - EXPECT_TRUE(display == nullptr); - - ui::DisplayMode mode; - auto result = SurfaceComposerClient::getActiveDisplayMode(display, &mode); - EXPECT_NE(NO_ERROR, result); - } - - mFakeComposerClient->clearFrames(); - - setExpectationsForConfigs(PRIMARY_DISPLAY, - {{.id = 1, - .w = 400, - .h = 200, - .vsyncPeriod = 16'666'666, - .group = 0}}, - 1, 16'666'666); - - mFakeComposerClient->hotplugDisplay(PRIMARY_DISPLAY, - V2_1::IComposerCallback::Connection::CONNECTED); - - waitForDisplayTransaction(PRIMARY_DISPLAY); - - EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, true)); - - { - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kPrimaryDisplayId); - EXPECT_FALSE(display == nullptr); - - ui::DisplayMode mode; - auto result = SurfaceComposerClient::getActiveDisplayMode(display, &mode); - EXPECT_EQ(NO_ERROR, result); - ASSERT_EQ(ui::Size(400, 200), mode.resolution); - EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate); - } - } - - void Test_SubsequentHotplugConnectUpdatesDisplay(Display hwcDisplayId) { - ALOGD("DisplayTest::Test_SubsequentHotplugConnectUpdatesDisplay"); - - // Send a hotplug connected event to set up the initial display modes. - // The primary display is already connected so this will update it. - // If we're running the test of an external display this will create it. - setExpectationsForConfigs(hwcDisplayId, - {{.id = 1, - .w = 800, - .h = 1600, - .vsyncPeriod = 11'111'111, - .group = 1}}, - /* activeConfig */ 1, 11'111'111); - - mFakeComposerClient->hotplugDisplay(hwcDisplayId, - V2_1::IComposerCallback::Connection::CONNECTED); - waitForDisplayTransaction(hwcDisplayId); - EXPECT_TRUE(waitForHotplugEvent(hwcDisplayId, true)); - - const auto displayId = physicalIdFromHwcDisplayId(hwcDisplayId); - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(displayId); - EXPECT_FALSE(display == nullptr); - - // Verify that the active mode and the supported moded are updated - { - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate); - - ui::DynamicDisplayInfo info; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info)); - const auto& modes = info.supportedDisplayModes; - EXPECT_EQ(modes.size(), 1); - } - - // Send another hotplug connected event - setExpectationsForConfigs(hwcDisplayId, - { - {.id = 1, - .w = 800, - .h = 1600, - .vsyncPeriod = 16'666'666, - .group = 1}, - {.id = 2, - .w = 800, - .h = 1600, - .vsyncPeriod = 11'111'111, - .group = 1}, - {.id = 3, - .w = 800, - .h = 1600, - .vsyncPeriod = 8'333'333, - .group = 1}, - }, - /* activeConfig */ 1, 16'666'666); - - mFakeComposerClient->hotplugDisplay(hwcDisplayId, - V2_1::IComposerCallback::Connection::CONNECTED); - waitForDisplayTransaction(hwcDisplayId); - EXPECT_TRUE(waitForHotplugEvent(hwcDisplayId, true)); - - // Verify that the active mode and the supported moded are updated - { - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate); - } - - ui::DynamicDisplayInfo info; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info)); - const auto& modes = info.supportedDisplayModes; - EXPECT_EQ(modes.size(), 3); - - EXPECT_EQ(ui::Size(800, 1600), modes[0].resolution); - EXPECT_EQ(1e9f / 16'666'666, modes[0].refreshRate); - - EXPECT_EQ(ui::Size(800, 1600), modes[1].resolution); - EXPECT_EQ(1e9f / 11'111'111, modes[1].refreshRate); - - EXPECT_EQ(ui::Size(800, 1600), modes[2].resolution); - EXPECT_EQ(1e9f / 8'333'333, modes[2].refreshRate); - - // Verify that we are able to switch to any of the modes - for (int i = modes.size() - 1; i >= 0; i--) { - const auto hwcId = i + 1; - // Set up HWC expectations for the mode change - if (mIs2_4Client) { - EXPECT_CALL(*mMockComposer, - setActiveConfigWithConstraints(hwcDisplayId, hwcId, _, _)) - .WillOnce(Return(V2_4::Error::NONE)); - } else { - EXPECT_CALL(*mMockComposer, setActiveConfig(hwcDisplayId, hwcId)) - .WillOnce(Return(V2_1::Error::NONE)); - } - - EXPECT_EQ(NO_ERROR, - SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false, - modes[i].refreshRate, - modes[i].refreshRate, - modes[i].refreshRate, - modes[i].refreshRate)); - // We need to refresh twice - once to apply the pending mode change request, - // and once to process the change. - waitForDisplayTransaction(hwcDisplayId); - waitForDisplayTransaction(hwcDisplayId); - EXPECT_TRUE(waitForModeChangedEvent(hwcDisplayId, i)) - << "Failure while switching to mode " << i; - - ui::DisplayMode mode; - EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - EXPECT_EQ(ui::Size(800, 1600), mode.resolution); - EXPECT_EQ(modes[i].refreshRate, mode.refreshRate); - } - } - - sp<V2_1::IComposer> mFakeService; - sp<SurfaceComposerClient> mComposerClient; - - std::unique_ptr<MockComposerHal> mMockComposer; - FakeComposerClient* mFakeComposerClient; - - std::unique_ptr<DisplayEventReceiver> mReceiver; - sp<Looper> mLooper; - std::deque<DisplayEventReceiver::Event> mReceivedDisplayEvents; - - static constexpr bool mIs2_4Client = - std::is_same<FakeComposerService, FakeComposerService_2_4>::value; -}; - -using DisplayTest_2_1 = DisplayTest<FakeComposerService_2_1>; - -// Tests that VSYNC injection can be safely toggled while invalidating. -TEST_F(DisplayTest_2_1, VsyncInjection) { - const auto flinger = ComposerServiceAIDL::getComposerService(); - bool enable = true; - - for (int i = 0; i < 100; i++) { - flinger->enableVSyncInjections(enable); - enable = !enable; - - constexpr uint32_t kForceInvalidate = 1004; - android::Parcel data, reply; - data.writeInterfaceToken(String16("android.ui.ISurfaceComposer")); - EXPECT_EQ(NO_ERROR, - android::IInterface::asBinder(flinger)->transact(kForceInvalidate, data, &reply)); - - std::this_thread::sleep_for(5ms); - } -} - -TEST_F(DisplayTest_2_1, HotplugOneConfig) { - Test_HotplugOneConfig(); -} - -TEST_F(DisplayTest_2_1, HotplugTwoSeparateConfigs) { - Test_HotplugTwoSeparateConfigs(); -} - -TEST_F(DisplayTest_2_1, HotplugTwoConfigsSameGroup) { - Test_HotplugTwoConfigsSameGroup(); -} - -TEST_F(DisplayTest_2_1, HotplugThreeConfigsMixedGroups) { - Test_HotplugThreeConfigsMixedGroups(); -} - -TEST_F(DisplayTest_2_1, HotplugPrimaryOneConfig) { - Test_HotplugPrimaryDisplay(); -} - -TEST_F(DisplayTest_2_1, SubsequentHotplugConnectUpdatesPrimaryDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY); -} - -TEST_F(DisplayTest_2_1, SubsequentHotplugConnectUpdatesExternalDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY); -} - -using DisplayTest_2_2 = DisplayTest<FakeComposerService_2_2>; - -TEST_F(DisplayTest_2_2, HotplugOneConfig) { - Test_HotplugOneConfig(); -} - -TEST_F(DisplayTest_2_2, HotplugTwoSeparateConfigs) { - Test_HotplugTwoSeparateConfigs(); -} - -TEST_F(DisplayTest_2_2, HotplugTwoConfigsSameGroup) { - Test_HotplugTwoConfigsSameGroup(); -} - -TEST_F(DisplayTest_2_2, HotplugThreeConfigsMixedGroups) { - Test_HotplugThreeConfigsMixedGroups(); -} - -TEST_F(DisplayTest_2_2, HotplugPrimaryOneConfig) { - Test_HotplugPrimaryDisplay(); -} - -TEST_F(DisplayTest_2_2, SubsequentHotplugConnectUpdatesPrimaryDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY); -} - -TEST_F(DisplayTest_2_2, SubsequentHotplugConnectUpdatesExternalDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY); -} - -using DisplayTest_2_3 = DisplayTest<FakeComposerService_2_3>; - -TEST_F(DisplayTest_2_3, HotplugOneConfig) { - Test_HotplugOneConfig(); -} - -TEST_F(DisplayTest_2_3, HotplugTwoSeparateConfigs) { - Test_HotplugTwoSeparateConfigs(); -} - -TEST_F(DisplayTest_2_3, HotplugTwoConfigsSameGroup) { - Test_HotplugTwoConfigsSameGroup(); -} - -TEST_F(DisplayTest_2_3, HotplugThreeConfigsMixedGroups) { - Test_HotplugThreeConfigsMixedGroups(); -} - -TEST_F(DisplayTest_2_3, HotplugPrimaryOneConfig) { - Test_HotplugPrimaryDisplay(); -} - -TEST_F(DisplayTest_2_3, SubsequentHotplugConnectUpdatesPrimaryDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY); -} - -TEST_F(DisplayTest_2_3, SubsequentHotplugConnectUpdatesExternalDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY); -} - -using DisplayTest_2_4 = DisplayTest<FakeComposerService_2_4>; - -TEST_F(DisplayTest_2_4, HotplugOneConfig) { - Test_HotplugOneConfig(); -} - -TEST_F(DisplayTest_2_4, HotplugTwoSeparateConfigs) { - Test_HotplugTwoSeparateConfigs(); -} - -TEST_F(DisplayTest_2_4, HotplugTwoConfigsSameGroup) { - Test_HotplugTwoConfigsSameGroup(); -} - -TEST_F(DisplayTest_2_4, HotplugThreeConfigsMixedGroups) { - Test_HotplugThreeConfigsMixedGroups(); -} - -TEST_F(DisplayTest_2_4, HotplugPrimaryOneConfig) { - Test_HotplugPrimaryDisplay(); -} - -TEST_F(DisplayTest_2_4, SubsequentHotplugConnectUpdatesPrimaryDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY); -} - -TEST_F(DisplayTest_2_4, SubsequentHotplugConnectUpdatesExternalDisplay) { - Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY); -} - -//////////////////////////////////////////////// - -template <typename FakeComposerService> -class TransactionTest : public ::testing::Test { -protected: - // Layer array indexing constants. - constexpr static int BG_LAYER = 0; - constexpr static int FG_LAYER = 1; - - static void SetUpTestCase() { - // TODO: See TODO comment at DisplayTest::SetUp for background on - // the lifetime of the FakeComposerClient. - sFakeComposer = new FakeComposerClient; - auto client = sp<V2_4::hal::ComposerClient>::make(sFakeComposer); - sp<V2_1::IComposer> fakeService = sp<FakeComposerService>::make(client); - (void)fakeService->registerAsService("mock"); - - android::hardware::ProcessState::self()->startThreadPool(); - android::ProcessState::self()->startThreadPool(); - - startSurfaceFlinger(); - - // Fake composer wants to enable VSync injection - sFakeComposer->onSurfaceFlingerStart(); - } - - static void TearDownTestCase() { - // Fake composer needs to release SurfaceComposerClient before the stop. - sFakeComposer->onSurfaceFlingerStop(); - stopSurfaceFlinger(); - // TODO: This is deleted when the ComposerClient calls - // removeClient. Devise better lifetime control. - sFakeComposer = nullptr; - } - - void SetUp() override { - ALOGI("TransactionTest::SetUp"); - mComposerClient = sp<SurfaceComposerClient>::make(); - ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); - - ALOGI("TransactionTest::SetUp - display"); - const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kPrimaryDisplayId); - ASSERT_FALSE(display == nullptr); - - ui::DisplayMode mode; - ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode)); - - const ui::Size& resolution = mode.resolution; - mDisplayWidth = resolution.getWidth(); - mDisplayHeight = resolution.getHeight(); - - // Background surface - mBGSurfaceControl = - mComposerClient->createSurface(String8("BG Test Surface"), mDisplayWidth, - mDisplayHeight, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mBGSurfaceControl != nullptr); - ASSERT_TRUE(mBGSurfaceControl->isValid()); - fillSurfaceRGBA8(mBGSurfaceControl, BLUE); - - // Foreground surface - mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64, - PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mFGSurfaceControl != nullptr); - ASSERT_TRUE(mFGSurfaceControl->isValid()); - - fillSurfaceRGBA8(mFGSurfaceControl, RED); - - Transaction t; - t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK); - - t.setLayer(mBGSurfaceControl, INT32_MAX - 2); - t.show(mBGSurfaceControl); - - t.setLayer(mFGSurfaceControl, INT32_MAX - 1); - t.setPosition(mFGSurfaceControl, 64, 64); - t.show(mFGSurfaceControl); - - // Synchronous transaction will stop this thread, so we set up a - // delayed, off-thread vsync request before closing the - // transaction. In the test code this is usually done with - // TransactionScope. Leaving here in the 'vanilla' form for - // reference. - ASSERT_EQ(0, sFakeComposer->getFrameCount()); - sFakeComposer->runVSyncAfter(1ms); - t.apply(); - sFakeComposer->waitUntilFrame(1); - - // Reference data. This is what the HWC should see. - static_assert(BG_LAYER == 0 && FG_LAYER == 1, "Unexpected enum values for array indexing"); - mBaseFrame.push_back(makeSimpleRect(0u, 0u, mDisplayWidth, mDisplayHeight)); - mBaseFrame[BG_LAYER].mSwapCount = 1; - mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64)); - mBaseFrame[FG_LAYER].mSwapCount = 1; - - auto frame = sFakeComposer->getFrameRects(0); - ASSERT_TRUE(framesAreSame(mBaseFrame, frame)); - } - - void TearDown() override { - ALOGD("TransactionTest::TearDown"); - - mComposerClient->dispose(); - mBGSurfaceControl = 0; - mFGSurfaceControl = 0; - mComposerClient = 0; - - sFakeComposer->runVSyncAndWait(); - mBaseFrame.clear(); - sFakeComposer->clearFrames(); - ASSERT_EQ(0, sFakeComposer->getFrameCount()); - - sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService()); - std::vector<gui::LayerDebugInfo> layers; - binder::Status status = sf->getLayerDebugInfo(&layers); - status_t result = gui::aidl_utils::statusTFromBinderStatus(status); - if (result != NO_ERROR) { - ALOGE("Failed to get layers %s %d", strerror(-result), result); - } else { - // If this fails, the test being torn down leaked layers. - EXPECT_EQ(0u, layers.size()); - if (layers.size() > 0) { - for (auto layer = layers.begin(); layer != layers.end(); ++layer) { - std::cout << to_string(*layer).c_str(); - } - // To ensure the next test has clean slate, will run the class - // tear down and setup here. - TearDownTestCase(); - SetUpTestCase(); - } - } - ALOGD("TransactionTest::TearDown - complete"); - } - - void Test_LayerMove() { - ALOGD("TransactionTest::LayerMove"); - - // The scope opens and closes a global transaction and, at the - // same time, makes sure the SurfaceFlinger progresses one frame - // after the transaction closes. The results of the transaction - // should be available in the latest frame stored by the fake - // composer. - { - TransactionScope ts(*sFakeComposer); - ts.setPosition(mFGSurfaceControl, 128, 128); - // NOTE: No changes yet, so vsync will do nothing, HWC does not get any calls. - // (How to verify that? Throw in vsync and wait a 2x frame time? Separate test?) - // - // sFakeComposer->runVSyncAndWait(); - } - - fillSurfaceRGBA8(mFGSurfaceControl, GREEN); - sFakeComposer->runVSyncAndWait(); - - ASSERT_EQ(3, sFakeComposer->getFrameCount()); // Make sure the waits didn't time out and - // there's no extra frames. - - // NOTE: Frame 0 is produced in the SetUp. - auto frame1Ref = mBaseFrame; - frame1Ref[FG_LAYER].mDisplayFrame = - hwc_rect_t{128, 128, 128 + 64, 128 + 64}; // Top-most layer moves. - EXPECT_TRUE(framesAreSame(frame1Ref, sFakeComposer->getFrameRects(1))); - - auto frame2Ref = frame1Ref; - frame2Ref[FG_LAYER].mSwapCount++; - EXPECT_TRUE(framesAreSame(frame2Ref, sFakeComposer->getFrameRects(2))); - } - - void Test_LayerCrop() { - // TODO: Add scaling to confirm that crop happens in buffer space? - { - TransactionScope ts(*sFakeComposer); - Rect cropRect(16, 16, 32, 32); - ts.setCrop(mFGSurfaceControl, cropRect); - } - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - - auto referenceFrame = mBaseFrame; - referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{16.f, 16.f, 32.f, 32.f}; - referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64 + 16, 64 + 16, 64 + 32, 64 + 32}; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - } - - void Test_LayerSetLayer() { - { - TransactionScope ts(*sFakeComposer); - ts.setLayer(mFGSurfaceControl, INT_MAX - 3); - } - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - - // The layers will switch order, but both are rendered because the background layer is - // transparent (RGBA8888). - std::vector<RenderState> referenceFrame(2); - referenceFrame[0] = mBaseFrame[FG_LAYER]; - referenceFrame[1] = mBaseFrame[BG_LAYER]; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - } - - void Test_LayerSetLayerOpaque() { - { - TransactionScope ts(*sFakeComposer); - ts.setLayer(mFGSurfaceControl, INT_MAX - 3); - ts.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque, - layer_state_t::eLayerOpaque); - } - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - - // The former foreground layer is now covered with opaque layer - it should have disappeared - std::vector<RenderState> referenceFrame(1); - referenceFrame[BG_LAYER] = mBaseFrame[BG_LAYER]; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - } - - void Test_SetLayerStack() { - ALOGD("TransactionTest::SetLayerStack"); - { - TransactionScope ts(*sFakeComposer); - ts.setLayerStack(mFGSurfaceControl, ui::LayerStack{1}); - } - - // Foreground layer should have disappeared. - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - std::vector<RenderState> refFrame(1); - refFrame[BG_LAYER] = mBaseFrame[BG_LAYER]; - EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame())); - } - - void Test_LayerShowHide() { - ALOGD("TransactionTest::LayerShowHide"); - { - TransactionScope ts(*sFakeComposer); - ts.hide(mFGSurfaceControl); - } - - // Foreground layer should have disappeared. - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - std::vector<RenderState> refFrame(1); - refFrame[BG_LAYER] = mBaseFrame[BG_LAYER]; - EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*sFakeComposer); - ts.show(mFGSurfaceControl); - } - - // Foreground layer should be back - ASSERT_EQ(3, sFakeComposer->getFrameCount()); - EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame())); - } - - void Test_LayerSetAlpha() { - { - TransactionScope ts(*sFakeComposer); - ts.setAlpha(mFGSurfaceControl, 0.75f); - } - - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - auto referenceFrame = mBaseFrame; - referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - } - - void Test_LayerSetFlags() { - { - TransactionScope ts(*sFakeComposer); - ts.setFlags(mFGSurfaceControl, layer_state_t::eLayerHidden, - layer_state_t::eLayerHidden); - } - - // Foreground layer should have disappeared. - ASSERT_EQ(2, sFakeComposer->getFrameCount()); - std::vector<RenderState> refFrame(1); - refFrame[BG_LAYER] = mBaseFrame[BG_LAYER]; - EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame())); - } - - void Test_LayerSetMatrix() { - struct matrixTestData { - float matrix[4]; - hwc_transform_t expectedTransform; - hwc_rect_t expectedDisplayFrame; - }; - - // The matrix operates on the display frame and is applied before - // the position is added. So, the foreground layer rect is (0, 0, - // 64, 64) is first transformed, potentially yielding negative - // coordinates and then the position (64, 64) is added yielding - // the final on-screen rectangles given. - - const matrixTestData MATRIX_TESTS[7] = // clang-format off - {{{-1.f, 0.f, 0.f, 1.f}, HWC_TRANSFORM_FLIP_H, {0, 64, 64, 128}}, - {{1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_FLIP_V, {64, 0, 128, 64}}, - {{0.f, 1.f, -1.f, 0.f}, HWC_TRANSFORM_ROT_90, {0, 64, 64, 128}}, - {{-1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_ROT_180, {0, 0, 64, 64}}, - {{0.f, -1.f, 1.f, 0.f}, HWC_TRANSFORM_ROT_270, {64, 0, 128, 64}}, - {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_H_ROT_90, {64, 64, 128, 128}}, - {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_V_ROT_90, {64, 64, 128, 128}}}; - // clang-format on - constexpr int TEST_COUNT = sizeof(MATRIX_TESTS) / sizeof(matrixTestData); - - for (int i = 0; i < TEST_COUNT; i++) { - // TODO: How to leverage the HWC2 stringifiers? - const matrixTestData& xform = MATRIX_TESTS[i]; - SCOPED_TRACE(i); - { - TransactionScope ts(*sFakeComposer); - ts.setMatrix(mFGSurfaceControl, xform.matrix[0], xform.matrix[1], xform.matrix[2], - xform.matrix[3]); - } - - auto referenceFrame = mBaseFrame; - referenceFrame[FG_LAYER].mTransform = xform.expectedTransform; - referenceFrame[FG_LAYER].mDisplayFrame = xform.expectedDisplayFrame; - - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - } - } - - void Test_SetRelativeLayer() { - constexpr int RELATIVE_LAYER = 2; - auto relativeSurfaceControl = mComposerClient->createSurface(String8("Test Surface"), 64, - 64, PIXEL_FORMAT_RGBA_8888, 0); - fillSurfaceRGBA8(relativeSurfaceControl, LIGHT_RED); - - // Now we stack the surface above the foreground surface and make sure it is visible. - { - TransactionScope ts(*sFakeComposer); - ts.setPosition(relativeSurfaceControl, 64, 64); - ts.show(relativeSurfaceControl); - ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl, 1); - } - auto referenceFrame = mBaseFrame; - // NOTE: All three layers will be visible as the surfaces are - // transparent because of the RGBA format. - referenceFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64)); - referenceFrame[RELATIVE_LAYER].mSwapCount = 1; - EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame())); - - // A call to setLayer will override a call to setRelativeLayer - { - TransactionScope ts(*sFakeComposer); - ts.setLayer(relativeSurfaceControl, 0); - } - - // Previous top layer will now appear at the bottom. - auto referenceFrame2 = mBaseFrame; - referenceFrame2.insert(referenceFrame2.begin(), referenceFrame[RELATIVE_LAYER]); - EXPECT_EQ(3, sFakeComposer->getFrameCount()); - EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame())); - } - - sp<SurfaceComposerClient> mComposerClient; - sp<SurfaceControl> mBGSurfaceControl; - sp<SurfaceControl> mFGSurfaceControl; - std::vector<RenderState> mBaseFrame; - uint32_t mDisplayWidth; - uint32_t mDisplayHeight; - - static inline FakeComposerClient* sFakeComposer; -}; - -using TransactionTest_2_1 = TransactionTest<FakeComposerService_2_1>; - -TEST_F(TransactionTest_2_1, DISABLED_LayerMove) { - Test_LayerMove(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerCrop) { - Test_LayerCrop(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerSetLayer) { - Test_LayerSetLayer(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerSetLayerOpaque) { - Test_LayerSetLayerOpaque(); -} - -TEST_F(TransactionTest_2_1, DISABLED_SetLayerStack) { - Test_SetLayerStack(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerShowHide) { - Test_LayerShowHide(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerSetAlpha) { - Test_LayerSetAlpha(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerSetFlags) { - Test_LayerSetFlags(); -} - -TEST_F(TransactionTest_2_1, DISABLED_LayerSetMatrix) { - Test_LayerSetMatrix(); -} - -TEST_F(TransactionTest_2_1, DISABLED_SetRelativeLayer) { - Test_SetRelativeLayer(); -} - -template <typename FakeComposerService> -class ChildLayerTest : public TransactionTest<FakeComposerService> { - using Base = TransactionTest<FakeComposerService>; - -protected: - constexpr static int CHILD_LAYER = 2; - - void SetUp() override { - Base::SetUp(); - mChild = Base::mComposerClient->createSurface(String8("Child surface"), 10, 10, - PIXEL_FORMAT_RGBA_8888, 0, - Base::mFGSurfaceControl->getHandle()); - fillSurfaceRGBA8(mChild, LIGHT_GRAY); - - Base::sFakeComposer->runVSyncAndWait(); - Base::mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10)); - Base::mBaseFrame[CHILD_LAYER].mSwapCount = 1; - ASSERT_EQ(2, Base::sFakeComposer->getFrameCount()); - ASSERT_TRUE(framesAreSame(Base::mBaseFrame, Base::sFakeComposer->getLatestFrame())); - } - - void TearDown() override { - mChild = 0; - Base::TearDown(); - } - - void Test_Positioning() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(mChild); - ts.setPosition(mChild, 10, 10); - // Move to the same position as in the original setup. - ts.setPosition(Base::mFGSurfaceControl, 64, 64); - } - - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = - hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - } - - auto referenceFrame2 = Base::mBaseFrame; - referenceFrame2[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 64, 0 + 64}; - referenceFrame2[CHILD_LAYER].mDisplayFrame = - hwc_rect_t{0 + 10, 0 + 10, 0 + 10 + 10, 0 + 10 + 10}; - EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); - } - - void Test_Cropping() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(mChild); - ts.setPosition(mChild, 0, 0); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.setCrop(Base::mFGSurfaceControl, Rect(0, 0, 5, 5)); - } - // NOTE: The foreground surface would be occluded by the child - // now, but is included in the stack because the child is - // transparent. - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5}; - referenceFrame[Base::FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f}; - referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5}; - referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - } - - void Test_Constraints() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(mChild); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.setPosition(mChild, 63, 63); - } - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{63, 63, 64, 64}; - referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 1.f, 1.f}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - } - - void Test_Scaling() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - } - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10}; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setMatrix(Base::mFGSurfaceControl, 2.0, 0, 0, 2.0); - } - - auto referenceFrame2 = Base::mBaseFrame; - referenceFrame2[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 128, 128}; - referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 20, 20}; - EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); - } - - void Test_LayerAlpha() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(mChild); - ts.setPosition(mChild, 0, 0); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.setAlpha(mChild, 0.5); - } - - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; - referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10}; - referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setAlpha(Base::mFGSurfaceControl, 0.5); - } - - auto referenceFrame2 = referenceFrame; - referenceFrame2[Base::FG_LAYER].mPlaneAlpha = 0.5f; - referenceFrame2[CHILD_LAYER].mPlaneAlpha = 0.25f; - EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); - } - - sp<SurfaceControl> mChild; -}; - -using ChildLayerTest_2_1 = ChildLayerTest<FakeComposerService_2_1>; - -TEST_F(ChildLayerTest_2_1, DISABLED_Positioning) { - Test_Positioning(); -} - -TEST_F(ChildLayerTest_2_1, DISABLED_Cropping) { - Test_Cropping(); -} - -TEST_F(ChildLayerTest_2_1, DISABLED_Constraints) { - Test_Constraints(); -} - -TEST_F(ChildLayerTest_2_1, DISABLED_Scaling) { - Test_Scaling(); -} - -TEST_F(ChildLayerTest_2_1, DISABLED_LayerAlpha) { - Test_LayerAlpha(); -} - -template <typename FakeComposerService> -class ChildColorLayerTest : public ChildLayerTest<FakeComposerService> { - using Base = ChildLayerTest<FakeComposerService>; - -protected: - void SetUp() override { - Base::SetUp(); - Base::mChild = - Base::mComposerClient->createSurface(String8("Child surface"), 0, 0, - PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceEffect, - Base::mFGSurfaceControl->getHandle()); - { - TransactionScope ts(*Base::sFakeComposer); - ts.setColor(Base::mChild, - {LIGHT_GRAY.r / 255.0f, LIGHT_GRAY.g / 255.0f, LIGHT_GRAY.b / 255.0f}); - ts.setCrop(Base::mChild, Rect(0, 0, 10, 10)); - } - - Base::sFakeComposer->runVSyncAndWait(); - Base::mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10)); - Base::mBaseFrame[Base::CHILD_LAYER].mSourceCrop = hwc_frect_t{0.0f, 0.0f, 0.0f, 0.0f}; - Base::mBaseFrame[Base::CHILD_LAYER].mSwapCount = 0; - ASSERT_EQ(2, Base::sFakeComposer->getFrameCount()); - ASSERT_TRUE(framesAreSame(Base::mBaseFrame, Base::sFakeComposer->getLatestFrame())); - } - - void Test_LayerAlpha() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(Base::mChild); - ts.setPosition(Base::mChild, 0, 0); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.setAlpha(Base::mChild, 0.5); - } - - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; - referenceFrame[Base::CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10}; - referenceFrame[Base::CHILD_LAYER].mPlaneAlpha = 0.5f; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setAlpha(Base::mFGSurfaceControl, 0.5); - } - - auto referenceFrame2 = referenceFrame; - referenceFrame2[Base::FG_LAYER].mPlaneAlpha = 0.5f; - referenceFrame2[Base::CHILD_LAYER].mPlaneAlpha = 0.25f; - EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame())); - } - - void Test_LayerZeroAlpha() { - { - TransactionScope ts(*Base::sFakeComposer); - ts.show(Base::mChild); - ts.setPosition(Base::mChild, 0, 0); - ts.setPosition(Base::mFGSurfaceControl, 0, 0); - ts.setAlpha(Base::mChild, 0.5); - } - - auto referenceFrame = Base::mBaseFrame; - referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64}; - referenceFrame[Base::CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10}; - referenceFrame[Base::CHILD_LAYER].mPlaneAlpha = 0.5f; - EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame())); - - { - TransactionScope ts(*Base::sFakeComposer); - ts.setAlpha(Base::mFGSurfaceControl, 0.0f); - } - - std::vector<RenderState> refFrame(1); - refFrame[Base::BG_LAYER] = Base::mBaseFrame[Base::BG_LAYER]; - - EXPECT_TRUE(framesAreSame(refFrame, Base::sFakeComposer->getLatestFrame())); - } -}; - -using ChildColorLayerTest_2_1 = ChildColorLayerTest<FakeComposerService_2_1>; - -TEST_F(ChildColorLayerTest_2_1, DISABLED_LayerAlpha) { - Test_LayerAlpha(); -} - -TEST_F(ChildColorLayerTest_2_1, DISABLED_LayerZeroAlpha) { - Test_LayerZeroAlpha(); -} -} // namespace - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - - auto* fakeEnvironment = new sftest::FakeHwcEnvironment; - ::testing::AddGlobalTestEnvironment(fakeEnvironment); - ::testing::InitGoogleMock(&argc, argv); - return RUN_ALL_TESTS(); -} - -// TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion -Wextra" |