1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "CubebUtils.h"
7 #include "GraphDriver.h"
8
9 #include "gmock/gmock.h"
10 #include "gtest/gtest-printers.h"
11 #include "gtest/gtest.h"
12
13 #include "mozilla/Attributes.h"
14 #include "mozilla/UniquePtr.h"
15 #include "nsTArray.h"
16
17 #include "MockCubeb.h"
18
19 using IterationResult = GraphInterface::IterationResult;
20 using ::testing::NiceMock;
21 using ::testing::Return;
22 using namespace mozilla;
23
24 class MockGraphInterface : public GraphInterface {
25 NS_DECL_THREADSAFE_ISUPPORTS
26 MOCK_METHOD4(NotifyOutputData,
27 void(AudioDataValue*, size_t, TrackRate, uint32_t));
28 MOCK_METHOD0(NotifyStarted, void());
29 MOCK_METHOD4(NotifyInputData,
30 void(const AudioDataValue*, size_t, TrackRate, uint32_t));
31 MOCK_METHOD0(DeviceChanged, void());
32 /* OneIteration cannot be mocked because IterationResult is non-memmovable and
33 * cannot be passed as a parameter, which GMock does internally. */
OneIteration(GraphTime,GraphTime,AudioMixer *)34 IterationResult OneIteration(GraphTime, GraphTime, AudioMixer*) {
35 return mKeepProcessing ? IterationResult::CreateStillProcessing()
36 : IterationResult::CreateStop(
37 NS_NewRunnableFunction(__func__, [] {}));
38 }
39 #ifdef DEBUG
InDriverIteration(GraphDriver * aDriver)40 bool InDriverIteration(GraphDriver* aDriver) override {
41 return aDriver->OnThread();
42 }
43 #endif
44
StopIterating()45 void StopIterating() { mKeepProcessing = false; }
46
47 protected:
48 Atomic<bool> mKeepProcessing{true};
49 virtual ~MockGraphInterface() = default;
50 };
51
52 NS_IMPL_ISUPPORTS0(MockGraphInterface)
53
TEST(TestAudioCallbackDriver,StartStop)54 TEST(TestAudioCallbackDriver, StartStop)
55 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
56 MockCubeb* cubeb = new MockCubeb();
57 CubebUtils::ForceSetCubebContext(cubeb->AsCubebContext());
58
59 RefPtr<AudioCallbackDriver> driver;
60 auto graph = MakeRefPtr<NiceMock<MockGraphInterface>>();
61 EXPECT_CALL(*graph, NotifyStarted).Times(1);
62 ON_CALL(*graph, NotifyOutputData)
63 .WillByDefault([&](AudioDataValue*, size_t, TrackRate, uint32_t) {});
64
65 driver = MakeRefPtr<AudioCallbackDriver>(graph, nullptr, 44100, 2, 0, nullptr,
66 nullptr, AudioInputType::Unknown);
67 EXPECT_FALSE(driver->ThreadRunning()) << "Verify thread is not running";
68 EXPECT_FALSE(driver->IsStarted()) << "Verify thread is not started";
69
70 driver->Start();
71 // Allow some time to "play" audio.
72 std::this_thread::sleep_for(std::chrono::milliseconds(200));
73 EXPECT_TRUE(driver->ThreadRunning()) << "Verify thread is running";
74 EXPECT_TRUE(driver->IsStarted()) << "Verify thread is started";
75
76 // This will block untill all events have been executed.
77 graph->StopIterating();
78 MOZ_KnownLive(driver)->Shutdown();
79 EXPECT_FALSE(driver->ThreadRunning()) << "Verify thread is not running";
80 EXPECT_FALSE(driver->IsStarted()) << "Verify thread is not started";
81 }
82