Implement use of Device.setConnectedState/_7_1 HAL method
Add 'Device.setConnectedState' to libaudiohal. It tries
to use Device.setConnectedState_7_1 when supported, or
fallbacks to Device.setConnectedState.
Remove direct use of setParameters from the framework
code. Add required plumbing between APM and AF.
Bug: 211601178
Test: on the device, check that HAL still receives the update
Change-Id: Ic9ac6fbea6ceea7db504d9c962392d90e21f57cb
(cherry picked from commit 516d398b4432022b1d39c8b32df25a6b894c010a)
Merged-In: Ic9ac6fbea6ceea7db504d9c962392d90e21f57cb
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 2af1c50..504e4f8 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -765,6 +765,12 @@
return statusTFromBinderStatus(mDelegate->updateSecondaryOutputs(trackSecondaryOutputInfos));
}
+status_t AudioFlingerClientAdapter::setDeviceConnectedState(
+ const struct audio_port_v7 *port, bool connected) {
+ media::AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPort(*port));
+ return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
+}
////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
@@ -1236,4 +1242,10 @@
return Status::fromStatusT(mDelegate->updateSecondaryOutputs(trackSecondaryOutputs));
}
+Status AudioFlingerServerAdapter::setDeviceConnectedState(
+ const media::AudioPort& port, bool connected) {
+ audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+ return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
+}
+
} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 7ffcc33..5cdde5d 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -216,4 +216,6 @@
// This usually happens when there is a dynamic policy registered.
void updateSecondaryOutputs(
in TrackSecondaryOutputInfo[] trackSecondaryOutputInfos);
+
+ void setDeviceConnectedState(in AudioPort devicePort, boolean connected);
}
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 9e5019e..6d4ab8e 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -347,6 +347,8 @@
virtual status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) = 0;
+
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
};
/**
@@ -443,6 +445,7 @@
status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) override;
+ status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -528,6 +531,7 @@
SET_AUDIO_HAL_PIDS = media::BnAudioFlingerService::TRANSACTION_setAudioHalPids,
SET_VIBRATOR_INFOS = media::BnAudioFlingerService::TRANSACTION_setVibratorInfos,
UPDATE_SECONDARY_OUTPUTS = media::BnAudioFlingerService::TRANSACTION_updateSecondaryOutputs,
+ SET_DEVICE_CONNECTED_STATE = media::BnAudioFlingerService::TRANSACTION_setDeviceConnectedState,
};
/**
@@ -637,6 +641,7 @@
Status setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
Status updateSecondaryOutputs(
const std::vector<media::TrackSecondaryOutputInfo>& trackSecondaryOutputInfos) override;
+ Status setDeviceConnectedState(const media::AudioPort& port, bool connected) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 50311e5..f450c22 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -478,6 +478,32 @@
}
#endif
+status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ if (mDevice == 0) return NO_INIT;
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ if (supportsSetConnectedState7_1) {
+ AudioPort hidlPort;
+ if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
+ return result;
+ }
+ Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
+ if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
+ return processReturn("setConnectedState_7_1", ret);
+ } else if (ret == Result::OK) {
+ return NO_ERROR;
+ }
+ supportsSetConnectedState7_1 = false;
+ }
+#endif
+ DeviceAddress hidlAddress;
+ if (status_t result = CoreUtils::deviceAddressFromHal(
+ port->ext.device.type, port->ext.device.address, &hidlAddress);
+ result != NO_ERROR) {
+ return result;
+ }
+ return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
+}
+
status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
if (mDevice == 0) return NO_INIT;
native_handle_t* hidlHandle = native_handle_create(1, 0);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index d2b31d4..fb0be5a 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -115,13 +115,16 @@
status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+ status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
+
status_t dump(int fd, const Vector<String16>& args) override;
private:
friend class DevicesFactoryHalHidl;
sp<::android::hardware::audio::CPP_VERSION::IDevice> mDevice;
- sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice> mPrimaryDevice;
// Null if it's not a primary device.
+ sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice> mPrimaryDevice;
+ bool supportsSetConnectedState7_1 = true;
// Can not be constructed directly by clients.
explicit DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device);
diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp
index 1384c1e..e473e41 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.cpp
+++ b/media/libaudiohal/impl/DeviceHalLocal.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "DeviceHalLocal"
//#define LOG_NDEBUG 0
+#include <media/AudioParameter.h>
#include <utils/Log.h>
#include "DeviceHalLocal.h"
@@ -232,6 +233,14 @@
return INVALID_OPERATION;
}
+status_t DeviceHalLocal::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ AudioParameter param(String8(port->ext.device.address));
+ const String8 key(connected ?
+ AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect);
+ param.addInt(key, port->ext.device.type);
+ return setParameters(param.toString());
+}
+
status_t DeviceHalLocal::dump(int fd, const Vector<String16>& /* args */) {
return mDev->dump(mDev, fd);
}
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
index a75ce2e..79db930 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.h
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -111,6 +111,8 @@
status_t addDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
status_t removeDeviceEffect(audio_port_handle_t device, sp<EffectHalInterface> effect) override;
+ status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
+
status_t dump(int fd, const Vector<String16>& args) override;
void closeOutputStream(struct audio_stream_out *stream_out);
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 69cbcec..f0a0b29 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -120,6 +120,9 @@
virtual status_t removeDeviceEffect(
audio_port_handle_t device, sp<EffectHalInterface> effect) = 0;
+ // Update the connection status of an external device.
+ virtual status_t setConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+
virtual status_t dump(int fd, const Vector<String16>& args) = 0;
protected:
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index fcbcf46..2897ac8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -335,6 +335,24 @@
return NO_ERROR;
}
+status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) {
+ status_t final_result = NO_INIT;
+ Mutex::Autolock _l(mLock);
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_SET_CONNECTED_STATE;
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+ status_t result = dev->setConnectedState(port, connected);
+ // Same logic as with setParameter: it's a success if at least one
+ // HAL module accepts the update.
+ if (final_result != NO_ERROR) {
+ final_result = result;
+ }
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
+ return final_result;
+}
+
// getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
const media::AudioVibratorInfo* AudioFlinger::getDefaultVibratorInfo_l() {
if (mAudioVibratorInfos.empty()) {
@@ -4184,6 +4202,7 @@
case TransactionCode::SET_AUDIO_PORT_CONFIG:
case TransactionCode::SET_RECORD_SILENCED:
case TransactionCode::AUDIO_POLICY_READY:
+ case TransactionCode::SET_DEVICE_CONNECTED_STATE:
ALOGW("%s: transaction %d received from PID %d",
__func__, code, IPCThreadState::self()->getCallingPid());
// return status only for non void methods
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 5df270e..0863126 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -282,6 +282,8 @@
virtual status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs);
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected);
+
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
const std::function<status_t()>& delegate) override;
@@ -903,6 +905,7 @@
AUDIO_HW_SET_MASTER_MUTE, // set_master_mute
AUDIO_HW_GET_MASTER_MUTE, // get_master_mute
AUDIO_HW_GET_MICROPHONES, // getMicrophones
+ AUDIO_HW_SET_CONNECTED_STATE, // setConnectedState
};
mutable hardware_call_state mHardwareStatus; // for dump only
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 602671e..ca6ba1e 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -459,6 +459,8 @@
virtual status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) = 0;
+
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
};
// These are the signatures of createAudioPolicyManager/destroyAudioPolicyManager
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4ce7851..b028e8f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -112,11 +112,14 @@
void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
audio_policy_dev_state_t state)
{
- AudioParameter param(String8(device->address().c_str()));
- const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
- AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect);
- param.addInt(key, device->type());
- mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
+ audio_port_v7 devicePort;
+ device->toAudioPort(&devicePort);
+ if (status_t status = mpClientInterface->setDeviceConnectedState(
+ &devicePort, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
+ status != OK) {
+ ALOGE("Error %d while setting connected state for device %s", status,
+ device->getDeviceTypeAddr().toString(false).c_str());
+ }
}
status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index cd53073..469c93e 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -301,4 +301,15 @@
return af->updateSecondaryOutputs(trackSecondaryOutputs);
}
+status_t AudioPolicyService::AudioPolicyClient::setDeviceConnectedState(
+ const struct audio_port_v7 *port, bool connected) {
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ ALOGW("%s: could not get AudioFlinger", __func__);
+ return PERMISSION_DENIED;
+ }
+ return af->setDeviceConnectedState(port, connected);
+}
+
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 9ec5341..0c97591 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -761,6 +761,9 @@
status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) override;
+ status_t setDeviceConnectedState(
+ const struct audio_port_v7 *port, bool connected) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index f7b0565..90076e8 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -102,6 +102,11 @@
++mAudioPortListUpdateCount;
}
+ status_t setDeviceConnectedState(
+ const struct audio_port_v7 *port __unused, bool connected __unused) override {
+ return NO_ERROR;
+ }
+
// Helper methods for tests
size_t getActivePatchesCount() const { return mActivePatches.size(); }
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 1384864..25902e9 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -95,6 +95,10 @@
const TrackSecondaryOutputsMap& trackSecondaryOutputs __unused) override {
return NO_INIT;
}
+ status_t setDeviceConnectedState(
+ const struct audio_port_v7 *port __unused, bool connected __unused) override {
+ return NO_INIT;
+ }
};
} // namespace android