• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "DisplayDevice.h"
20 #include "SurfaceFlinger.h"
21 
22 namespace android {
23 
24 class EventThread;
25 
26 namespace RE {
27 class RenderEngine;
28 }
29 
30 namespace Hwc2 {
31 class Composer;
32 }
33 
34 class TestableSurfaceFlinger {
35 public:
36     // Extend this as needed for accessing SurfaceFlinger private (and public)
37     // functions.
38 
setupRenderEngine(std::unique_ptr<RE::RenderEngine> renderEngine)39     void setupRenderEngine(std::unique_ptr<RE::RenderEngine> renderEngine) {
40         mFlinger->getBE().mRenderEngine = std::move(renderEngine);
41     }
42 
setupComposer(std::unique_ptr<Hwc2::Composer> composer)43     void setupComposer(std::unique_ptr<Hwc2::Composer> composer) {
44         mFlinger->getBE().mHwc.reset(new HWComposer(std::move(composer)));
45     }
46 
47     using CreateBufferQueueFunction = SurfaceFlinger::CreateBufferQueueFunction;
setCreateBufferQueueFunction(CreateBufferQueueFunction f)48     void setCreateBufferQueueFunction(CreateBufferQueueFunction f) {
49         mFlinger->mCreateBufferQueue = f;
50     }
51 
52     using CreateNativeWindowSurfaceFunction = SurfaceFlinger::CreateNativeWindowSurfaceFunction;
setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f)53     void setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f) {
54         mFlinger->mCreateNativeWindowSurface = f;
55     }
56 
57     using HotplugEvent = SurfaceFlinger::HotplugEvent;
58 
59     /* ------------------------------------------------------------------------
60      * Forwarding for functions being tested
61      */
62 
createDisplay(const String8 & displayName,bool secure)63     auto createDisplay(const String8& displayName, bool secure) {
64         return mFlinger->createDisplay(displayName, secure);
65     }
66 
destroyDisplay(const sp<IBinder> & display)67     auto destroyDisplay(const sp<IBinder>& display) { return mFlinger->destroyDisplay(display); }
68 
resetDisplayState()69     auto resetDisplayState() { return mFlinger->resetDisplayState(); }
70 
setupNewDisplayDeviceInternal(const wp<IBinder> & display,int hwcId,const DisplayDeviceState & state,const sp<DisplaySurface> & dispSurface,const sp<IGraphicBufferProducer> & producer)71     auto setupNewDisplayDeviceInternal(const wp<IBinder>& display, int hwcId,
72                                        const DisplayDeviceState& state,
73                                        const sp<DisplaySurface>& dispSurface,
74                                        const sp<IGraphicBufferProducer>& producer) {
75         return mFlinger->setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,
76                                                        producer);
77     }
78 
handleTransactionLocked(uint32_t transactionFlags)79     auto handleTransactionLocked(uint32_t transactionFlags) {
80         return mFlinger->handleTransactionLocked(transactionFlags);
81     }
82 
onHotplugReceived(int32_t sequenceId,hwc2_display_t display,HWC2::Connection connection)83     auto onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
84                            HWC2::Connection connection) {
85         return mFlinger->onHotplugReceived(sequenceId, display, connection);
86     }
87 
setDisplayStateLocked(const DisplayState & s)88     auto setDisplayStateLocked(const DisplayState& s) { return mFlinger->setDisplayStateLocked(s); }
89 
onInitializeDisplays()90     auto onInitializeDisplays() { return mFlinger->onInitializeDisplays(); }
91 
92     auto setPowerModeInternal(const sp<DisplayDevice>& hw, int mode, bool stateLockHeld = false) {
93         return mFlinger->setPowerModeInternal(hw, mode, stateLockHeld);
94     }
95 
96     /* ------------------------------------------------------------------------
97      * Read-only access to private data to assert post-conditions.
98      */
99 
getAnimFrameTracker()100     const auto& getAnimFrameTracker() const { return mFlinger->mAnimFrameTracker; }
getHasPoweredOff()101     const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; }
getHWVsyncAvailable()102     const auto& getHWVsyncAvailable() const { return mFlinger->mHWVsyncAvailable; }
getVisibleRegionsDirty()103     const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; }
104 
getCompositorTiming()105     const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; }
106 
107     /* ------------------------------------------------------------------------
108      * Read-write access to private data to set up preconditions and assert
109      * post-conditions.
110      */
111 
mutableHasWideColorDisplay()112     auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
113 
mutableBuiltinDisplays()114     auto& mutableBuiltinDisplays() { return mFlinger->mBuiltinDisplays; }
mutableCurrentState()115     auto& mutableCurrentState() { return mFlinger->mCurrentState; }
mutableDisplays()116     auto& mutableDisplays() { return mFlinger->mDisplays; }
mutableDisplayColorSetting()117     auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
mutableDrawingState()118     auto& mutableDrawingState() { return mFlinger->mDrawingState; }
mutableEventControlThread()119     auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
mutableEventQueue()120     auto& mutableEventQueue() { return mFlinger->mEventQueue; }
mutableEventThread()121     auto& mutableEventThread() { return mFlinger->mEventThread; }
mutableHWVsyncAvailable()122     auto& mutableHWVsyncAvailable() { return mFlinger->mHWVsyncAvailable; }
mutableInterceptor()123     auto& mutableInterceptor() { return mFlinger->mInterceptor; }
mutableMainThreadId()124     auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
mutablePendingHotplugEvents()125     auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
mutablePrimaryHWVsyncEnabled()126     auto& mutablePrimaryHWVsyncEnabled() { return mFlinger->mPrimaryHWVsyncEnabled; }
mutableTransactionFlags()127     auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
mutableUseHwcVirtualDisplays()128     auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
129 
mutableComposerSequenceId()130     auto& mutableComposerSequenceId() { return mFlinger->getBE().mComposerSequenceId; }
mutableHwcDisplayData()131     auto& mutableHwcDisplayData() { return mFlinger->getBE().mHwc->mDisplayData; }
mutableHwcDisplaySlots()132     auto& mutableHwcDisplaySlots() { return mFlinger->getBE().mHwc->mHwcDisplaySlots; }
133 
~TestableSurfaceFlinger()134     ~TestableSurfaceFlinger() {
135         // All these pointer and container clears help ensure that GMock does
136         // not report a leaked object, since the SurfaceFlinger instance may
137         // still be referenced by something despite our best efforts to destroy
138         // it after each test is done.
139         mutableDisplays().clear();
140         mutableEventControlThread().reset();
141         mutableEventQueue().reset();
142         mutableEventThread().reset();
143         mutableInterceptor().reset();
144         mFlinger->getBE().mHwc.reset();
145         mFlinger->getBE().mRenderEngine.reset();
146     }
147 
148     /* ------------------------------------------------------------------------
149      * Wrapper classes for Read-write access to private data to set up
150      * preconditions and assert post-conditions.
151      */
152 
153     struct HWC2Display : public HWC2::Display {
HWC2DisplayHWC2Display154         HWC2Display(Hwc2::Composer& composer,
155                     const std::unordered_set<HWC2::Capability>& capabilities, hwc2_display_t id,
156                     HWC2::DisplayType type)
157               : HWC2::Display(composer, capabilities, id, type) {}
~HWC2DisplayHWC2Display158         ~HWC2Display() {
159             // Prevents a call to disable vsyncs.
160             mType = HWC2::DisplayType::Invalid;
161         }
162 
mutableIsConnectedHWC2Display163         auto& mutableIsConnected() { return this->mIsConnected; }
mutableConfigsHWC2Display164         auto& mutableConfigs() { return this->mConfigs; }
165     };
166 
167     class FakeHwcDisplayInjector {
168     public:
169         static constexpr hwc2_display_t DEFAULT_HWC_DISPLAY_ID = 1000;
170         static constexpr int32_t DEFAULT_WIDTH = 1920;
171         static constexpr int32_t DEFAULT_HEIGHT = 1280;
172         static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
173         static constexpr int32_t DEFAULT_DPI = 320;
174         static constexpr int32_t DEFAULT_ACTIVE_CONFIG = 0;
175 
FakeHwcDisplayInjector(DisplayDevice::DisplayType type,HWC2::DisplayType hwcDisplayType)176         FakeHwcDisplayInjector(DisplayDevice::DisplayType type, HWC2::DisplayType hwcDisplayType)
177               : mType(type), mHwcDisplayType(hwcDisplayType) {}
178 
setHwcDisplayId(hwc2_display_t displayId)179         auto& setHwcDisplayId(hwc2_display_t displayId) {
180             mHwcDisplayId = displayId;
181             return *this;
182         }
183 
setWidth(int32_t width)184         auto& setWidth(int32_t width) {
185             mWidth = width;
186             return *this;
187         }
188 
setHeight(int32_t height)189         auto& setHeight(int32_t height) {
190             mHeight = height;
191             return *this;
192         }
193 
setRefreshRate(int32_t refreshRate)194         auto& setRefreshRate(int32_t refreshRate) {
195             mRefreshRate = refreshRate;
196             return *this;
197         }
198 
setDpiX(int32_t dpi)199         auto& setDpiX(int32_t dpi) {
200             mDpiX = dpi;
201             return *this;
202         }
203 
setDpiY(int32_t dpi)204         auto& setDpiY(int32_t dpi) {
205             mDpiY = dpi;
206             return *this;
207         }
208 
setActiveConfig(int32_t config)209         auto& setActiveConfig(int32_t config) {
210             mActiveConfig = config;
211             return *this;
212         }
213 
addCapability(HWC2::Capability cap)214         auto& addCapability(HWC2::Capability cap) {
215             mCapabilities.emplace(cap);
216             return *this;
217         }
218 
inject(TestableSurfaceFlinger * flinger,Hwc2::Composer * composer)219         void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
220             auto display = std::make_unique<HWC2Display>(*composer, mCapabilities, mHwcDisplayId,
221                                                          mHwcDisplayType);
222 
223             auto config = HWC2::Display::Config::Builder(*display, mActiveConfig);
224             config.setWidth(mWidth);
225             config.setHeight(mHeight);
226             config.setVsyncPeriod(mRefreshRate);
227             config.setDpiX(mDpiX);
228             config.setDpiY(mDpiY);
229             display->mutableConfigs().emplace(mActiveConfig, config.build());
230             display->mutableIsConnected() = true;
231 
232             ASSERT_TRUE(flinger->mutableHwcDisplayData().size() > static_cast<size_t>(mType));
233             flinger->mutableHwcDisplayData()[mType].reset();
234             flinger->mutableHwcDisplayData()[mType].hwcDisplay = display.get();
235             flinger->mutableHwcDisplaySlots().emplace(mHwcDisplayId, mType);
236 
237             flinger->mFakeHwcDisplays.push_back(std::move(display));
238         }
239 
240     private:
241         DisplayDevice::DisplayType mType;
242         HWC2::DisplayType mHwcDisplayType;
243         hwc2_display_t mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
244         int32_t mWidth = DEFAULT_WIDTH;
245         int32_t mHeight = DEFAULT_HEIGHT;
246         int32_t mRefreshRate = DEFAULT_REFRESH_RATE;
247         int32_t mDpiX = DEFAULT_DPI;
248         int32_t mDpiY = DEFAULT_DPI;
249         int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
250         std::unordered_set<HWC2::Capability> mCapabilities;
251     };
252 
253     class FakeDisplayDeviceInjector {
254     public:
FakeDisplayDeviceInjector(TestableSurfaceFlinger & flinger,DisplayDevice::DisplayType type,int hwcId)255         FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, DisplayDevice::DisplayType type,
256                                   int hwcId)
257               : mFlinger(flinger), mType(type), mHwcId(hwcId) {}
258 
token()259         sp<IBinder> token() const { return mDisplayToken; }
260 
mutableDrawingDisplayState()261         DisplayDeviceState& mutableDrawingDisplayState() {
262             return mFlinger.mutableDrawingState().displays.editValueFor(mDisplayToken);
263         }
264 
mutableCurrentDisplayState()265         DisplayDeviceState& mutableCurrentDisplayState() {
266             return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken);
267         }
268 
getDrawingDisplayState()269         const auto& getDrawingDisplayState() {
270             return mFlinger.mutableDrawingState().displays.valueFor(mDisplayToken);
271         }
272 
getCurrentDisplayState()273         const auto& getCurrentDisplayState() {
274             return mFlinger.mutableCurrentState().displays.valueFor(mDisplayToken);
275         }
276 
mutableDisplayDevice()277         auto& mutableDisplayDevice() { return mFlinger.mutableDisplays().valueFor(mDisplayToken); }
278 
setNativeWindow(const sp<ANativeWindow> & nativeWindow)279         auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
280             mNativeWindow = nativeWindow;
281             return *this;
282         }
283 
setDisplaySurface(const sp<DisplaySurface> & displaySurface)284         auto& setDisplaySurface(const sp<DisplaySurface>& displaySurface) {
285             mDisplaySurface = displaySurface;
286             return *this;
287         }
288 
setRenderSurface(std::unique_ptr<RE::Surface> renderSurface)289         auto& setRenderSurface(std::unique_ptr<RE::Surface> renderSurface) {
290             mRenderSurface = std::move(renderSurface);
291             return *this;
292         }
293 
setSecure(bool secure)294         auto& setSecure(bool secure) {
295             mSecure = secure;
296             return *this;
297         }
298 
inject()299         sp<DisplayDevice> inject() {
300             std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hdrAndRenderIntents;
301             sp<DisplayDevice> device =
302                     new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, mSecure, mDisplayToken,
303                                       mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
304                                       0, false, HdrCapabilities(), 0, hdrAndRenderIntents,
305                                       HWC_POWER_MODE_NORMAL);
306             mFlinger.mutableDisplays().add(mDisplayToken, device);
307 
308             DisplayDeviceState state(mType, mSecure);
309             mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
310             mFlinger.mutableDrawingState().displays.add(mDisplayToken, state);
311 
312             if (mType >= DisplayDevice::DISPLAY_PRIMARY && mType < DisplayDevice::DISPLAY_VIRTUAL) {
313                 mFlinger.mutableBuiltinDisplays()[mType] = mDisplayToken;
314             }
315 
316             return device;
317         }
318 
319     private:
320         TestableSurfaceFlinger& mFlinger;
321         sp<BBinder> mDisplayToken = new BBinder();
322         DisplayDevice::DisplayType mType;
323         int mHwcId;
324         sp<ANativeWindow> mNativeWindow;
325         sp<DisplaySurface> mDisplaySurface;
326         std::unique_ptr<RE::Surface> mRenderSurface;
327         bool mSecure = false;
328     };
329 
330     sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(SurfaceFlinger::SkipInitialization);
331 
332     // We need to keep a reference to these so they are properly destroyed.
333     std::vector<std::unique_ptr<HWC2Display>> mFakeHwcDisplays;
334 };
335 
336 } // namespace android
337