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 <algorithm> 20 #include <chrono> 21 #include <variant> 22 23 #include <compositionengine/Display.h> 24 #include <compositionengine/LayerFECompositionState.h> 25 #include <compositionengine/OutputLayer.h> 26 #include <compositionengine/impl/CompositionEngine.h> 27 #include <compositionengine/impl/Display.h> 28 #include <compositionengine/impl/OutputLayerCompositionState.h> 29 #include <compositionengine/mock/DisplaySurface.h> 30 #include <gui/ScreenCaptureResults.h> 31 32 #include "BufferQueueLayer.h" 33 #include "BufferStateLayer.h" 34 #include "ContainerLayer.h" 35 #include "DisplayDevice.h" 36 #include "EffectLayer.h" 37 #include "FakeVsyncConfiguration.h" 38 #include "FrameTracer/FrameTracer.h" 39 #include "Layer.h" 40 #include "NativeWindowSurface.h" 41 #include "Scheduler/MessageQueue.h" 42 #include "Scheduler/RefreshRateConfigs.h" 43 #include "StartPropertySetThread.h" 44 #include "SurfaceFlinger.h" 45 #include "SurfaceFlingerDefaultFactory.h" 46 #include "SurfaceInterceptor.h" 47 #include "TestableScheduler.h" 48 #include "mock/DisplayHardware/MockComposer.h" 49 #include "mock/DisplayHardware/MockDisplayMode.h" 50 #include "mock/MockFrameTimeline.h" 51 #include "mock/MockFrameTracer.h" 52 #include "mock/MockSchedulerCallback.h" 53 54 namespace android { 55 56 class EventThread; 57 58 namespace renderengine { 59 60 class RenderEngine; 61 62 } // namespace renderengine 63 64 namespace Hwc2 { 65 66 class Composer; 67 68 } // namespace Hwc2 69 70 namespace hal = android::hardware::graphics::composer::hal; 71 72 namespace surfaceflinger::test { 73 74 class Factory final : public surfaceflinger::Factory { 75 public: 76 ~Factory() = default; 77 createHWComposer(const std::string &)78 std::unique_ptr<HWComposer> createHWComposer(const std::string&) override { 79 return nullptr; 80 } 81 createVsyncConfiguration(Fps)82 std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( 83 Fps /*currentRefreshRate*/) override { 84 return std::make_unique<scheduler::FakePhaseOffsets>(); 85 } 86 createSurfaceInterceptor()87 sp<SurfaceInterceptor> createSurfaceInterceptor() override { 88 return new android::impl::SurfaceInterceptor(); 89 } 90 createStartPropertySetThread(bool timestampPropertyValue)91 sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override { 92 return new StartPropertySetThread(timestampPropertyValue); 93 } 94 createDisplayDevice(DisplayDeviceCreationArgs & creationArgs)95 sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs& creationArgs) override { 96 return new DisplayDevice(creationArgs); 97 } 98 createGraphicBuffer(uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,std::string requestorName)99 sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height, PixelFormat format, 100 uint32_t layerCount, uint64_t usage, 101 std::string requestorName) override { 102 return new GraphicBuffer(width, height, format, layerCount, usage, requestorName); 103 } 104 createBufferQueue(sp<IGraphicBufferProducer> * outProducer,sp<IGraphicBufferConsumer> * outConsumer,bool consumerIsSurfaceFlinger)105 void createBufferQueue(sp<IGraphicBufferProducer>* outProducer, 106 sp<IGraphicBufferConsumer>* outConsumer, 107 bool consumerIsSurfaceFlinger) override { 108 if (!mCreateBufferQueue) { 109 BufferQueue::createBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger); 110 return; 111 } 112 mCreateBufferQueue(outProducer, outConsumer, consumerIsSurfaceFlinger); 113 } 114 createMonitoredProducer(const sp<IGraphicBufferProducer> & producer,const sp<SurfaceFlinger> & flinger,const wp<Layer> & layer)115 sp<IGraphicBufferProducer> createMonitoredProducer(const sp<IGraphicBufferProducer>& producer, 116 const sp<SurfaceFlinger>& flinger, 117 const wp<Layer>& layer) override { 118 return new MonitoredProducer(producer, flinger, layer); 119 } 120 createBufferLayerConsumer(const sp<IGraphicBufferConsumer> & consumer,renderengine::RenderEngine & renderEngine,uint32_t textureName,Layer * layer)121 sp<BufferLayerConsumer> createBufferLayerConsumer(const sp<IGraphicBufferConsumer>& consumer, 122 renderengine::RenderEngine& renderEngine, 123 uint32_t textureName, Layer* layer) override { 124 return new BufferLayerConsumer(consumer, renderEngine, textureName, layer); 125 } 126 createNativeWindowSurface(const sp<IGraphicBufferProducer> & producer)127 std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface( 128 const sp<IGraphicBufferProducer>& producer) override { 129 if (!mCreateNativeWindowSurface) return nullptr; 130 return mCreateNativeWindowSurface(producer); 131 } 132 createCompositionEngine()133 std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override { 134 return compositionengine::impl::createCompositionEngine(); 135 } 136 createBufferQueueLayer(const LayerCreationArgs &)137 sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override { 138 return nullptr; 139 } 140 createBufferStateLayer(const LayerCreationArgs &)141 sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs&) override { 142 return nullptr; 143 } 144 createEffectLayer(const LayerCreationArgs &)145 sp<EffectLayer> createEffectLayer(const LayerCreationArgs&) override { return nullptr; } 146 createContainerLayer(const LayerCreationArgs &)147 sp<ContainerLayer> createContainerLayer(const LayerCreationArgs&) override { 148 return nullptr; 149 } 150 createFrameTracer()151 std::unique_ptr<FrameTracer> createFrameTracer() override { 152 return std::make_unique<mock::FrameTracer>(); 153 } 154 155 std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline( 156 std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid = 0) override { 157 return std::make_unique<mock::FrameTimeline>(timeStats, surfaceFlingerPid); 158 } 159 160 using CreateBufferQueueFunction = 161 std::function<void(sp<IGraphicBufferProducer>* /* outProducer */, 162 sp<IGraphicBufferConsumer>* /* outConsumer */, 163 bool /* consumerIsSurfaceFlinger */)>; 164 CreateBufferQueueFunction mCreateBufferQueue; 165 166 using CreateNativeWindowSurfaceFunction = 167 std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>( 168 const sp<IGraphicBufferProducer>&)>; 169 CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface; 170 171 using CreateCompositionEngineFunction = 172 std::function<std::unique_ptr<compositionengine::CompositionEngine>()>; 173 CreateCompositionEngineFunction mCreateCompositionEngine; 174 }; 175 176 } // namespace surfaceflinger::test 177 178 class TestableSurfaceFlinger { 179 public: 180 using HotplugEvent = SurfaceFlinger::HotplugEvent; 181 mFlinger(flinger)182 TestableSurfaceFlinger(sp<SurfaceFlinger> flinger = nullptr) : mFlinger(flinger) { 183 if (!mFlinger) { 184 mFlinger = sp<SurfaceFlinger>::make(mFactory, SurfaceFlinger::SkipInitialization); 185 } 186 mFlinger->mAnimationTransactionTimeout = ms2ns(10); 187 } 188 flinger()189 SurfaceFlinger* flinger() { return mFlinger.get(); } scheduler()190 scheduler::TestableScheduler* scheduler() { return mScheduler; } 191 192 // Extend this as needed for accessing SurfaceFlinger private (and public) 193 // functions. 194 setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine)195 void setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) { 196 mFlinger->mCompositionEngine->setRenderEngine(std::move(renderEngine)); 197 } 198 setupComposer(std::unique_ptr<Hwc2::Composer> composer)199 void setupComposer(std::unique_ptr<Hwc2::Composer> composer) { 200 mFlinger->mCompositionEngine->setHwComposer( 201 std::make_unique<impl::HWComposer>(std::move(composer))); 202 } 203 setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor> powerAdvisor)204 void setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor> powerAdvisor) { 205 mFlinger->mPowerAdvisor = std::move(powerAdvisor); 206 } 207 setupTimeStats(const std::shared_ptr<TimeStats> & timeStats)208 void setupTimeStats(const std::shared_ptr<TimeStats>& timeStats) { 209 mFlinger->mCompositionEngine->setTimeStats(timeStats); 210 } 211 212 enum class SchedulerCallbackImpl { kNoOp, kMock }; 213 214 static constexpr struct OneDisplayMode { 215 } kOneDisplayMode; 216 217 static constexpr struct TwoDisplayModes { 218 } kTwoDisplayModes; 219 220 using RefreshRateConfigsPtr = std::shared_ptr<scheduler::RefreshRateConfigs>; 221 222 using DisplayModesVariant = 223 std::variant<OneDisplayMode, TwoDisplayModes, RefreshRateConfigsPtr>; 224 225 void setupScheduler(std::unique_ptr<scheduler::VsyncController> vsyncController, 226 std::unique_ptr<scheduler::VSyncTracker> vsyncTracker, 227 std::unique_ptr<EventThread> appEventThread, 228 std::unique_ptr<EventThread> sfEventThread, 229 SchedulerCallbackImpl callbackImpl = SchedulerCallbackImpl::kNoOp, 230 DisplayModesVariant modesVariant = kOneDisplayMode, 231 bool useNiceMock = false) { 232 RefreshRateConfigsPtr configs; 233 if (std::holds_alternative<RefreshRateConfigsPtr>(modesVariant)) { 234 configs = std::move(std::get<RefreshRateConfigsPtr>(modesVariant)); 235 } else { 236 constexpr DisplayModeId kModeId60{0}; 237 DisplayModes modes = makeModes(mock::createDisplayMode(kModeId60, 60_Hz)); 238 239 if (std::holds_alternative<TwoDisplayModes>(modesVariant)) { 240 constexpr DisplayModeId kModeId90{1}; 241 modes.try_emplace(kModeId90, mock::createDisplayMode(kModeId90, 90_Hz)); 242 } 243 244 configs = std::make_shared<scheduler::RefreshRateConfigs>(modes, kModeId60); 245 } 246 247 const auto fps = configs->getActiveMode()->getFps(); 248 mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(fps); 249 mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make( 250 mFlinger->mVsyncConfiguration->getCurrentConfigs()); 251 252 mFlinger->mRefreshRateStats = 253 std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, fps, 254 hal::PowerMode::OFF); 255 256 using Callback = scheduler::ISchedulerCallback; 257 Callback& callback = callbackImpl == SchedulerCallbackImpl::kNoOp 258 ? static_cast<Callback&>(mNoOpSchedulerCallback) 259 : static_cast<Callback&>(mSchedulerCallback); 260 261 if (useNiceMock) { 262 mScheduler = 263 new testing::NiceMock<scheduler::TestableScheduler>(std::move(vsyncController), 264 std::move(vsyncTracker), 265 std::move(configs), 266 callback); 267 } else { 268 mScheduler = new scheduler::TestableScheduler(std::move(vsyncController), 269 std::move(vsyncTracker), 270 std::move(configs), callback); 271 } 272 273 mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread)); 274 mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread)); 275 resetScheduler(mScheduler); 276 } 277 resetScheduler(scheduler::Scheduler * scheduler)278 void resetScheduler(scheduler::Scheduler* scheduler) { mFlinger->mScheduler.reset(scheduler); } 279 mutableScheduler()280 scheduler::TestableScheduler& mutableScheduler() { return *mScheduler; } mockSchedulerCallback()281 scheduler::mock::SchedulerCallback& mockSchedulerCallback() { return mSchedulerCallback; } 282 mutableVsyncModulator()283 auto& mutableVsyncModulator() { return mFlinger->mVsyncModulator; } 284 285 using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction; setCreateBufferQueueFunction(CreateBufferQueueFunction f)286 void setCreateBufferQueueFunction(CreateBufferQueueFunction f) { 287 mFactory.mCreateBufferQueue = f; 288 } 289 290 using CreateNativeWindowSurfaceFunction = 291 surfaceflinger::test::Factory::CreateNativeWindowSurfaceFunction; setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f)292 void setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f) { 293 mFactory.mCreateNativeWindowSurface = f; 294 } 295 setInternalDisplayPrimaries(const ui::DisplayPrimaries & primaries)296 void setInternalDisplayPrimaries(const ui::DisplayPrimaries& primaries) { 297 memcpy(&mFlinger->mInternalDisplayPrimaries, &primaries, sizeof(ui::DisplayPrimaries)); 298 } 299 mutableLayerDrawingState(const sp<Layer> & layer)300 static auto& mutableLayerDrawingState(const sp<Layer>& layer) { return layer->mDrawingState; } 301 mutableStateLock()302 auto& mutableStateLock() { return mFlinger->mStateLock; } 303 findOutputLayerForDisplay(const sp<Layer> & layer,const sp<const DisplayDevice> & display)304 static auto findOutputLayerForDisplay(const sp<Layer>& layer, 305 const sp<const DisplayDevice>& display) { 306 return layer->findOutputLayerForDisplay(display.get()); 307 } 308 setLayerSidebandStream(const sp<Layer> & layer,const sp<NativeHandle> & sidebandStream)309 static void setLayerSidebandStream(const sp<Layer>& layer, 310 const sp<NativeHandle>& sidebandStream) { 311 layer->mDrawingState.sidebandStream = sidebandStream; 312 layer->mSidebandStream = sidebandStream; 313 layer->editCompositionState()->sidebandStream = sidebandStream; 314 } 315 setLayerCompositionType(const sp<Layer> & layer,aidl::android::hardware::graphics::composer3::Composition type)316 void setLayerCompositionType(const sp<Layer>& layer, 317 aidl::android::hardware::graphics::composer3::Composition type) { 318 auto outputLayer = findOutputLayerForDisplay(layer, mFlinger->getDefaultDisplayDevice()); 319 LOG_ALWAYS_FATAL_IF(!outputLayer); 320 auto& state = outputLayer->editState(); 321 LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc); 322 (*state.hwc).hwcCompositionType = type; 323 } 324 setLayerPotentialCursor(const sp<Layer> & layer,bool potentialCursor)325 static void setLayerPotentialCursor(const sp<Layer>& layer, bool potentialCursor) { 326 layer->mPotentialCursor = potentialCursor; 327 } 328 setLayerDrawingParent(const sp<Layer> & layer,const sp<Layer> & drawingParent)329 static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) { 330 layer->mDrawingParent = drawingParent; 331 } 332 setPowerHintSessionMode(bool early,bool late)333 void setPowerHintSessionMode(bool early, bool late) { 334 mFlinger->mPowerHintSessionMode = {.late = late, .early = early}; 335 } 336 337 /* ------------------------------------------------------------------------ 338 * Forwarding for functions being tested 339 */ 340 commit(nsecs_t frameTime,int64_t vsyncId,nsecs_t expectedVSyncTime)341 nsecs_t commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVSyncTime) { 342 mFlinger->commit(frameTime, vsyncId, expectedVSyncTime); 343 return frameTime; 344 } 345 commit(nsecs_t frameTime,int64_t vsyncId)346 nsecs_t commit(nsecs_t frameTime, int64_t vsyncId) { 347 std::chrono::nanoseconds period = 10ms; 348 return commit(frameTime, vsyncId, frameTime + period.count()); 349 } 350 commit()351 nsecs_t commit() { 352 const nsecs_t now = systemTime(); 353 const nsecs_t expectedVsyncTime = now + 10'000'000; 354 return commit(now, kVsyncId, expectedVsyncTime); 355 } 356 commitAndComposite(const nsecs_t frameTime,const int64_t vsyncId,const nsecs_t expectedVsyncTime)357 void commitAndComposite(const nsecs_t frameTime, const int64_t vsyncId, 358 const nsecs_t expectedVsyncTime) { 359 mFlinger->composite(commit(frameTime, vsyncId, expectedVsyncTime), kVsyncId); 360 } 361 commitAndComposite()362 void commitAndComposite() { mFlinger->composite(commit(), kVsyncId); } 363 createDisplay(const String8 & displayName,bool secure)364 auto createDisplay(const String8& displayName, bool secure) { 365 return mFlinger->createDisplay(displayName, secure); 366 } 367 destroyDisplay(const sp<IBinder> & displayToken)368 auto destroyDisplay(const sp<IBinder>& displayToken) { 369 return mFlinger->destroyDisplay(displayToken); 370 } 371 getDisplay(const sp<IBinder> & displayToken)372 auto getDisplay(const sp<IBinder>& displayToken) { 373 Mutex::Autolock lock(mFlinger->mStateLock); 374 return mFlinger->getDisplayDeviceLocked(displayToken); 375 } 376 enableHalVirtualDisplays(bool enable)377 void enableHalVirtualDisplays(bool enable) { mFlinger->enableHalVirtualDisplays(enable); } 378 setupNewDisplayDeviceInternal(const wp<IBinder> & displayToken,std::shared_ptr<compositionengine::Display> compositionDisplay,const DisplayDeviceState & state,const sp<compositionengine::DisplaySurface> & dispSurface,const sp<IGraphicBufferProducer> & producer)379 auto setupNewDisplayDeviceInternal( 380 const wp<IBinder>& displayToken, 381 std::shared_ptr<compositionengine::Display> compositionDisplay, 382 const DisplayDeviceState& state, 383 const sp<compositionengine::DisplaySurface>& dispSurface, 384 const sp<IGraphicBufferProducer>& producer) NO_THREAD_SAFETY_ANALYSIS { 385 return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, 386 dispSurface, producer); 387 } 388 commitTransactionsLocked(uint32_t transactionFlags)389 auto commitTransactionsLocked(uint32_t transactionFlags) { 390 Mutex::Autolock lock(mFlinger->mStateLock); 391 return mFlinger->commitTransactionsLocked(transactionFlags); 392 } 393 onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,hal::Connection connection)394 void onComposerHalHotplug(hal::HWDisplayId hwcDisplayId, hal::Connection connection) { 395 mFlinger->onComposerHalHotplug(hwcDisplayId, connection); 396 } 397 setDisplayStateLocked(const DisplayState & s)398 auto setDisplayStateLocked(const DisplayState& s) { 399 Mutex::Autolock lock(mFlinger->mStateLock); 400 return mFlinger->setDisplayStateLocked(s); 401 } 402 403 // Allow reading display state without locking, as if called on the SF main thread. onInitializeDisplays()404 auto onInitializeDisplays() NO_THREAD_SAFETY_ANALYSIS { 405 return mFlinger->onInitializeDisplays(); 406 } 407 notifyPowerBoost(int32_t boostId)408 auto notifyPowerBoost(int32_t boostId) { return mFlinger->notifyPowerBoost(boostId); } 409 setDisplayBrightness(const sp<IBinder> & display,const gui::DisplayBrightness & brightness)410 auto setDisplayBrightness(const sp<IBinder>& display, 411 const gui::DisplayBrightness& brightness) { 412 return mFlinger->setDisplayBrightness(display, brightness); 413 } 414 415 // Allow reading display state without locking, as if called on the SF main thread. setPowerModeInternal(const sp<DisplayDevice> & display,hal::PowerMode mode)416 auto setPowerModeInternal(const sp<DisplayDevice>& display, 417 hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS { 418 return mFlinger->setPowerModeInternal(display, mode); 419 } 420 renderScreenImpl(const RenderArea & renderArea,SurfaceFlinger::TraverseLayersFunction traverseLayers,const std::shared_ptr<renderengine::ExternalTexture> & buffer,bool forSystem,bool regionSampling)421 auto renderScreenImpl(const RenderArea& renderArea, 422 SurfaceFlinger::TraverseLayersFunction traverseLayers, 423 const std::shared_ptr<renderengine::ExternalTexture>& buffer, 424 bool forSystem, bool regionSampling) { 425 ScreenCaptureResults captureResults; 426 return mFlinger->renderScreenImpl(renderArea, traverseLayers, buffer, forSystem, 427 regionSampling, false /* grayscale */, 428 captureResults); 429 } 430 traverseLayersInLayerStack(ui::LayerStack layerStack,int32_t uid,const LayerVector::Visitor & visitor)431 auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid, 432 const LayerVector::Visitor& visitor) { 433 return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid, visitor); 434 } 435 getDisplayNativePrimaries(const sp<IBinder> & displayToken,ui::DisplayPrimaries & primaries)436 auto getDisplayNativePrimaries(const sp<IBinder>& displayToken, 437 ui::DisplayPrimaries &primaries) { 438 return mFlinger->SurfaceFlinger::getDisplayNativePrimaries(displayToken, primaries); 439 } 440 getTransactionQueue()441 auto& getTransactionQueue() { return mFlinger->mTransactionQueue; } getPendingTransactionQueue()442 auto& getPendingTransactionQueue() { return mFlinger->mPendingTransactionQueues; } getTransactionCommittedSignals()443 auto& getTransactionCommittedSignals() { return mFlinger->mTransactionCommittedSignals; } 444 setTransactionState(const FrameTimelineInfo & frameTimelineInfo,const Vector<ComposerState> & states,const Vector<DisplayState> & displays,uint32_t flags,const sp<IBinder> & applyToken,const InputWindowCommands & inputWindowCommands,int64_t desiredPresentTime,bool isAutoTimestamp,const client_cache_t & uncacheBuffer,bool hasListenerCallbacks,std::vector<ListenerCallbacks> & listenerCallbacks,uint64_t transactionId)445 auto setTransactionState( 446 const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states, 447 const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, 448 const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, 449 bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, 450 std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) { 451 return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken, 452 inputWindowCommands, desiredPresentTime, 453 isAutoTimestamp, uncacheBuffer, hasListenerCallbacks, 454 listenerCallbacks, transactionId); 455 } 456 flushTransactionQueues()457 auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(0); }; 458 onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)459 auto onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 460 return mFlinger->onTransact(code, data, reply, flags); 461 } 462 getGPUContextPriority()463 auto getGPUContextPriority() { return mFlinger->getGPUContextPriority(); } 464 calculateMaxAcquiredBufferCount(Fps refreshRate,std::chrono::nanoseconds presentLatency)465 auto calculateMaxAcquiredBufferCount(Fps refreshRate, 466 std::chrono::nanoseconds presentLatency) const { 467 return SurfaceFlinger::calculateMaxAcquiredBufferCount(refreshRate, presentLatency); 468 } 469 setDesiredDisplayModeSpecs(const sp<IBinder> & displayToken,ui::DisplayModeId defaultMode,bool allowGroupSwitching,float primaryRefreshRateMin,float primaryRefreshRateMax,float appRequestRefreshRateMin,float appRequestRefreshRateMax)470 auto setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken, ui::DisplayModeId defaultMode, 471 bool allowGroupSwitching, float primaryRefreshRateMin, 472 float primaryRefreshRateMax, float appRequestRefreshRateMin, 473 float appRequestRefreshRateMax) { 474 return mFlinger->setDesiredDisplayModeSpecs(displayToken, defaultMode, allowGroupSwitching, 475 primaryRefreshRateMin, primaryRefreshRateMax, 476 appRequestRefreshRateMin, 477 appRequestRefreshRateMax); 478 } 479 onActiveDisplayChanged(const sp<DisplayDevice> & activeDisplay)480 void onActiveDisplayChanged(const sp<DisplayDevice>& activeDisplay) { 481 Mutex::Autolock lock(mFlinger->mStateLock); 482 mFlinger->onActiveDisplayChangedLocked(activeDisplay); 483 } 484 createLayer(LayerCreationArgs & args,sp<IBinder> * outHandle,const sp<IBinder> & parentHandle,int32_t * outLayerId,const sp<Layer> & parentLayer,uint32_t * outTransformHint)485 auto createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle, 486 const sp<IBinder>& parentHandle, int32_t* outLayerId, 487 const sp<Layer>& parentLayer, uint32_t* outTransformHint) { 488 return mFlinger->createLayer(args, outHandle, parentHandle, outLayerId, parentLayer, 489 outTransformHint); 490 } 491 mirrorLayer(const LayerCreationArgs & args,const sp<IBinder> & mirrorFromHandle,sp<IBinder> * outHandle,int32_t * outLayerId)492 auto mirrorLayer(const LayerCreationArgs& args, const sp<IBinder>& mirrorFromHandle, 493 sp<IBinder>* outHandle, int32_t* outLayerId) { 494 return mFlinger->mirrorLayer(args, mirrorFromHandle, outHandle, outLayerId); 495 } 496 497 /* ------------------------------------------------------------------------ 498 * Read-only access to private data to assert post-conditions. 499 */ 500 getAnimFrameTracker()501 const auto& getAnimFrameTracker() const { return mFlinger->mAnimFrameTracker; } getHasPoweredOff()502 const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; } getVisibleRegionsDirty()503 const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; } getHwComposer()504 auto& getHwComposer() const { 505 return static_cast<impl::HWComposer&>(mFlinger->getHwComposer()); 506 } getCompositionEngine()507 auto& getCompositionEngine() const { return mFlinger->getCompositionEngine(); } 508 getCompositorTiming()509 const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; } 510 getFrameTracer()511 mock::FrameTracer* getFrameTracer() const { 512 return static_cast<mock::FrameTracer*>(mFlinger->mFrameTracer.get()); 513 } 514 getAnimationTransactionTimeout()515 nsecs_t getAnimationTransactionTimeout() const { 516 return mFlinger->mAnimationTransactionTimeout; 517 } 518 519 /* ------------------------------------------------------------------------ 520 * Read-write access to private data to set up preconditions and assert 521 * post-conditions. 522 */ 523 displays()524 const auto& displays() const { return mFlinger->mDisplays; } currentState()525 const auto& currentState() const { return mFlinger->mCurrentState; } drawingState()526 const auto& drawingState() const { return mFlinger->mDrawingState; } transactionFlags()527 const auto& transactionFlags() const { return mFlinger->mTransactionFlags; } hwcPhysicalDisplayIdMap()528 const auto& hwcPhysicalDisplayIdMap() const { return getHwComposer().mPhysicalDisplayIdMap; } 529 mutableHasWideColorDisplay()530 auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; } 531 mutableCurrentState()532 auto& mutableCurrentState() { return mFlinger->mCurrentState; } mutableDisplayColorSetting()533 auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; } mutableDisplays()534 auto& mutableDisplays() { return mFlinger->mDisplays; } mutableDrawingState()535 auto& mutableDrawingState() { return mFlinger->mDrawingState; } mutableGeometryDirty()536 auto& mutableGeometryDirty() { return mFlinger->mGeometryDirty; } mutableInterceptor()537 auto& mutableInterceptor() { return mFlinger->mInterceptor; } mutableMainThreadId()538 auto& mutableMainThreadId() { return mFlinger->mMainThreadId; } mutablePendingHotplugEvents()539 auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; } mutablePhysicalDisplayTokens()540 auto& mutablePhysicalDisplayTokens() { return mFlinger->mPhysicalDisplayTokens; } mutableTexturePool()541 auto& mutableTexturePool() { return mFlinger->mTexturePool; } mutableTransactionFlags()542 auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; } mutableDebugDisableHWC()543 auto& mutableDebugDisableHWC() { return mFlinger->mDebugDisableHWC; } mutableMaxRenderTargetSize()544 auto& mutableMaxRenderTargetSize() { return mFlinger->mMaxRenderTargetSize; } 545 mutableHwcDisplayData()546 auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; } mutableHwcPhysicalDisplayIdMap()547 auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; } mutablePrimaryHwcDisplayId()548 auto& mutablePrimaryHwcDisplayId() { return getHwComposer().mPrimaryHwcDisplayId; } mutableActiveDisplayToken()549 auto& mutableActiveDisplayToken() { return mFlinger->mActiveDisplayToken; } 550 fromHandle(const sp<IBinder> & handle)551 auto fromHandle(const sp<IBinder>& handle) { 552 return mFlinger->fromHandle(handle); 553 } 554 ~TestableSurfaceFlinger()555 ~TestableSurfaceFlinger() { 556 // All these pointer and container clears help ensure that GMock does 557 // not report a leaked object, since the SurfaceFlinger instance may 558 // still be referenced by something despite our best efforts to destroy 559 // it after each test is done. 560 mutableDisplays().clear(); 561 mutableCurrentState().displays.clear(); 562 mutableDrawingState().displays.clear(); 563 mutableInterceptor().clear(); 564 mFlinger->mScheduler.reset(); 565 mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>()); 566 mFlinger->mCompositionEngine->setRenderEngine( 567 std::unique_ptr<renderengine::RenderEngine>()); 568 } 569 570 /* ------------------------------------------------------------------------ 571 * Wrapper classes for Read-write access to private data to set up 572 * preconditions and assert post-conditions. 573 */ 574 struct HWC2Display : public HWC2::impl::Display { HWC2DisplayHWC2Display575 HWC2Display( 576 Hwc2::Composer& composer, 577 const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>& 578 capabilities, 579 hal::HWDisplayId id, hal::DisplayType type) 580 : HWC2::impl::Display(composer, capabilities, id, type) {} ~HWC2DisplayHWC2Display581 ~HWC2Display() { 582 // Prevents a call to disable vsyncs. 583 mType = hal::DisplayType::INVALID; 584 } 585 mutableIsConnectedHWC2Display586 auto& mutableIsConnected() { return this->mIsConnected; } mutableLayersHWC2Display587 auto& mutableLayers() { return this->mLayers; } 588 }; 589 590 class FakeHwcDisplayInjector { 591 public: 592 static constexpr hal::HWDisplayId DEFAULT_HWC_DISPLAY_ID = 1000; 593 static constexpr ui::Size DEFAULT_RESOLUTION{1920, 1280}; 594 static constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667; 595 static constexpr int32_t DEFAULT_CONFIG_GROUP = 7; 596 static constexpr int32_t DEFAULT_DPI = 320; 597 static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0; 598 static constexpr hal::PowerMode DEFAULT_POWER_MODE = hal::PowerMode::ON; 599 FakeHwcDisplayInjector(HalDisplayId displayId,hal::DisplayType hwcDisplayType,bool isPrimary)600 FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType, 601 bool isPrimary) 602 : mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {} 603 setHwcDisplayId(hal::HWDisplayId displayId)604 auto& setHwcDisplayId(hal::HWDisplayId displayId) { 605 mHwcDisplayId = displayId; 606 return *this; 607 } 608 setResolution(ui::Size resolution)609 auto& setResolution(ui::Size resolution) { 610 mResolution = resolution; 611 return *this; 612 } 613 setVsyncPeriod(nsecs_t vsyncPeriod)614 auto& setVsyncPeriod(nsecs_t vsyncPeriod) { 615 mVsyncPeriod = vsyncPeriod; 616 return *this; 617 } 618 setDpiX(int32_t dpi)619 auto& setDpiX(int32_t dpi) { 620 mDpiX = dpi; 621 return *this; 622 } 623 setDpiY(int32_t dpi)624 auto& setDpiY(int32_t dpi) { 625 mDpiY = dpi; 626 return *this; 627 } 628 setActiveConfig(hal::HWConfigId config)629 auto& setActiveConfig(hal::HWConfigId config) { 630 mActiveConfig = config; 631 return *this; 632 } 633 setCapabilities(const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability> * capabilities)634 auto& setCapabilities( 635 const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>* 636 capabilities) { 637 mCapabilities = capabilities; 638 return *this; 639 } 640 setPowerMode(hal::PowerMode mode)641 auto& setPowerMode(hal::PowerMode mode) { 642 mPowerMode = mode; 643 return *this; 644 } 645 inject(TestableSurfaceFlinger * flinger,Hwc2::mock::Composer * composer)646 void inject(TestableSurfaceFlinger* flinger, Hwc2::mock::Composer* composer) { 647 using ::testing::_; 648 using ::testing::DoAll; 649 using ::testing::Return; 650 using ::testing::SetArgPointee; 651 652 static const std::unordered_set< 653 aidl::android::hardware::graphics::composer3::Capability> 654 defaultCapabilities; 655 if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities; 656 657 // Caution - Make sure that any values passed by reference here do 658 // not refer to an instance owned by FakeHwcDisplayInjector. This 659 // class has temporary lifetime, while the constructed HWC2::Display 660 // is much longer lived. 661 auto display = std::make_unique<HWC2Display>(*composer, *mCapabilities, mHwcDisplayId, 662 mHwcDisplayType); 663 664 display->mutableIsConnected() = true; 665 display->setPowerMode(mPowerMode); 666 flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display); 667 668 EXPECT_CALL(*composer, getDisplayConfigs(mHwcDisplayId, _)) 669 .WillRepeatedly( 670 DoAll(SetArgPointee<1>(std::vector<hal::HWConfigId>{mActiveConfig}), 671 Return(hal::Error::NONE))); 672 673 EXPECT_CALL(*composer, 674 getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::WIDTH, _)) 675 .WillRepeatedly(DoAll(SetArgPointee<3>(mResolution.getWidth()), 676 Return(hal::Error::NONE))); 677 678 EXPECT_CALL(*composer, 679 getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::HEIGHT, 680 _)) 681 .WillRepeatedly(DoAll(SetArgPointee<3>(mResolution.getHeight()), 682 Return(hal::Error::NONE))); 683 684 EXPECT_CALL(*composer, 685 getDisplayAttribute(mHwcDisplayId, mActiveConfig, 686 hal::Attribute::VSYNC_PERIOD, _)) 687 .WillRepeatedly(DoAll(SetArgPointee<3>(static_cast<int32_t>(mVsyncPeriod)), 688 Return(hal::Error::NONE))); 689 690 EXPECT_CALL(*composer, 691 getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_X, _)) 692 .WillRepeatedly(DoAll(SetArgPointee<3>(mDpiX), Return(hal::Error::NONE))); 693 694 EXPECT_CALL(*composer, 695 getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_Y, _)) 696 .WillRepeatedly(DoAll(SetArgPointee<3>(mDpiY), Return(hal::Error::NONE))); 697 698 EXPECT_CALL(*composer, 699 getDisplayAttribute(mHwcDisplayId, mActiveConfig, 700 hal::Attribute::CONFIG_GROUP, _)) 701 .WillRepeatedly( 702 DoAll(SetArgPointee<3>(mConfigGroup), Return(hal::Error::NONE))); 703 704 if (mHwcDisplayType == hal::DisplayType::PHYSICAL) { 705 const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId); 706 LOG_ALWAYS_FATAL_IF(!physicalId); 707 flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId); 708 if (mIsPrimary) { 709 flinger->mutablePrimaryHwcDisplayId() = mHwcDisplayId; 710 } else { 711 // If there is an external HWC display, there should always be a primary ID 712 // as well. Set it to some arbitrary value. 713 auto& primaryId = flinger->mutablePrimaryHwcDisplayId(); 714 if (!primaryId) primaryId = mHwcDisplayId - 1; 715 } 716 } 717 } 718 719 private: 720 const HalDisplayId mDisplayId; 721 const hal::DisplayType mHwcDisplayType; 722 const bool mIsPrimary; 723 724 hal::HWDisplayId mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID; 725 ui::Size mResolution = DEFAULT_RESOLUTION; 726 nsecs_t mVsyncPeriod = DEFAULT_VSYNC_PERIOD; 727 int32_t mDpiX = DEFAULT_DPI; 728 int32_t mDpiY = DEFAULT_DPI; 729 int32_t mConfigGroup = DEFAULT_CONFIG_GROUP; 730 hal::HWConfigId mActiveConfig = DEFAULT_ACTIVE_CONFIG; 731 hal::PowerMode mPowerMode = DEFAULT_POWER_MODE; 732 const std::unordered_set<aidl::android::hardware::graphics::composer3::Capability>* 733 mCapabilities = nullptr; 734 }; 735 736 class FakeDisplayDeviceInjector { 737 public: FakeDisplayDeviceInjector(TestableSurfaceFlinger & flinger,std::shared_ptr<compositionengine::Display> display,std::optional<ui::DisplayConnectionType> connectionType,std::optional<hal::HWDisplayId> hwcDisplayId,bool isPrimary)738 FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger, 739 std::shared_ptr<compositionengine::Display> display, 740 std::optional<ui::DisplayConnectionType> connectionType, 741 std::optional<hal::HWDisplayId> hwcDisplayId, bool isPrimary) 742 : mFlinger(flinger), 743 mCreationArgs(flinger.mFlinger.get(), flinger.mFlinger->getHwComposer(), 744 mDisplayToken, display), 745 mHwcDisplayId(hwcDisplayId) { 746 mCreationArgs.connectionType = connectionType; 747 mCreationArgs.isPrimary = isPrimary; 748 mCreationArgs.initialPowerMode = hal::PowerMode::ON; 749 } 750 token()751 sp<IBinder> token() const { return mDisplayToken; } 752 mutableDrawingDisplayState()753 DisplayDeviceState& mutableDrawingDisplayState() { 754 return mFlinger.mutableDrawingState().displays.editValueFor(mDisplayToken); 755 } 756 mutableCurrentDisplayState()757 DisplayDeviceState& mutableCurrentDisplayState() { 758 return mFlinger.mutableCurrentState().displays.editValueFor(mDisplayToken); 759 } 760 getDrawingDisplayState()761 const auto& getDrawingDisplayState() { 762 return mFlinger.mutableDrawingState().displays.valueFor(mDisplayToken); 763 } 764 getCurrentDisplayState()765 const auto& getCurrentDisplayState() { 766 return mFlinger.mutableCurrentState().displays.valueFor(mDisplayToken); 767 } 768 mutableDisplayDevice()769 const sp<DisplayDevice>& mutableDisplayDevice() { 770 return mFlinger.mutableDisplays().get(mDisplayToken)->get(); 771 } 772 773 // If `configs` is nullptr, the injector creates RefreshRateConfigs from the `modes`. 774 // Otherwise, it uses `configs`, which the caller must create using the same `modes`. 775 // 776 // TODO(b/182939859): Once `modes` can be retrieved from RefreshRateConfigs, remove 777 // the `configs` parameter in favor of an alternative setRefreshRateConfigs API. 778 auto& setDisplayModes(DisplayModes modes, DisplayModeId activeModeId, 779 std::shared_ptr<scheduler::RefreshRateConfigs> configs = nullptr) { 780 mCreationArgs.supportedModes = std::move(modes); 781 mCreationArgs.activeModeId = activeModeId; 782 mCreationArgs.refreshRateConfigs = std::move(configs); 783 return *this; 784 } 785 setNativeWindow(const sp<ANativeWindow> & nativeWindow)786 auto& setNativeWindow(const sp<ANativeWindow>& nativeWindow) { 787 mCreationArgs.nativeWindow = nativeWindow; 788 return *this; 789 } 790 setDisplaySurface(const sp<compositionengine::DisplaySurface> & displaySurface)791 auto& setDisplaySurface(const sp<compositionengine::DisplaySurface>& displaySurface) { 792 mCreationArgs.displaySurface = displaySurface; 793 return *this; 794 } 795 setSecure(bool secure)796 auto& setSecure(bool secure) { 797 mCreationArgs.isSecure = secure; 798 return *this; 799 } 800 setPowerMode(std::optional<hal::PowerMode> mode)801 auto& setPowerMode(std::optional<hal::PowerMode> mode) { 802 mCreationArgs.initialPowerMode = mode; 803 return *this; 804 } 805 setHwcColorModes(const std::unordered_map<ui::ColorMode,std::vector<ui::RenderIntent>> hwcColorModes)806 auto& setHwcColorModes( 807 const std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> 808 hwcColorModes) { 809 mCreationArgs.hwcColorModes = hwcColorModes; 810 return *this; 811 } 812 setHasWideColorGamut(bool hasWideColorGamut)813 auto& setHasWideColorGamut(bool hasWideColorGamut) { 814 mCreationArgs.hasWideColorGamut = hasWideColorGamut; 815 return *this; 816 } 817 setPhysicalOrientation(ui::Rotation orientation)818 auto& setPhysicalOrientation(ui::Rotation orientation) { 819 mCreationArgs.physicalOrientation = orientation; 820 return *this; 821 } 822 inject()823 sp<DisplayDevice> inject() NO_THREAD_SAFETY_ANALYSIS { 824 const auto displayId = mCreationArgs.compositionDisplay->getDisplayId(); 825 826 auto& modes = mCreationArgs.supportedModes; 827 auto& activeModeId = mCreationArgs.activeModeId; 828 829 if (displayId && !mCreationArgs.refreshRateConfigs) { 830 if (const auto physicalId = PhysicalDisplayId::tryCast(*displayId)) { 831 if (modes.empty()) { 832 constexpr DisplayModeId kModeId{0}; 833 DisplayModePtr mode = 834 DisplayMode::Builder(FakeHwcDisplayInjector::DEFAULT_ACTIVE_CONFIG) 835 .setId(kModeId) 836 .setPhysicalDisplayId(*physicalId) 837 .setResolution(FakeHwcDisplayInjector::DEFAULT_RESOLUTION) 838 .setVsyncPeriod( 839 FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD) 840 .setDpiX(FakeHwcDisplayInjector::DEFAULT_DPI) 841 .setDpiY(FakeHwcDisplayInjector::DEFAULT_DPI) 842 .setGroup(FakeHwcDisplayInjector::DEFAULT_CONFIG_GROUP) 843 .build(); 844 845 modes = ftl::init::map(kModeId, std::move(mode)); 846 activeModeId = kModeId; 847 } 848 849 mCreationArgs.refreshRateConfigs = 850 std::make_shared<scheduler::RefreshRateConfigs>(modes, activeModeId); 851 } 852 } 853 854 DisplayDeviceState state; 855 if (const auto type = mCreationArgs.connectionType) { 856 LOG_ALWAYS_FATAL_IF(!displayId); 857 const auto physicalId = PhysicalDisplayId::tryCast(*displayId); 858 LOG_ALWAYS_FATAL_IF(!physicalId); 859 LOG_ALWAYS_FATAL_IF(!mHwcDisplayId); 860 861 const auto activeMode = modes.get(activeModeId); 862 LOG_ALWAYS_FATAL_IF(!activeMode); 863 864 state.physical = {.id = *physicalId, 865 .type = *type, 866 .hwcDisplayId = *mHwcDisplayId, 867 .deviceProductInfo = {}, 868 .supportedModes = modes, 869 .activeMode = activeMode->get()}; 870 871 if (mCreationArgs.isPrimary) { 872 mFlinger.mutableActiveDisplayToken() = mDisplayToken; 873 } 874 } 875 876 state.isSecure = mCreationArgs.isSecure; 877 878 sp<DisplayDevice> display = sp<DisplayDevice>::make(mCreationArgs); 879 if (!display->isVirtual()) { 880 display->setActiveMode(activeModeId); 881 } 882 mFlinger.mutableDisplays().emplace_or_replace(mDisplayToken, display); 883 884 mFlinger.mutableCurrentState().displays.add(mDisplayToken, state); 885 mFlinger.mutableDrawingState().displays.add(mDisplayToken, state); 886 887 if (const auto& physical = state.physical) { 888 mFlinger.mutablePhysicalDisplayTokens().emplace_or_replace(physical->id, 889 mDisplayToken); 890 } 891 892 return display; 893 } 894 895 private: 896 TestableSurfaceFlinger& mFlinger; 897 sp<BBinder> mDisplayToken = new BBinder(); 898 DisplayDeviceCreationArgs mCreationArgs; 899 const std::optional<hal::HWDisplayId> mHwcDisplayId; 900 }; 901 902 private: 903 constexpr static int64_t kVsyncId = 123; 904 905 surfaceflinger::test::Factory mFactory; 906 sp<SurfaceFlinger> mFlinger; 907 scheduler::mock::SchedulerCallback mSchedulerCallback; 908 scheduler::mock::NoOpSchedulerCallback mNoOpSchedulerCallback; 909 scheduler::TestableScheduler* mScheduler = nullptr; 910 }; 911 912 } // namespace android 913