Merge "APM: Notify the client about new audio ports" into rvc-dev

gugelfrei
TreeHugger Robot 4 years ago committed by Android (Google) Code Review
commit 7bb5d6abf9

@ -133,12 +133,14 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
sp<DeviceDescriptor> device =
mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
if (device == 0) {
return INVALID_OPERATION;
}
return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION;
}
status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device,
audio_policy_dev_state_t state)
{
// handle output devices
if (audio_is_output_device(deviceType)) {
if (audio_is_output_device(device->type())) {
SortedVector <audio_io_handle_t> outputs;
ssize_t index = mAvailableOutputDevices.indexOf(device);
@ -155,7 +157,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
return INVALID_OPERATION;
}
ALOGV("%s() connecting device %s format %x",
__func__, device->toString().c_str(), encodedFormat);
__func__, device->toString().c_str(), device->getEncodedFormat());
// register new device as available
if (mAvailableOutputDevices.add(device) < 0) {
@ -217,16 +219,13 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
// output device used by a dynamic policy of type recorder as no
// playback use case is affected.
bool doCheckForDeviceAndOutputChanges = true;
if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
&& strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) {
if (device->type() == AUDIO_DEVICE_OUT_REMOTE_SUBMIX && device->address() != "0") {
for (audio_io_handle_t output : outputs) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
if (policyMix != nullptr
&& policyMix->mMixType == MIX_TYPE_RECORDERS
&& strncmp(device_address,
policyMix->mDeviceAddress.string(),
AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
&& device->address() == policyMix->mDeviceAddress.string()) {
doCheckForDeviceAndOutputChanges = false;
break;
}
@ -272,7 +271,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
// a valid device selection on those outputs.
bool force = (msdOutDevices.isEmpty() || msdOutDevices != desc->devices())
&& !desc->isDuplicated()
&& (!device_distinguishes_on_address(deviceType)
&& (!device_distinguishes_on_address(device->type())
// always force when disconnecting (a non-duplicated device)
|| (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
setOutputDevices(desc, newDevices, force, 0);
@ -288,7 +287,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
} // end if is output device
// handle input devices
if (audio_is_input_device(deviceType)) {
if (audio_is_input_device(device->type())) {
ssize_t index = mAvailableInputDevices.indexOf(device);
switch (state)
{
@ -4444,7 +4443,7 @@ status_t AudioPolicyManager::initialize() {
// after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
// open all output streams needed to access attached devices
onNewAudioModulesAvailable();
onNewAudioModulesAvailableInt(nullptr /*newDevices*/);
// make sure default device is reachable
if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
@ -4500,6 +4499,16 @@ status_t AudioPolicyManager::initCheck()
// ---
void AudioPolicyManager::onNewAudioModulesAvailable()
{
DeviceVector newDevices;
onNewAudioModulesAvailableInt(&newDevices);
if (!newDevices.empty()) {
nextAudioPortGeneration();
mpClientInterface->onAudioPortListUpdate();
}
}
void AudioPolicyManager::onNewAudioModulesAvailableInt(DeviceVector *newDevices)
{
for (const auto& hwModule : mHwModulesAll) {
if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
@ -4564,6 +4573,7 @@ void AudioPolicyManager::onNewAudioModulesAvailable()
if (!device->isAttached()) {
device->attach(hwModule);
mAvailableOutputDevices.add(device);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}
@ -4619,6 +4629,7 @@ void AudioPolicyManager::onNewAudioModulesAvailable()
device->attach(hwModule);
device->importAudioPortAndPickAudioProfile(inProfile, true);
mAvailableInputDevices.add(device);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}
}

@ -788,6 +788,8 @@ protected:
std::unordered_map<uid_t, audio_flags_mask_t> mAllowedCapturePolicies;
private:
void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
// Add or remove AC3 DTS encodings based on user preferences.
void modifySurroundFormats(const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr);
void modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr);
@ -878,6 +880,8 @@ private:
const char *device_address,
const char *device_name,
audio_format_t encodedFormat);
status_t setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device,
audio_policy_dev_state_t state);
void setEngineDeviceConnectionState(const sp<DeviceDescriptor> device,
audio_policy_dev_state_t state);

@ -1876,7 +1876,7 @@ void AudioPolicyService::setEffectSuspended(int effectId,
void AudioPolicyService::onNewAudioModulesAvailable()
{
mAudioCommandThread->audioModulesUpdateCommand();
mOutputCommandThread->audioModulesUpdateCommand();
}

@ -94,6 +94,10 @@ public:
return NO_ERROR;
}
void onAudioPortListUpdate() override {
++mAudioPortListUpdateCount;
}
// Helper methods for tests
size_t getActivePatchesCount() const { return mActivePatches.size(); }
@ -111,12 +115,15 @@ public:
mAllowedModuleNames.swap(names);
}
size_t getAudioPortListUpdateCount() const { return mAudioPortListUpdateCount; }
private:
audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
audio_io_handle_t mNextIoHandle = AUDIO_IO_HANDLE_NONE + 1;
audio_patch_handle_t mNextPatchHandle = AUDIO_PATCH_HANDLE_NONE + 1;
std::map<audio_patch_handle_t, struct audio_patch> mActivePatches;
std::set<std::string> mAllowedModuleNames;
size_t mAudioPortListUpdateCount = 0;
};
} // namespace android

@ -29,6 +29,7 @@ class AudioPolicyTestManager : public AudioPolicyManager {
using AudioPolicyManager::getOutputs;
using AudioPolicyManager::getAvailableOutputDevices;
using AudioPolicyManager::getAvailableInputDevices;
uint32_t getAudioPortGeneration() const { return mAudioPortGeneration; }
};
} // namespace android

@ -104,8 +104,10 @@ class AudioPolicyManagerTest : public testing::Test {
audio_port_handle_t *portId = nullptr);
PatchCountCheck snapshotPatchCount() { return PatchCountCheck(mClient.get()); }
void findDevicePort(audio_port_role_t role, audio_devices_t deviceType,
const std::string &address, audio_port &foundPort);
// Tries to find a device port. If 'foundPort' isn't nullptr,
// will generate a failure if the port hasn't been found.
bool findDevicePort(audio_port_role_t role, audio_devices_t deviceType,
const std::string &address, audio_port *foundPort);
static audio_port_handle_t getDeviceIdFromPatch(const struct audio_patch* patch);
std::unique_ptr<AudioPolicyManagerTestClient> mClient;
@ -211,30 +213,36 @@ void AudioPolicyManagerTest::getInputForAttr(
ASSERT_NE(AUDIO_PORT_HANDLE_NONE, *portId);
}
void AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
audio_devices_t deviceType, const std::string &address, audio_port &foundPort) {
bool AudioPolicyManagerTest::findDevicePort(audio_port_role_t role,
audio_devices_t deviceType, const std::string &address, audio_port *foundPort) {
uint32_t numPorts = 0;
uint32_t generation1;
status_t ret;
ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, nullptr, &generation1);
ASSERT_EQ(NO_ERROR, ret);
EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
if (HasFailure()) return false;
uint32_t generation2;
struct audio_port ports[numPorts];
ret = mManager->listAudioPorts(role, AUDIO_PORT_TYPE_DEVICE, &numPorts, ports, &generation2);
ASSERT_EQ(NO_ERROR, ret);
ASSERT_EQ(generation1, generation2);
EXPECT_EQ(NO_ERROR, ret) << "mManager->listAudioPorts returned error";
EXPECT_EQ(generation1, generation2) << "Generations changed during ports retrieval";
if (HasFailure()) return false;
for (const auto &port : ports) {
if (port.role == role && port.ext.device.type == deviceType &&
(strncmp(port.ext.device.address, address.c_str(),
AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
foundPort = port;
return;
if (foundPort) *foundPort = port;
return true;
}
}
GTEST_FAIL() << "Device port with role " << role << " and address " << address << "not found";
if (foundPort) {
ADD_FAILURE() << "Device port with role " << role << " and address "
<< address << " not found";
}
return false;
}
audio_port_handle_t AudioPolicyManagerTest::getDeviceIdFromPatch(
@ -694,8 +702,8 @@ void AudioPolicyManagerTestDPPlaybackReRouting::SetUp() {
ASSERT_EQ(NO_ERROR, ret);
struct audio_port extractionPort;
findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
mMixAddress, extractionPort);
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
mMixAddress, &extractionPort));
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
audio_source_t source = AUDIO_SOURCE_REMOTE_SUBMIX;
@ -707,8 +715,8 @@ void AudioPolicyManagerTestDPPlaybackReRouting::SetUp() {
ASSERT_EQ(NO_ERROR, mManager->startInput(mPortId));
ASSERT_EQ(extractionPort.id, selectedDeviceId);
findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
mMixAddress, mInjectionPort);
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
mMixAddress, &mInjectionPort));
}
void AudioPolicyManagerTestDPPlaybackReRouting::TearDown() {
@ -879,8 +887,8 @@ void AudioPolicyManagerTestDPMixRecordInjection::SetUp() {
ASSERT_EQ(NO_ERROR, ret);
struct audio_port injectionPort;
findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
mMixAddress, injectionPort);
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SINK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
mMixAddress, &injectionPort));
audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
audio_usage_t usage = AUDIO_USAGE_VIRTUAL_SOURCE;
@ -892,8 +900,8 @@ void AudioPolicyManagerTestDPMixRecordInjection::SetUp() {
ASSERT_EQ(NO_ERROR, mManager->startOutput(mPortId));
ASSERT_EQ(injectionPort.id, getDeviceIdFromPatch(mClient->getLastAddedPatch()));
findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
mMixAddress, mExtractionPort);
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX,
mMixAddress, &mExtractionPort));
}
void AudioPolicyManagerTestDPMixRecordInjection::TearDown() {
@ -1028,7 +1036,7 @@ TEST_P(AudioPolicyManagerTestDeviceConnection, ExplicitlyRoutingAfterConnection)
audio_port devicePort;
const audio_port_role_t role = audio_is_output_device(type)
? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
findDevicePort(role, type, address, devicePort);
ASSERT_TRUE(findDevicePort(role, type, address, &devicePort));
audio_port_handle_t routedPortId = devicePort.id;
// Try start input or output according to the device type
@ -1162,3 +1170,21 @@ TEST_F(AudioPolicyManagerDynamicHwModulesTest, AddedDeviceAvailable) {
ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE, mManager->getDeviceConnectionState(
AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0"));
}
TEST_F(AudioPolicyManagerDynamicHwModulesTest, ListAddedAudioPorts) {
ASSERT_FALSE(
findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", nullptr));
mClient->swapAllowedModuleNames({"primary", "r_submix"});
mManager->onNewAudioModulesAvailable();
struct audio_port port;
ASSERT_TRUE(findDevicePort(AUDIO_PORT_ROLE_SOURCE, AUDIO_DEVICE_IN_REMOTE_SUBMIX, "0", &port));
}
TEST_F(AudioPolicyManagerDynamicHwModulesTest, ClientIsUpdated) {
const size_t prevAudioPortListUpdateCount = mClient->getAudioPortListUpdateCount();
const uint32_t prevAudioPortGeneration = mManager->getAudioPortGeneration();
mClient->swapAllowedModuleNames({"primary", "r_submix"});
mManager->onNewAudioModulesAvailable();
EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
}

Loading…
Cancel
Save