Merge "Add a mechanism for handling audio device configuration change" am: 549e431947 am: a1b496ac35 am: fcc1132010
am: c6fe843463
Change-Id: I7812e3e4426e526b886c1a414ac8ddec7649291e
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 0e9960f..4c64242 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -200,6 +200,9 @@
const char *device_address, const char *device_name);
static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
+ static status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name);
static status_t setPhoneState(audio_mode_t state);
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index e8db4b1..d111fd2 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -48,6 +48,9 @@
const char *device_name) = 0;
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
+ virtual status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name) = 0;
virtual status_t setPhoneState(audio_mode_t state) = 0;
virtual status_t setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) = 0;
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index f7ba757..1908f0e 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -751,6 +751,25 @@
return aps->getDeviceConnectionState(device, device_address);
}
+status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ const char *address = "";
+ const char *name = "";
+
+ if (aps == 0) return PERMISSION_DENIED;
+
+ if (device_address != NULL) {
+ address = device_address;
+ }
+ if (device_name != NULL) {
+ name = device_name;
+ }
+ return aps->handleDeviceConfigChange(device, address, name);
+}
+
status_t AudioSystem::setPhoneState(audio_mode_t state)
{
if (uint32_t(state) >= AUDIO_MODE_CNT) return BAD_VALUE;
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index bc5502e..776e509 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -33,6 +33,7 @@
enum {
SET_DEVICE_CONNECTION_STATE = IBinder::FIRST_CALL_TRANSACTION,
GET_DEVICE_CONNECTION_STATE,
+ HANDLE_DEVICE_CONFIG_CHANGE,
SET_PHONE_STATE,
SET_RINGER_MODE, // reserved, no longer used
SET_FORCE_USE,
@@ -116,6 +117,19 @@
return static_cast <audio_policy_dev_state_t>(reply.readInt32());
}
+ virtual status_t handleDeviceConfigChange(audio_devices_t device,
+ const char *device_address,
+ const char *device_name)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(static_cast <uint32_t>(device));
+ data.writeCString(device_address);
+ data.writeCString(device_name);
+ remote()->transact(HANDLE_DEVICE_CONFIG_CHANGE, data, &reply);
+ return static_cast <status_t> (reply.readInt32());
+ }
+
virtual status_t setPhoneState(audio_mode_t state)
{
Parcel data, reply;
@@ -837,6 +851,18 @@
return NO_ERROR;
} break;
+ case HANDLE_DEVICE_CONFIG_CHANGE: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_devices_t device =
+ static_cast <audio_devices_t>(data.readInt32());
+ const char *device_address = data.readCString();
+ const char *device_name = data.readCString();
+ reply->writeInt32(static_cast<uint32_t> (handleDeviceConfigChange(device,
+ device_address,
+ device_name)));
+ return NO_ERROR;
+ } break;
+
case SET_PHONE_STATE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
reply->writeInt32(static_cast <uint32_t>(setPhoneState(
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index ff9e44c..60ed1d6 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -89,6 +89,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 2f25020..2f4cc1d 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;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index f440c37..3c5ed3a 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 be86cfa..52aa143 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 d800743..9a083f4 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -62,6 +62,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);