MockGraphInterface.h (3901B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOCK_GRAPH_INTERFACE_H_ 8 #define MOCK_GRAPH_INTERFACE_H_ 9 10 #include <tuple> 11 12 #include "GraphDriver.h" 13 #include "gmock/gmock.h" 14 15 namespace mozilla { 16 17 class MockGraphInterface : public GraphInterface { 18 NS_DECL_THREADSAFE_ISUPPORTS 19 explicit MockGraphInterface(TrackRate aSampleRate) 20 : mSampleRate(aSampleRate) {} 21 MOCK_METHOD(void, NotifyInputStopped, ()); 22 MOCK_METHOD(void, NotifyInputData, 23 (const AudioDataValue*, size_t, TrackRate, uint32_t, uint32_t)); 24 MOCK_METHOD(void, NotifySetRequestedInputProcessingParamsResult, 25 (AudioCallbackDriver*, int, 26 (Result<cubeb_input_processing_params, int>&&))); 27 MOCK_METHOD(void, DeviceChanged, ()); 28 #ifdef DEBUG 29 MOCK_METHOD(bool, InDriverIteration, (const GraphDriver*), (const)); 30 #endif 31 /* OneIteration cannot be mocked because IterationResult is non-memmovable and 32 * cannot be passed as a parameter, which GMock does internally. */ 33 MOCK_METHOD(void, MockIteration, (GraphTime aStateComputedTime), ()); 34 IterationResult OneIteration(GraphTime aStateComputedTime, 35 MixerCallbackReceiver* aMixerReceiver) { 36 MockIteration(aStateComputedTime); 37 GraphDriver* driver = mCurrentDriver; 38 if (aMixerReceiver) { 39 mMixer.StartMixing(); 40 mMixer.Mix(nullptr, driver->AsAudioCallbackDriver()->OutputChannelCount(), 41 aStateComputedTime - mStateComputedTime, mSampleRate); 42 aMixerReceiver->MixerCallback(mMixer.MixedChunk(), mSampleRate); 43 } 44 if (aStateComputedTime != mStateComputedTime) { 45 mFramesIteratedEvent.Notify(aStateComputedTime - mStateComputedTime); 46 ++mIterationCount; 47 } 48 mStateComputedTime = aStateComputedTime; 49 if (!mKeepProcessing) { 50 return IterationResult::CreateStop( 51 NS_NewRunnableFunction(__func__, [] {})); 52 } 53 if (auto guard = mNextDriver.Lock(); guard->isSome()) { 54 auto tup = guard->extract(); 55 const auto& [driver, switchedRunnable] = tup; 56 return IterationResult::CreateSwitchDriver(driver, switchedRunnable); 57 } 58 if (mEnsureNextIteration) { 59 driver->EnsureNextIteration(); 60 } 61 return IterationResult::CreateStillProcessing(); 62 } 63 void SetEnsureNextIteration(bool aEnsure) { mEnsureNextIteration = aEnsure; } 64 65 size_t IterationCount() const { return mIterationCount; } 66 67 GraphTime StateComputedTime() const { return mStateComputedTime; } 68 void SetCurrentDriver(GraphDriver* aDriver) { mCurrentDriver = aDriver; } 69 70 void StopIterating() { mKeepProcessing = false; } 71 72 void SwitchTo(RefPtr<GraphDriver> aDriver, 73 RefPtr<Runnable> aSwitchedRunnable = NS_NewRunnableFunction( 74 "DefaultNoopSwitchedRunnable", [] {})) { 75 auto guard = mNextDriver.Lock(); 76 MOZ_RELEASE_ASSERT(guard->isNothing()); 77 *guard = 78 Some(std::make_tuple(std::move(aDriver), std::move(aSwitchedRunnable))); 79 } 80 const TrackRate mSampleRate; 81 82 MediaEventSource<uint32_t>& FramesIteratedEvent() { 83 return mFramesIteratedEvent; 84 } 85 86 protected: 87 Atomic<size_t> mIterationCount{0}; 88 Atomic<GraphTime> mStateComputedTime{0}; 89 Atomic<GraphDriver*> mCurrentDriver{nullptr}; 90 Atomic<bool> mEnsureNextIteration{false}; 91 Atomic<bool> mKeepProcessing{true}; 92 DataMutex<Maybe<std::tuple<RefPtr<GraphDriver>, RefPtr<Runnable>>>> 93 mNextDriver{"MockGraphInterface::mNextDriver"}; 94 RefPtr<Runnable> mNextDriverSwitchedRunnable; 95 MediaEventProducer<uint32_t> mFramesIteratedEvent; 96 AudioMixer mMixer; 97 virtual ~MockGraphInterface() = default; 98 }; 99 100 } // namespace mozilla 101 102 #endif