chromium/services/audio/output_device_mixer_manager_unittest.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/audio/output_device_mixer_manager.h"

#include <optional>

#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_io.h"
#include "media/audio/mock_audio_manager.h"
#include "media/audio/test_audio_thread.h"
#include "media/base/audio_parameters.h"
#include "services/audio/output_device_mixer.h"
#include "services/audio/reference_output.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

_;
ByMove;
Eq;
InSequence;
NiceMock;
Ref;
Return;
ReturnRef;
StrictMock;

AudioOutputStream;
AudioParameters;

RunOnceClosure;

namespace audio {
namespace {

// The "default" and "communications" strings represent reserved device IDs.
// They are used in different situations, but the OutputDeviceMixerManager
// should treat all reserved device IDs the same way.
enum class ReservedIdTestType {};

// Matches non-null device change callbacks.
MATCHER(ValidDeviceChangeCallback, "") {}

// Matches an expected media::AudioParameters.
MATCHER_P(ExactParams, expected, "") {}

// Matches media::AudioParameters that are equal in all aspects,
// except for sample_per_buffer()
MATCHER_P(CompatibleParams, expected, "") {}

const std::string kFakeDeviceId =;
const std::string kOtherFakeDeviceId =;
const std::string kFakeCommunicationsId =;
const std::string kEmptyDeviceId =;
const std::string kNormalizedDefaultDeviceId =;
const auto* kReservedDefaultId =;
const auto* kReservedCommsId =;

class MockAudioOutputStream : public AudioOutputStream {};

class LocalMockAudioManager : public media::MockAudioManager {};

class MockListener : public audio::ReferenceOutput::Listener {};

class MockOutputDeviceMixer : public audio::OutputDeviceMixer {};
}  // namespace

class OutputDeviceMixerManagerTest
    : public ::testing::TestWithParam<ReservedIdTestType> {};

// Makes sure we can create an output stream for the reserved output devices.
TEST_P(OutputDeviceMixerManagerTest, MakeOutputStream_ForReservedDevice) {}

// Makes sure we can create a default output stream when AudioManager doesn't
// support getting the current default ID.
TEST_P(OutputDeviceMixerManagerTest,
       MakeOutputStream_ForReservedDevice_NoGetReservedOuputDeviceIdSupport) {}

// Makes sure the empty string resolves to the "default" device.
TEST_F(OutputDeviceMixerManagerTest,
       MakeOutputStream_ForDefaultDevice_EmptyDeviceId) {}

// Makes sure we can create an output stream for physical IDs that match a
// reserved ID's.
TEST_P(OutputDeviceMixerManagerTest,
       MakeOutputStream_ForSpecificDeviceId_MatchesCurrentReservedId) {}

// Makes sure we can create an output stream for a device ID when
// AudioManager::GetDefaultOutputDeviceId() is unsupported.
TEST_P(OutputDeviceMixerManagerTest,
       MakeOutputStream_ForSpecificDeviceId_NoGetDefaultOuputDeviceIdSupport) {}

// Makes sure we can create an output stream for a device ID when
// AudioManager doesn't support getting the current reserved ID.
TEST_P(OutputDeviceMixerManagerTest,
       MakeOutputStream_ForSpecificDeviceId_NoGetGetReservedIdSupport) {}

// Makes sure we can create an output stream a device ID for a device that is
// not any device.
TEST_F(OutputDeviceMixerManagerTest,
       MakeOutputStream_ForSpecificDeviceId_IdDoesntMatchReservedIds) {}

// Makes sure we get the correct output parameters from the AudioManager when
// creating streams.
TEST_F(OutputDeviceMixerManagerTest,
       MakeOutputStream_GetsDeviceOrDefaultParams) {}

// Makes sure we still get an unmixable stream when requesting bitstream
// formats.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_WithBitstreamFormat) {}

// Makes sure we still get an unmixable stream if device info is stale and
// AudioManager::GetOutputStreamParameters() returns invalid parameters.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_WithStaleDeviceInfo) {}

// Makes sure we handle running out of stream proxies.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_MaxProxies) {}

// Makes sure we handle failing to create a mixer.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_MixerCreationFails) {}

// Makes sure we handle the case when the output mixer returns a nullptr when
// creating a stream.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_MixerReturnsNull) {}

// Makes sure creating multiple output streams for the same device ID re-uses
// the same OutputDeviceMixer.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_OneMixerPerId) {}

// Makes sure creating an output stream for a "reserved ID" or the
// "current reserved device ID" is equivalent, and the mixer is shared.
TEST_P(OutputDeviceMixerManagerTest,
       MakeOutputStream_ReservedIdAndCurrentReservedDeviceIdShareOneMixer) {}

// Makes sure we create one output mixer per device ID.
TEST_F(OutputDeviceMixerManagerTest, MakeOutputStream_TwoDevicesTwoMixers) {}

// Makes sure the default mixer is separate from other mixers.
TEST_F(OutputDeviceMixerManagerTest,
       MakeOutputStream_DefaultMixerDistinctFromOtherMixers) {}

// Makes sure the communications mixer is separate from other mixers.
TEST_F(OutputDeviceMixerManagerTest,
       MakeOutputStream_CommunicationsMixerDistinctFromOtherMixers) {}

// Makes sure we get the latest reserved device ID each time we create a stream
// for a reserved ID.
TEST_P(OutputDeviceMixerManagerTest,
       MakeOutputStream_CurrentReseredIdIsUpdatedAfterDeviceChange) {}

// Makes sure OutputDeviceMixers are notified of device changes.
TEST_P(OutputDeviceMixerManagerTest,
       OnDeviceChange_MixersReceiveDeviceChanges) {}

// Makes sure OnDeviceChange() is only called once per device change.
TEST_F(OutputDeviceMixerManagerTest, OnDeviceChange_OncePerDeviceChange) {}

// Attach/detach listeners with no mixer.
TEST_F(OutputDeviceMixerManagerTest, DeviceOutputListener_StartStop) {}

// Attach/detach listeners to multiple devices with no mixers.
TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartStop_MultipleDevice) {}

