Add a mechanism for handling audio device configuration change
* Added new call handleDeviceConfigChange() to the Media Framework.
That call can be used when there are device configuration changes
(e.g., Bluetooth A2DP codec configuration has changed).
* Added new method AudioPolicyManager::handleDeviceConfigChange().
That method toggles the UNAVAILABLE/AVAILABLE connection state of the
device, so it can be reconfigured as appropriate - e.g., the audio
feeding parameters can be updated.
* Fix ALOGVV compilation errors when extra logging is enabled.
Test: A2DP streaming to headsets
Bug: 30958229
Change-Id: I388abbbb3ec4d1a003b441cb0c77e00d80cad668
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index bb8a8fa..d1b86da 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -81,6 +81,10 @@
// retrieve a device connection status
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
+ // indicate a change in device configuration
+ virtual status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name) = 0;
// indicate a change in phone state. Valid phones states are defined by audio_mode_t
virtual void setPhoneState(audio_mode_t state) = 0;
// force using a specific device category for the specified usage
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a8bdf86..8744de8 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -333,6 +333,47 @@
AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
+status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name)
+{
+ status_t status;
+
+ ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
+ device, device_address, device_name);
+
+ // Check if the device is currently connected
+ sp<DeviceDescriptor> devDesc =
+ mHwModules.getDeviceDescriptor(device, device_address, device_name);
+ ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
+ if (index < 0) {
+ // Nothing to do: device is not connected
+ return NO_ERROR;
+ }
+
+ // Toggle the device state: UNAVAILABLE -> AVAILABLE
+ // This will force reading again the device configuration
+ status = setDeviceConnectionState(device,
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ device_address, device_name);
+ if (status != NO_ERROR) {
+ ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
+ status);
+ return status;
+ }
+
+ status = setDeviceConnectionState(device,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ device_address, device_name);
+ if (status != NO_ERROR) {
+ ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
+ status);
+ return status;
+ }
+
+ return NO_ERROR;
+}
+
uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
{
bool createTxPatch = false;
@@ -4173,7 +4214,7 @@
ALOGVV("getOutputsForDevice() device %04x", device);
for (size_t i = 0; i < openOutputs.size(); i++) {
- ALOGVV("output %d isDuplicated=%d device=%04x",
+ ALOGVV("output %zu isDuplicated=%d device=%04x",
i, openOutputs.valueAt(i)->isDuplicated(),
openOutputs.valueAt(i)->supportedDevices());
if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
@@ -4614,7 +4655,7 @@
== AUDIO_DEVICE_NONE) {
continue;
}
- ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x)",
+ ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
mute ? "muting" : "unmuting", i, curDevice);
setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
if (isStrategyActive(desc, (routing_strategy)i)) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 5c2b673..3cfe508 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -93,6 +93,9 @@
const char *device_name);
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
+ virtual status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name);
virtual void setPhoneState(audio_mode_t state);
virtual void setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 451ce84..b4470c0 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -62,6 +62,26 @@
device_address);
}
+status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name)
+{
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ if (!settingsAllowed()) {
+ return PERMISSION_DENIED;
+ }
+ if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
+ return BAD_VALUE;
+ }
+
+ ALOGV("handleDeviceConfigChange()");
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->handleDeviceConfigChange(device, device_address,
+ device_name);
+}
+
status_t AudioPolicyService::setPhoneState(audio_mode_t state)
{
if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index def6405..8c9b23c 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -66,6 +66,9 @@
virtual audio_policy_dev_state_t getDeviceConnectionState(
audio_devices_t device,
const char *device_address);
+ virtual status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name);
virtual status_t setPhoneState(audio_mode_t state);
virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);