summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/managerdefault
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-04-21 15:07:36 -0700
committerEric Laurent <elaurent@google.com>2015-04-22 08:12:53 -0700
commit493404d8c396e15ed73455acd39aa0f1940996e2 (patch)
treea07080e7733732fd7273963cca1c93436b86b997 /services/audiopolicy/managerdefault
parentc9c3804a2caf3c0f96e7a8985f82db7ceef490df (diff)
downloadframeworks_av-493404d8c396e15ed73455acd39aa0f1940996e2.zip
frameworks_av-493404d8c396e15ed73455acd39aa0f1940996e2.tar.gz
frameworks_av-493404d8c396e15ed73455acd39aa0f1940996e2.tar.bz2
audio policy: fix AudioTrack output device selection
Have AudioTrack::setOutputDevice() set CBLK_INVALID flag instead of calling restoreTrack_l(). This allows restoreTrack_l() to be called in a safe context. Allow device change while the AudioTrack is active by forcing a new device selection in startOutput() if the output route for this session was changed. Remove some warnings. Change-Id: I2d921a63c9bfa0e122233645e2d6d39f95f5f17d
Diffstat (limited to 'services/audiopolicy/managerdefault')
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp30
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h16
2 files changed, 35 insertions, 11 deletions
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3ea6a11..01f2b61 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -969,6 +969,8 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
audio_devices_t newDevice;
if (outputDesc->mPolicyMix != NULL) {
newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+ } else if (mOutputRoutes.hasRouteChanged(session)) {
+ newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
} else {
newDevice = AUDIO_DEVICE_NONE;
}
@@ -1026,7 +1028,7 @@ status_t AudioPolicyManager::startSource(sp<AudioOutputDescriptor> outputDesc,
// necessary for a correct control of hardware output routing by startOutput() and stopOutput()
outputDesc->changeRefCount(stream, 1);
- if (outputDesc->mRefCount[stream] == 1) {
+ if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
// starting an output being rerouted?
if (device == AUDIO_DEVICE_NONE) {
device = getNewOutputDevice(outputDesc, false /*fromCache*/);
@@ -2462,14 +2464,14 @@ status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session
return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
}
-status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
- const audio_attributes_t *attributes,
- audio_io_handle_t *handle)
+status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source __unused,
+ const audio_attributes_t *attributes __unused,
+ audio_io_handle_t *handle __unused)
{
return INVALID_OPERATION;
}
-status_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle)
+status_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle __unused)
{
return INVALID_OPERATION;
}
@@ -4511,18 +4513,36 @@ bool AudioPolicyManager::SessionRouteMap::hasRoute(audio_session_t session)
return indexOfKey(session) >= 0 && valueFor(session)->mDeviceDescriptor != 0;
}
+bool AudioPolicyManager::SessionRouteMap::hasRouteChanged(audio_session_t session)
+{
+ if (indexOfKey(session) >= 0) {
+ if (valueFor(session)->mChanged) {
+ valueFor(session)->mChanged = false;
+ return true;
+ }
+ }
+ return false;
+}
+
void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
audio_stream_type_t streamType,
sp<DeviceDescriptor> deviceDescriptor)
{
sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
if (route != NULL) {
+ if ((route->mDeviceDescriptor == 0 && deviceDescriptor != 0) ||
+ (!route->mDeviceDescriptor->equals(deviceDescriptor))) {
+ route->mChanged = true;
+ }
route->mRefCount++;
route->mDeviceDescriptor = deviceDescriptor;
} else {
route = new AudioPolicyManager::SessionRoute(session, streamType, deviceDescriptor);
route->mRefCount++;
add(session, route);
+ if (deviceDescriptor != 0) {
+ route->mChanged = true;
+ }
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 146a7af..521f6c4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -244,7 +244,10 @@ protected:
mStreamType(streamType),
mDeviceDescriptor(deviceDescriptor),
mRefCount(0),
- mActivityCount(0) {}
+ mActivityCount(0),
+ mChanged(false) {}
+
+ void log(const char* prefix);
audio_session_t mSession;
audio_stream_type_t mStreamType;
@@ -252,10 +255,9 @@ protected:
sp<DeviceDescriptor> mDeviceDescriptor;
// "reference" counting
- int mRefCount; // +/- on references
- int mActivityCount; // +/- on start/stop
-
- void log(const char* prefix);
+ int mRefCount; // +/- on references
+ int mActivityCount; // +/- on start/stop
+ bool mChanged;
};
class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>>
@@ -268,7 +270,7 @@ protected:
int incRouteActivity(audio_session_t session);
int decRouteActivity(audio_session_t session);
-
+ bool hasRouteChanged(audio_session_t session); // also clears the changed flag
void log(const char* caption);
};
@@ -510,6 +512,8 @@ protected:
void updateCallRouting(audio_devices_t rxDevice, int delayMs = 0);
+ // if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force
+ // the re-evaluation of the output device.
status_t startSource(sp<AudioOutputDescriptor> outputDesc,
audio_stream_type_t stream,
audio_devices_t device,