// Attach/detach multiple listeners to a single device with no mixer.
TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartStop_MultipleListener) {}

// Attach/detach to the reserved device.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartStop_ReservedId) {}

// Listeners are attached as they are added.
TEST_F(OutputDeviceMixerManagerTest, DeviceOutputListener_CreateStartStop) {}

// Listeners are attached on mixer creation.
TEST_F(OutputDeviceMixerManagerTest, DeviceOutputListener_StartCreateStop) {}

// Removed listeners are not attached.
TEST_F(OutputDeviceMixerManagerTest, DeviceOutputListener_StartStopCreate) {}

// Listeners are attached as they are added.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_CreateStartStop_NoGetReservedIdSupport) {}

// Listeners are attached on mixer creation.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartCreateStop_NoGetReservedIdSupport) {}

// Removed listeners are not attached.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartStopCreate_NoGetReservedIdSupport) {}

// Removed listeners are not attached, and remaining listeners are.
TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartStopCreate_TwoListeners) {}

TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_CreateStartStop_ReservedId) {}

TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartCreateStop_ReservedId) {}

TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartStopCreate_ReservedId) {}

TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_StartCreateStop_DefaultId_EmptyDeviceId) {}

// Makes sure reserved-listeners are attached to the reserved-mixer when it is
// created via current_reserved_physical_device().
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_ReservedListenersAttachToCurrentReservedIdMixer) {}

// Makes sure current_reserved_physical_device() listeners are attached when the
// reserved-mixer is created.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_CurrentReservedIdListenersAttachToReservedMixer) {}

// Makes sure the presence of listeners does not force device recreation
// on device change.
TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_NoCreateAfterDeviceChange_WithListeners) {}

// Makes sure listeners are re-attached when mixers are recreated.
TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_ListenersReattachedAfterDeviceChange) {}

// Makes sure the reserved listeners are re-attached when mixers are
// re-created.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_ReservedIdListenersReattachedAfterDeviceChange) {}

// Makes sure the reserved listeners are not attached to non-reserved listeners,
// if support for AudioManager's GetDefaultOutputDeviceID() or
// GetCommunicationsOutputDeviceID() changes.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_CurrentDefaultListenersNotReattached) {}

// Makes sure both "default listeners" and "current_reserved_physical_device()
// listeners" get attached to the same current_reserved_physical_device() mixer.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_CurrentDefaultMixerCreation_ListenersAttached) {}

// Makes sure both "reserved listeners" and "current_reserve_physical_device()
// listeners" get attached to the same reserved mixer.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_ReservedIdMixerCreation_ListenersAttached) {}

// Makes sure both "reserved listeners" and "current_reserved_physical_device()
// listeners" don't get attached to non-reserved mixers.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_OtherDeviceMixerCreation_ListenersNotAttached) {}

// Makes sure we can call StartListening multiple times with the same listener,
// when the different device IDs map to the same mixer.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_MultipleStarts_EquivalentIds) {}

// Makes sure we can call StartListening multiple times with the same listener,
// with different device IDs.
TEST_F(OutputDeviceMixerManagerTest,
       DeviceOutputListener_MultipleStarts_DifferentIds) {}

// Makes sure listeners are properly updated internally when going from a
// reserved to a specific device.
TEST_P(OutputDeviceMixerManagerTest,
       DeviceOutputListener_MultipleStarts_ReservedToSpecific) {}

// Makes sure that there one shared default and communications mixer, if the
// current default and communication physical IDs are identical.
TEST_F(OutputDeviceMixerManagerTest,
       ReservedIds_DefaultAndCommunicationsPhysicalIdsShared) {}

// Makes sure that we map "communications" to kNormalizedDefaultDeviceId if the
// current physical communications device ID is empty.
TEST_F(OutputDeviceMixerManagerTest,
       ReservedIds_EmptyCommunicationsPhysicalId) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace audio