• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 //#define LOG_NDEBUG 0
18 #undef LOG_TAG
19 #define LOG_TAG "FakeComposer"
20 
21 #include "FakeComposerClient.h"
22 
23 #include <gui/SurfaceComposerClient.h>
24 
25 #include <log/log.h>
26 
27 #include <gtest/gtest.h>
28 
29 #include <inttypes.h>
30 #include <time.h>
31 #include <algorithm>
32 #include <condition_variable>
33 #include <iostream>
34 #include <mutex>
35 #include <set>
36 #include <thread>
37 
38 constexpr Config NULL_DISPLAY_CONFIG = static_cast<Config>(0);
39 
40 using namespace sftest;
41 
42 using android::Condition;
43 using android::Mutex;
44 
45 using Clock = std::chrono::steady_clock;
46 using TimePoint = std::chrono::time_point<Clock>;
47 
48 namespace {
49 
50 // Internal state of a layer in the HWC API.
51 class LayerImpl {
52 public:
53     LayerImpl() = default;
54 
55     bool mValid = true;
56     RenderState mRenderState;
57     uint32_t mZ = 0;
58 };
59 
60 // Struct for storing per frame rectangle state. Contains the render
61 // state shared to the test case. Basically a snapshot and a subset of
62 // LayerImpl sufficient to re-create the pixels of a layer for the
63 // frame.
64 struct FrameRect {
65 public:
FrameRect__anonada22b190111::FrameRect66     FrameRect(Layer layer_, const RenderState& state, uint32_t z_)
67           : layer(layer_), renderState(state), z(z_) {}
68 
69     const Layer layer;
70     const RenderState renderState;
71     const uint32_t z;
72 };
73 
74 // Collection of FrameRects forming one rendered frame. Could store
75 // related fences and other data in the future.
76 class Frame {
77 public:
78     Frame() = default;
79     std::vector<std::unique_ptr<FrameRect>> rectangles;
80 };
81 
82 class DelayedEventGenerator {
83 public:
DelayedEventGenerator(std::function<void ()> onTimerExpired)84     explicit DelayedEventGenerator(std::function<void()> onTimerExpired)
85           : mOnTimerExpired(onTimerExpired), mThread([this]() { loop(); }) {}
86 
~DelayedEventGenerator()87     ~DelayedEventGenerator() {
88         ALOGI("DelayedEventGenerator exiting.");
89         {
90             std::unique_lock<std::mutex> lock(mMutex);
91             mRunning = false;
92             mWakeups.clear();
93             mCondition.notify_one();
94         }
95         mThread.join();
96         ALOGI("DelayedEventGenerator exited.");
97     }
98 
wakeAfter(std::chrono::nanoseconds waitTime)99     void wakeAfter(std::chrono::nanoseconds waitTime) {
100         std::unique_lock<std::mutex> lock(mMutex);
101         mWakeups.insert(Clock::now() + waitTime);
102         mCondition.notify_one();
103     }
104 
105 private:
loop()106     void loop() {
107         while (true) {
108             // Lock scope
109             {
110                 std::unique_lock<std::mutex> lock(mMutex);
111                 mCondition.wait(lock, [this]() { return !mRunning || !mWakeups.empty(); });
112                 if (!mRunning && mWakeups.empty()) {
113                     // This thread should only exit once the destructor has been called and all
114                     // wakeups have been processed
115                     return;
116                 }
117 
118                 // At this point, mWakeups will not be empty
119 
120                 TimePoint target = *(mWakeups.begin());
121                 auto status = mCondition.wait_until(lock, target);
122                 while (status == std::cv_status::no_timeout) {
123                     // This was either a spurious wakeup or another wakeup was added, so grab the
124                     // oldest point and wait again
125                     target = *(mWakeups.begin());
126                     status = mCondition.wait_until(lock, target);
127                 }
128 
129                 // status must have been timeout, so we can finally clear this point
130                 mWakeups.erase(target);
131             }
132             // Callback *without* locks!
133             mOnTimerExpired();
134         }
135     }
136 
137     std::function<void()> mOnTimerExpired;
138     std::thread mThread;
139     std::mutex mMutex;
140     std::condition_variable mCondition;
141     bool mRunning = true;
142     std::set<TimePoint> mWakeups;
143 };
144 
145 } // namespace
146 
FakeComposerClient()147 FakeComposerClient::FakeComposerClient()
148       : mEventCallback(nullptr),
149         mCurrentConfig(NULL_DISPLAY_CONFIG),
150         mVsyncEnabled(false),
151         mLayers(),
152         mDelayedEventGenerator(
153                 std::make_unique<DelayedEventGenerator>([this]() { this->requestVSync(); })),
154         mSurfaceComposer(nullptr) {}
155 
~FakeComposerClient()156 FakeComposerClient::~FakeComposerClient() {}
157 
hasCapability(hwc2_capability_t)158 bool FakeComposerClient::hasCapability(hwc2_capability_t /*capability*/) {
159     return false;
160 }
161 
dumpDebugInfo()162 std::string FakeComposerClient::dumpDebugInfo() {
163     return {};
164 }
165 
registerEventCallback(EventCallback * callback)166 void FakeComposerClient::registerEventCallback(EventCallback* callback) {
167     ALOGV("registerEventCallback");
168     mEventCallback = callback;
169     if (mEventCallback) {
170         mEventCallback->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
171     }
172 }
173 
unregisterEventCallback()174 void FakeComposerClient::unregisterEventCallback() {
175     ALOGV("unregisterEventCallback");
176     mEventCallback = nullptr;
177 }
178 
hotplugDisplay(Display display,IComposerCallback::Connection state)179 void FakeComposerClient::hotplugDisplay(Display display, IComposerCallback::Connection state) {
180     if (mEventCallback) {
181         mEventCallback->onHotplug(display, state);
182     }
183 }
184 
refreshDisplay(Display display)185 void FakeComposerClient::refreshDisplay(Display display) {
186     if (mEventCallback) {
187         mEventCallback->onRefresh(display);
188     }
189 }
190 
getMaxVirtualDisplayCount()191 uint32_t FakeComposerClient::getMaxVirtualDisplayCount() {
192     ALOGV("getMaxVirtualDisplayCount");
193     return 1;
194 }
195 
createVirtualDisplay(uint32_t,uint32_t,PixelFormat *,Display *)196 Error FakeComposerClient::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
197                                                PixelFormat* /*format*/, Display* /*outDisplay*/) {
198     ALOGV("createVirtualDisplay");
199     return Error::NONE;
200 }
201 
destroyVirtualDisplay(Display)202 Error FakeComposerClient::destroyVirtualDisplay(Display /*display*/) {
203     ALOGV("destroyVirtualDisplay");
204     return Error::NONE;
205 }
206 
createLayer(Display,Layer * outLayer)207 Error FakeComposerClient::createLayer(Display /*display*/, Layer* outLayer) {
208     ALOGV("createLayer");
209     *outLayer = mLayers.size();
210     auto newLayer = std::make_unique<LayerImpl>();
211     mLayers.push_back(std::move(newLayer));
212     return Error::NONE;
213 }
214 
destroyLayer(Display,Layer layer)215 Error FakeComposerClient::destroyLayer(Display /*display*/, Layer layer) {
216     ALOGV("destroyLayer");
217     mLayers[layer]->mValid = false;
218     return Error::NONE;
219 }
220 
getActiveConfig(Display,Config * outConfig)221 Error FakeComposerClient::getActiveConfig(Display /*display*/, Config* outConfig) {
222     ALOGV("getActiveConfig");
223 
224     // TODO Assert outConfig != nullptr
225 
226     // TODO This is my reading of the
227     // IComposerClient::getActiveConfig, but returning BAD_CONFIG
228     // seems to not fit SurfaceFlinger plans. See version 2 below.
229     // if (mCurrentConfig == NULL_DISPLAY_CONFIG) {
230     //     return Error::BAD_CONFIG;
231     // }
232     //*outConfig = mCurrentConfig;
233     *outConfig = 1; // Very special config for you my friend
234     return Error::NONE;
235 }
236 
getClientTargetSupport(Display,uint32_t,uint32_t,PixelFormat,Dataspace)237 Error FakeComposerClient::getClientTargetSupport(Display /*display*/, uint32_t /*width*/,
238                                                  uint32_t /*height*/, PixelFormat /*format*/,
239                                                  Dataspace /*dataspace*/) {
240     ALOGV("getClientTargetSupport");
241     return Error::NONE;
242 }
243 
getColorModes(Display,hidl_vec<ColorMode> *)244 Error FakeComposerClient::getColorModes(Display /*display*/, hidl_vec<ColorMode>* /*outModes*/) {
245     ALOGV("getColorModes");
246     return Error::NONE;
247 }
248 
getDisplayAttribute(Display display,Config config,IComposerClient::Attribute attribute,int32_t * outValue)249 Error FakeComposerClient::getDisplayAttribute(Display display, Config config,
250                                               IComposerClient::Attribute attribute,
251                                               int32_t* outValue) {
252     ALOGV("getDisplayAttribute (%d, %d, %d, %p)", static_cast<int>(display),
253           static_cast<int>(config), static_cast<int>(attribute), outValue);
254 
255     // TODO: SOOO much fun to be had with these alone
256     switch (attribute) {
257         case IComposerClient::Attribute::WIDTH:
258             *outValue = 1920;
259             break;
260         case IComposerClient::Attribute::HEIGHT:
261             *outValue = 1080;
262             break;
263         case IComposerClient::Attribute::VSYNC_PERIOD:
264             *outValue = 1666666666;
265             break; // TOOD: Tests break down if lowered to 16ms?
266         case IComposerClient::Attribute::DPI_X:
267             *outValue = 240;
268             break;
269         case IComposerClient::Attribute::DPI_Y:
270             *outValue = 240;
271             break;
272         default:
273             LOG_ALWAYS_FATAL("Say what!?! New attribute");
274     }
275 
276     return Error::NONE;
277 }
278 
getDisplayConfigs(Display,hidl_vec<Config> * outConfigs)279 Error FakeComposerClient::getDisplayConfigs(Display /*display*/, hidl_vec<Config>* outConfigs) {
280     ALOGV("getDisplayConfigs");
281     // TODO assert display == 1, outConfigs != nullptr
282 
283     outConfigs->resize(1);
284     (*outConfigs)[0] = 1;
285 
286     return Error::NONE;
287 }
288 
getDisplayName(Display,hidl_string *)289 Error FakeComposerClient::getDisplayName(Display /*display*/, hidl_string* /*outName*/) {
290     ALOGV("getDisplayName");
291     return Error::NONE;
292 }
293 
getDisplayType(Display,IComposerClient::DisplayType * outType)294 Error FakeComposerClient::getDisplayType(Display /*display*/,
295                                          IComposerClient::DisplayType* outType) {
296     ALOGV("getDisplayType");
297     // TODO: This setting nothing on the output had no effect on initial trials. Is first display
298     // assumed to be physical?
299     *outType = static_cast<IComposerClient::DisplayType>(HWC2_DISPLAY_TYPE_PHYSICAL);
300     return Error::NONE;
301 }
302 
getDozeSupport(Display,bool *)303 Error FakeComposerClient::getDozeSupport(Display /*display*/, bool* /*outSupport*/) {
304     ALOGV("getDozeSupport");
305     return Error::NONE;
306 }
307 
getHdrCapabilities(Display,hidl_vec<Hdr> *,float *,float *,float *)308 Error FakeComposerClient::getHdrCapabilities(Display /*display*/, hidl_vec<Hdr>* /*outTypes*/,
309                                              float* /*outMaxLuminance*/,
310                                              float* /*outMaxAverageLuminance*/,
311                                              float* /*outMinLuminance*/) {
312     ALOGV("getHdrCapabilities");
313     return Error::NONE;
314 }
315 
setActiveConfig(Display,Config config)316 Error FakeComposerClient::setActiveConfig(Display /*display*/, Config config) {
317     ALOGV("setActiveConfig");
318     mCurrentConfig = config;
319     return Error::NONE;
320 }
321 
setColorMode(Display,ColorMode)322 Error FakeComposerClient::setColorMode(Display /*display*/, ColorMode /*mode*/) {
323     ALOGV("setColorMode");
324     return Error::NONE;
325 }
326 
setPowerMode(Display,IComposerClient::PowerMode)327 Error FakeComposerClient::setPowerMode(Display /*display*/, IComposerClient::PowerMode /*mode*/) {
328     ALOGV("setPowerMode");
329     return Error::NONE;
330 }
331 
setVsyncEnabled(Display,IComposerClient::Vsync enabled)332 Error FakeComposerClient::setVsyncEnabled(Display /*display*/, IComposerClient::Vsync enabled) {
333     mVsyncEnabled = (enabled == IComposerClient::Vsync::ENABLE);
334     ALOGV("setVsyncEnabled(%s)", mVsyncEnabled ? "ENABLE" : "DISABLE");
335     return Error::NONE;
336 }
337 
setColorTransform(Display,const float *,int32_t)338 Error FakeComposerClient::setColorTransform(Display /*display*/, const float* /*matrix*/,
339                                             int32_t /*hint*/) {
340     ALOGV("setColorTransform");
341     return Error::NONE;
342 }
343 
setClientTarget(Display,buffer_handle_t,int32_t,int32_t,const std::vector<hwc_rect_t> &)344 Error FakeComposerClient::setClientTarget(Display /*display*/, buffer_handle_t /*target*/,
345                                           int32_t /*acquireFence*/, int32_t /*dataspace*/,
346                                           const std::vector<hwc_rect_t>& /*damage*/) {
347     ALOGV("setClientTarget");
348     return Error::NONE;
349 }
350 
setOutputBuffer(Display,buffer_handle_t,int32_t)351 Error FakeComposerClient::setOutputBuffer(Display /*display*/, buffer_handle_t /*buffer*/,
352                                           int32_t /*releaseFence*/) {
353     ALOGV("setOutputBuffer");
354     return Error::NONE;
355 }
356 
validateDisplay(Display,std::vector<Layer> *,std::vector<IComposerClient::Composition> *,uint32_t *,std::vector<Layer> *,std::vector<uint32_t> *)357 Error FakeComposerClient::validateDisplay(
358         Display /*display*/, std::vector<Layer>* /*outChangedLayers*/,
359         std::vector<IComposerClient::Composition>* /*outCompositionTypes*/,
360         uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
361         std::vector<uint32_t>* /*outRequestMasks*/) {
362     ALOGV("validateDisplay");
363     // TODO: Assume touching nothing means All Korrekt!
364     return Error::NONE;
365 }
366 
acceptDisplayChanges(Display)367 Error FakeComposerClient::acceptDisplayChanges(Display /*display*/) {
368     ALOGV("acceptDisplayChanges");
369     // Didn't ask for changes because software is omnipotent.
370     return Error::NONE;
371 }
372 
layerZOrdering(const std::unique_ptr<FrameRect> & a,const std::unique_ptr<FrameRect> & b)373 bool layerZOrdering(const std::unique_ptr<FrameRect>& a, const std::unique_ptr<FrameRect>& b) {
374     return a->z <= b->z;
375 }
376 
presentDisplay(Display,int32_t *,std::vector<Layer> *,std::vector<int32_t> *)377 Error FakeComposerClient::presentDisplay(Display /*display*/, int32_t* /*outPresentFence*/,
378                                          std::vector<Layer>* /*outLayers*/,
379                                          std::vector<int32_t>* /*outReleaseFences*/) {
380     ALOGV("presentDisplay");
381     // TODO Leaving layers and their fences out for now. Doing so
382     // means that we've already processed everything. Important to
383     // test that the fences are respected, though. (How?)
384 
385     std::unique_ptr<Frame> newFrame(new Frame);
386     for (uint64_t layer = 0; layer < mLayers.size(); layer++) {
387         const LayerImpl& layerImpl = *mLayers[layer];
388 
389         if (!layerImpl.mValid) continue;
390 
391         auto rect = std::make_unique<FrameRect>(layer, layerImpl.mRenderState, layerImpl.mZ);
392         newFrame->rectangles.push_back(std::move(rect));
393     }
394     std::sort(newFrame->rectangles.begin(), newFrame->rectangles.end(), layerZOrdering);
395     {
396         Mutex::Autolock _l(mStateMutex);
397         mFrames.push_back(std::move(newFrame));
398         mFramesAvailable.broadcast();
399     }
400     return Error::NONE;
401 }
402 
setLayerCursorPosition(Display,Layer,int32_t,int32_t)403 Error FakeComposerClient::setLayerCursorPosition(Display /*display*/, Layer /*layer*/,
404                                                  int32_t /*x*/, int32_t /*y*/) {
405     ALOGV("setLayerCursorPosition");
406     return Error::NONE;
407 }
408 
setLayerBuffer(Display,Layer layer,buffer_handle_t buffer,int32_t acquireFence)409 Error FakeComposerClient::setLayerBuffer(Display /*display*/, Layer layer, buffer_handle_t buffer,
410                                          int32_t acquireFence) {
411     ALOGV("setLayerBuffer");
412     LayerImpl& l = getLayerImpl(layer);
413     if (buffer != l.mRenderState.mBuffer) {
414         l.mRenderState.mSwapCount++; // TODO: Is setting to same value a swap or not?
415     }
416     l.mRenderState.mBuffer = buffer;
417     l.mRenderState.mAcquireFence = acquireFence;
418 
419     return Error::NONE;
420 }
421 
setLayerSurfaceDamage(Display,Layer,const std::vector<hwc_rect_t> &)422 Error FakeComposerClient::setLayerSurfaceDamage(Display /*display*/, Layer /*layer*/,
423                                                 const std::vector<hwc_rect_t>& /*damage*/) {
424     ALOGV("setLayerSurfaceDamage");
425     return Error::NONE;
426 }
427 
setLayerBlendMode(Display,Layer layer,int32_t mode)428 Error FakeComposerClient::setLayerBlendMode(Display /*display*/, Layer layer, int32_t mode) {
429     ALOGV("setLayerBlendMode");
430     getLayerImpl(layer).mRenderState.mBlendMode = static_cast<hwc2_blend_mode_t>(mode);
431     return Error::NONE;
432 }
433 
setLayerColor(Display,Layer layer,IComposerClient::Color color)434 Error FakeComposerClient::setLayerColor(Display /*display*/, Layer layer,
435                                         IComposerClient::Color color) {
436     ALOGV("setLayerColor");
437     getLayerImpl(layer).mRenderState.mLayerColor.r = color.r;
438     getLayerImpl(layer).mRenderState.mLayerColor.g = color.g;
439     getLayerImpl(layer).mRenderState.mLayerColor.b = color.b;
440     getLayerImpl(layer).mRenderState.mLayerColor.a = color.a;
441     return Error::NONE;
442 }
443 
setLayerCompositionType(Display,Layer,int32_t)444 Error FakeComposerClient::setLayerCompositionType(Display /*display*/, Layer /*layer*/,
445                                                   int32_t /*type*/) {
446     ALOGV("setLayerCompositionType");
447     return Error::NONE;
448 }
449 
setLayerDataspace(Display,Layer,int32_t)450 Error FakeComposerClient::setLayerDataspace(Display /*display*/, Layer /*layer*/,
451                                             int32_t /*dataspace*/) {
452     ALOGV("setLayerDataspace");
453     return Error::NONE;
454 }
455 
setLayerDisplayFrame(Display,Layer layer,const hwc_rect_t & frame)456 Error FakeComposerClient::setLayerDisplayFrame(Display /*display*/, Layer layer,
457                                                const hwc_rect_t& frame) {
458     ALOGV("setLayerDisplayFrame (%d, %d, %d, %d)", frame.left, frame.top, frame.right,
459           frame.bottom);
460     getLayerImpl(layer).mRenderState.mDisplayFrame = frame;
461     return Error::NONE;
462 }
463 
setLayerPlaneAlpha(Display,Layer layer,float alpha)464 Error FakeComposerClient::setLayerPlaneAlpha(Display /*display*/, Layer layer, float alpha) {
465     ALOGV("setLayerPlaneAlpha");
466     getLayerImpl(layer).mRenderState.mPlaneAlpha = alpha;
467     return Error::NONE;
468 }
469 
setLayerSidebandStream(Display,Layer,buffer_handle_t)470 Error FakeComposerClient::setLayerSidebandStream(Display /*display*/, Layer /*layer*/,
471                                                  buffer_handle_t /*stream*/) {
472     ALOGV("setLayerSidebandStream");
473     return Error::NONE;
474 }
475 
setLayerSourceCrop(Display,Layer layer,const hwc_frect_t & crop)476 Error FakeComposerClient::setLayerSourceCrop(Display /*display*/, Layer layer,
477                                              const hwc_frect_t& crop) {
478     ALOGV("setLayerSourceCrop");
479     getLayerImpl(layer).mRenderState.mSourceCrop = crop;
480     return Error::NONE;
481 }
482 
setLayerTransform(Display,Layer layer,int32_t transform)483 Error FakeComposerClient::setLayerTransform(Display /*display*/, Layer layer, int32_t transform) {
484     ALOGV("setLayerTransform");
485     getLayerImpl(layer).mRenderState.mTransform = static_cast<hwc_transform_t>(transform);
486     return Error::NONE;
487 }
488 
setLayerVisibleRegion(Display,Layer layer,const std::vector<hwc_rect_t> & visible)489 Error FakeComposerClient::setLayerVisibleRegion(Display /*display*/, Layer layer,
490                                                 const std::vector<hwc_rect_t>& visible) {
491     ALOGV("setLayerVisibleRegion");
492     getLayerImpl(layer).mRenderState.mVisibleRegion = visible;
493     return Error::NONE;
494 }
495 
setLayerZOrder(Display,Layer layer,uint32_t z)496 Error FakeComposerClient::setLayerZOrder(Display /*display*/, Layer layer, uint32_t z) {
497     ALOGV("setLayerZOrder");
498     getLayerImpl(layer).mZ = z;
499     return Error::NONE;
500 }
501 
502 //////////////////////////////////////////////////////////////////
503 
requestVSync(uint64_t vsyncTime)504 void FakeComposerClient::requestVSync(uint64_t vsyncTime) {
505     if (mEventCallback) {
506         uint64_t timestamp = vsyncTime;
507         ALOGV("Vsync");
508         if (timestamp == 0) {
509             struct timespec ts;
510             clock_gettime(CLOCK_MONOTONIC, &ts);
511             timestamp = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
512         }
513         if (mSurfaceComposer != nullptr) {
514             mSurfaceComposer->injectVSync(timestamp);
515         } else {
516             mEventCallback->onVsync(PRIMARY_DISPLAY, timestamp);
517         }
518     }
519 }
520 
runVSyncAfter(std::chrono::nanoseconds wait)521 void FakeComposerClient::runVSyncAfter(std::chrono::nanoseconds wait) {
522     mDelayedEventGenerator->wakeAfter(wait);
523 }
524 
getLayerImpl(Layer handle)525 LayerImpl& FakeComposerClient::getLayerImpl(Layer handle) {
526     // TODO Change these to an internal state check that can be
527     // invoked from the gtest? GTest macros do not seem all that safe
528     // when used outside the test class
529     EXPECT_GE(handle, static_cast<Layer>(0));
530     EXPECT_LT(handle, mLayers.size());
531     return *(mLayers[handle]);
532 }
533 
getFrameCount() const534 int FakeComposerClient::getFrameCount() const {
535     return mFrames.size();
536 }
537 
extractRenderState(const std::vector<std::unique_ptr<FrameRect>> & internalRects)538 static std::vector<RenderState> extractRenderState(
539         const std::vector<std::unique_ptr<FrameRect>>& internalRects) {
540     std::vector<RenderState> result;
541     result.reserve(internalRects.size());
542     for (const std::unique_ptr<FrameRect>& rect : internalRects) {
543         result.push_back(rect->renderState);
544     }
545     return result;
546 }
547 
getFrameRects(int frame) const548 std::vector<RenderState> FakeComposerClient::getFrameRects(int frame) const {
549     Mutex::Autolock _l(mStateMutex);
550     return extractRenderState(mFrames[frame]->rectangles);
551 }
552 
getLatestFrame() const553 std::vector<RenderState> FakeComposerClient::getLatestFrame() const {
554     Mutex::Autolock _l(mStateMutex);
555     return extractRenderState(mFrames[mFrames.size() - 1]->rectangles);
556 }
557 
runVSyncAndWait(std::chrono::nanoseconds maxWait)558 void FakeComposerClient::runVSyncAndWait(std::chrono::nanoseconds maxWait) {
559     int currentFrame = 0;
560     {
561         Mutex::Autolock _l(mStateMutex); // I hope this is ok...
562         currentFrame = static_cast<int>(mFrames.size());
563         requestVSync();
564     }
565     waitUntilFrame(currentFrame + 1, maxWait);
566 }
567 
waitUntilFrame(int targetFrame,std::chrono::nanoseconds maxWait) const568 void FakeComposerClient::waitUntilFrame(int targetFrame, std::chrono::nanoseconds maxWait) const {
569     Mutex::Autolock _l(mStateMutex);
570     while (mFrames.size() < static_cast<size_t>(targetFrame)) {
571         android::status_t result = mFramesAvailable.waitRelative(mStateMutex, maxWait.count());
572         if (result == android::TIMED_OUT) {
573             ALOGE("Waiting for frame %d (at frame %zu now) timed out after %lld ns", targetFrame,
574                   mFrames.size(), maxWait.count());
575             return;
576         }
577     }
578 }
579 
clearFrames()580 void FakeComposerClient::clearFrames() {
581     Mutex::Autolock _l(mStateMutex);
582     mFrames.clear();
583     for (const std::unique_ptr<LayerImpl>& layer : mLayers) {
584         if (layer->mValid) {
585             layer->mRenderState.mSwapCount = 0;
586         }
587     }
588 }
589 
onSurfaceFlingerStart()590 void FakeComposerClient::onSurfaceFlingerStart() {
591     mSurfaceComposer = nullptr;
592     do {
593         mSurfaceComposer = new android::SurfaceComposerClient;
594         android::status_t initResult = mSurfaceComposer->initCheck();
595         if (initResult != android::NO_ERROR) {
596             ALOGD("Init result: %d", initResult);
597             mSurfaceComposer = nullptr;
598             std::this_thread::sleep_for(10ms);
599         }
600     } while (mSurfaceComposer == nullptr);
601     ALOGD("SurfaceComposerClient created");
602     mSurfaceComposer->enableVSyncInjections(true);
603 }
604 
onSurfaceFlingerStop()605 void FakeComposerClient::onSurfaceFlingerStop() {
606     mSurfaceComposer->dispose();
607     mSurfaceComposer.clear();
608 }
609 
610 // Includes destroyed layers, stored in order of creation.
getLayerCount() const611 int FakeComposerClient::getLayerCount() const {
612     return mLayers.size();
613 }
614 
getLayer(size_t index) const615 Layer FakeComposerClient::getLayer(size_t index) const {
616     // NOTE: If/when passing calls through to actual implementation,
617     // this might get more involving.
618     return static_cast<Layer>(index);
619 }
620