Add unique audio port IDs to AudioTrack and AudioRecord
This will allow to track activity at the track level instead of
at audio session level as only possible with current implementation.
AudioTracks and AudioRecords will receive a unique audio port ID the
first time they register to audio policy with
getOutputForAttr()/getInputForAttr() and keep this ID for their
lifetime.
This CL is the first partial change and just updates the
audio policy and audio flinger APIs used at track creation time.
Test: basic regression test of audio playback and capture use cases
Change-Id: I8d612e67738e120494f61e3f7c60bfd0b2c6a329
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index f7eb397..1c8746f 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -650,6 +650,8 @@
// a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
audio_port_handle_t mSelectedDeviceId;
sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+ audio_port_handle_t mPortId; // unique ID allocated by audio policy
+
};
}; // namespace android
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 0533ba6..0e9960f 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -217,12 +217,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate = 0,
- audio_format_t format = AUDIO_FORMAT_DEFAULT,
- audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
- const audio_offload_info_t *offloadInfo = NULL);
+ const audio_config_t *config,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId);
static status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
@@ -240,11 +238,10 @@
audio_session_t session,
pid_t pid,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId);
static status_t startInput(audio_io_handle_t input,
audio_session_t session);
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 7c5686a..cd33a44 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -1134,6 +1134,7 @@
pid_t mClientPid;
sp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+ audio_port_handle_t mPortId; // unique ID allocated by audio policy
};
}; // namespace android
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 638f552..56cecea 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -66,7 +66,8 @@
pid_t tid, // -1 means unused, otherwise must be valid non-0
audio_session_t *sessionId,
int clientUid,
- status_t *status) = 0;
+ status_t *status,
+ audio_port_handle_t portId) = 0;
virtual sp<IAudioRecord> openRecord(
// On successful return, AudioFlinger takes over the handle
@@ -86,7 +87,8 @@
size_t *notificationFrames,
sp<IMemory>& cblk,
sp<IMemory>& buffers, // return value 0 means it follows cblk
- status_t *status) = 0;
+ status_t *status,
+ audio_port_handle_t portId) = 0;
// FIXME Surprisingly, format/latency don't work for input handles
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 5637dd5..e8db4b1 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -63,12 +63,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate = 0,
- audio_format_t format = AUDIO_FORMAT_DEFAULT,
- audio_channel_mask_t channelMask = 0,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
- const audio_offload_info_t *offloadInfo = NULL) = 0;
+ const audio_config_t *config,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId) = 0;
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session) = 0;
@@ -83,11 +81,10 @@
audio_session_t session,
pid_t pid,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE) = 0;
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId) = 0;
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session) = 0;
virtual status_t stopInput(audio_io_handle_t input,
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 778540c..4c1fbd7 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -68,7 +68,7 @@
AudioRecord::AudioRecord(const String16 &opPackageName)
: mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE)
{
}
@@ -95,7 +95,8 @@
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
mProxy(NULL),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
@@ -529,14 +530,18 @@
// The sp<> references will be dropped when re-entering scope.
// The lack of indentation is deliberate, to reduce code churn and ease merges.
for (;;) {
-
+ audio_config_base_t config = {
+ .sample_rate = mSampleRate,
+ .channel_mask = mChannelMask,
+ .format = mFormat
+ };
status = AudioSystem::getInputForAttr(&mAttributes, &input,
mSessionId,
// FIXME compare to AudioTrack
mClientPid,
mClientUid,
- mSampleRate, mFormat, mChannelMask,
- mFlags, mSelectedDeviceId);
+ &config,
+ mFlags, mSelectedDeviceId, &mPortId);
if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE) {
ALOGE("Could not get audio input for session %d, record source %d, sample rate %u, "
@@ -622,7 +627,8 @@
¬ificationFrames,
iMem,
bufferMem,
- &status);
+ &status,
+ mPortId);
ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
"session ID changed from %d to %d", originalSessionId, mSessionId);
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index d45b12f..f7ba757 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -792,18 +792,16 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t selectedDeviceId,
- const audio_offload_info_t *offloadInfo)
+ audio_port_handle_t *portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
return aps->getOutputForAttr(attr, output, session, stream, uid,
- samplingRate, format, channelMask,
- flags, selectedDeviceId, offloadInfo);
+ config,
+ flags, selectedDeviceId, portId);
}
status_t AudioSystem::startOutput(audio_io_handle_t output,
@@ -838,17 +836,16 @@
audio_session_t session,
pid_t pid,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId)
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
return aps->getInputForAttr(
attr, input, session, pid, uid,
- samplingRate, format, channelMask, flags, selectedDeviceId);
+ config, flags, selectedDeviceId, portId);
}
status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index aef7dfb..f9ab208 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -183,7 +183,8 @@
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
mAttributes.usage = AUDIO_USAGE_UNKNOWN;
@@ -214,7 +215,8 @@
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
@@ -245,7 +247,8 @@
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -452,6 +455,7 @@
mOffloadInfo = &mOffloadInfoCopy;
} else {
mOffloadInfo = NULL;
+ memset(&mOffloadInfoCopy, 0, sizeof(audio_offload_info_t));
}
mVolume[AUDIO_INTERLEAVE_LEFT] = 1.0f;
@@ -1255,10 +1259,15 @@
// After fast request is denied, we will request again if IAudioTrack is re-created.
status_t status;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = mSampleRate;
+ config.channel_mask = mChannelMask;
+ config.format = mFormat;
+ config.offload_info = mOffloadInfoCopy;
status = AudioSystem::getOutputForAttr(attr, &output,
mSessionId, &streamType, mClientUid,
- mSampleRate, mFormat, mChannelMask,
- mFlags, mSelectedDeviceId, mOffloadInfo);
+ &config,
+ mFlags, mSelectedDeviceId, &mPortId);
if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {
ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u, format %#x,"
@@ -1416,7 +1425,8 @@
tid,
&mSessionId,
mClientUid,
- &status);
+ &status,
+ mPortId);
ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
"session ID changed from %d to %d", originalSessionId, mSessionId);
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 65fdedb..b532deb 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -108,7 +108,8 @@
pid_t tid,
audio_session_t *sessionId,
int clientUid,
- status_t *status)
+ status_t *status,
+ audio_port_handle_t portId)
{
Parcel data, reply;
sp<IAudioTrack> track;
@@ -137,6 +138,7 @@
}
data.writeInt32(lSessionId);
data.writeInt32(clientUid);
+ data.writeInt32(portId);
status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
if (lStatus != NO_ERROR) {
ALOGE("createTrack error: %s", strerror(-lStatus));
@@ -188,7 +190,8 @@
size_t *notificationFrames,
sp<IMemory>& cblk,
sp<IMemory>& buffers,
- status_t *status)
+ status_t *status,
+ audio_port_handle_t portId)
{
Parcel data, reply;
sp<IAudioRecord> record;
@@ -211,6 +214,7 @@
}
data.writeInt32(lSessionId);
data.writeInt64(notificationFrames != NULL ? *notificationFrames : 0);
+ data.writeInt32(portId);
cblk.clear();
buffers.clear();
status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
@@ -958,6 +962,7 @@
pid_t tid = (pid_t) data.readInt32();
audio_session_t sessionId = (audio_session_t) data.readInt32();
int clientUid = data.readInt32();
+ audio_port_handle_t portId = (audio_port_handle_t) data.readInt32();
status_t status = NO_ERROR;
sp<IAudioTrack> track;
if ((haveSharedBuffer && (buffer == 0)) ||
@@ -968,7 +973,7 @@
track = createTrack(
(audio_stream_type_t) streamType, sampleRate, format,
channelMask, &frameCount, &flags, buffer, output, pid, tid,
- &sessionId, clientUid, &status);
+ &sessionId, clientUid, &status, portId);
LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
}
reply->writeInt64(frameCount);
@@ -992,13 +997,14 @@
int clientUid = data.readInt32();
audio_session_t sessionId = (audio_session_t) data.readInt32();
size_t notificationFrames = data.readInt64();
+ audio_port_handle_t portId = (audio_port_handle_t) data.readInt32();
sp<IMemory> cblk;
sp<IMemory> buffers;
status_t status = NO_ERROR;
sp<IAudioRecord> record = openRecord(input,
sampleRate, format, channelMask, opPackageName, &frameCount, &flags,
pid, tid, clientUid, &sessionId, ¬ificationFrames, cblk, buffers,
- &status);
+ &status, portId);
LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
reply->writeInt64(frameCount);
reply->writeInt32(flags);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 2fb2da6..bc5502e 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -175,12 +175,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t selectedDeviceId,
- const audio_offload_info_t *offloadInfo)
+ audio_port_handle_t *portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -198,6 +196,10 @@
ALOGE("getOutputForAttr NULL output - shouldn't happen");
return BAD_VALUE;
}
+ if (portId == NULL) {
+ ALOGE("getOutputForAttr NULL portId - shouldn't happen");
+ return BAD_VALUE;
+ }
if (attr == NULL) {
data.writeInt32(0);
} else {
@@ -212,18 +214,10 @@
data.writeInt32(*stream);
}
data.writeInt32(uid);
- data.writeInt32(samplingRate);
- data.writeInt32(static_cast <uint32_t>(format));
- data.writeInt32(channelMask);
+ data.write(config, sizeof(audio_config_t));
data.writeInt32(static_cast <uint32_t>(flags));
data.writeInt32(selectedDeviceId);
- // hasOffloadInfo
- if (offloadInfo == NULL) {
- data.writeInt32(0);
- } else {
- data.writeInt32(1);
- data.write(offloadInfo, sizeof(audio_offload_info_t));
- }
+ data.writeInt32(*portId);
status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
if (status != NO_ERROR) {
return status;
@@ -233,9 +227,11 @@
return status;
}
*output = (audio_io_handle_t)reply.readInt32();
+ audio_stream_type_t lStream = (audio_stream_type_t)reply.readInt32();
if (stream != NULL) {
- *stream = (audio_stream_type_t)reply.readInt32();
+ *stream = lStream;
}
+ *portId = (audio_port_handle_t)reply.readInt32();
return status;
}
@@ -282,11 +278,10 @@
audio_session_t session,
pid_t pid,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId)
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -298,15 +293,18 @@
ALOGE("getInputForAttr NULL input - shouldn't happen");
return BAD_VALUE;
}
+ if (portId == NULL) {
+ ALOGE("getInputForAttr NULL portId - shouldn't happen");
+ return BAD_VALUE;
+ }
data.write(attr, sizeof(audio_attributes_t));
data.writeInt32(session);
data.writeInt32(pid);
data.writeInt32(uid);
- data.writeInt32(samplingRate);
- data.writeInt32(static_cast <uint32_t>(format));
- data.writeInt32(channelMask);
+ data.write(config, sizeof(audio_config_base_t));
data.writeInt32(flags);
data.writeInt32(selectedDeviceId);
+ data.writeInt32(*portId);
status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply);
if (status != NO_ERROR) {
return status;
@@ -316,6 +314,7 @@
return status;
}
*input = (audio_io_handle_t)reply.readInt32();
+ *portId = (audio_port_handle_t)reply.readInt32();
return NO_ERROR;
}
@@ -901,25 +900,22 @@
stream = (audio_stream_type_t)data.readInt32();
}
uid_t uid = (uid_t)data.readInt32();
- uint32_t samplingRate = data.readInt32();
- audio_format_t format = (audio_format_t) data.readInt32();
- audio_channel_mask_t channelMask = data.readInt32();
+ audio_config_t config;
+ memset(&config, 0, sizeof(audio_config_t));
+ data.read(&config, sizeof(audio_config_t));
audio_output_flags_t flags =
static_cast <audio_output_flags_t>(data.readInt32());
audio_port_handle_t selectedDeviceId = data.readInt32();
- bool hasOffloadInfo = data.readInt32() != 0;
- audio_offload_info_t offloadInfo;
- if (hasOffloadInfo) {
- data.read(&offloadInfo, sizeof(audio_offload_info_t));
- }
+ audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
audio_io_handle_t output = 0;
status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
&output, session, &stream, uid,
- samplingRate, format, channelMask,
- flags, selectedDeviceId, hasOffloadInfo ? &offloadInfo : NULL);
+ &config,
+ flags, selectedDeviceId, &portId);
reply->writeInt32(status);
reply->writeInt32(output);
reply->writeInt32(stream);
+ reply->writeInt32(portId);
return NO_ERROR;
} break;
@@ -963,18 +959,20 @@
audio_session_t session = (audio_session_t)data.readInt32();
pid_t pid = (pid_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32();
- uint32_t samplingRate = data.readInt32();
- audio_format_t format = (audio_format_t) data.readInt32();
- audio_channel_mask_t channelMask = data.readInt32();
+ audio_config_base_t config;
+ memset(&config, 0, sizeof(audio_config_base_t));
+ data.read(&config, sizeof(audio_config_base_t));
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
+ audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = getInputForAttr(&attr, &input, session, pid, uid,
- samplingRate, format, channelMask,
- flags, selectedDeviceId);
+ &config,
+ flags, selectedDeviceId, &portId);
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->writeInt32(input);
+ reply->writeInt32(portId);
}
return NO_ERROR;
} break;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 0e70ad9..8917c26 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -547,7 +547,8 @@
pid_t tid,
audio_session_t *sessionId,
int clientUid,
- status_t *status)
+ status_t *status,
+ audio_port_handle_t portId)
{
sp<PlaybackThread::Track> track;
sp<TrackHandle> trackHandle;
@@ -640,7 +641,8 @@
ALOGV("createTrack() lSessionId: %d", lSessionId);
track = thread->createTrack_l(client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus);
+ channelMask, frameCount, sharedBuffer, lSessionId, flags, tid,
+ clientUid, &lStatus, portId);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0));
// we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
@@ -1445,7 +1447,8 @@
size_t *notificationFrames,
sp<IMemory>& cblk,
sp<IMemory>& buffers,
- status_t *status)
+ status_t *status,
+ audio_port_handle_t portId)
{
sp<RecordThread::RecordTrack> recordTrack;
sp<RecordHandle> recordHandle;
@@ -1529,7 +1532,7 @@
recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
frameCount, lSessionId, notificationFrames,
- clientUid, flags, tid, &lStatus);
+ clientUid, flags, tid, &lStatus, portId);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
if (lStatus == NO_ERROR) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index c3bf1f9..b046ab5 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -115,7 +115,8 @@
pid_t tid,
audio_session_t *sessionId,
int clientUid,
- status_t *status /*non-NULL*/);
+ status_t *status /*non-NULL*/,
+ audio_port_handle_t portId);
virtual sp<IAudioRecord> openRecord(
audio_io_handle_t input,
@@ -132,7 +133,8 @@
size_t *notificationFrames,
sp<IMemory>& cblk,
sp<IMemory>& buffers,
- status_t *status /*non-NULL*/);
+ status_t *status /*non-NULL*/,
+ audio_port_handle_t portId);
virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const;
virtual audio_format_t format(audio_io_handle_t output) const;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 0bcb9a0..27e4627 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -34,7 +34,8 @@
audio_session_t sessionId,
uid_t uid,
audio_output_flags_t flags,
- track_type type);
+ track_type type,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
virtual ~Track();
virtual status_t initCheck() const;
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 883ff6b..848e531 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -32,7 +32,8 @@
audio_session_t sessionId,
uid_t uid,
audio_input_flags_t flags,
- track_type type);
+ track_type type,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
virtual ~RecordTrack();
virtual status_t initCheck() const;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9966eeb..85d2335 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1754,7 +1754,8 @@
audio_output_flags_t *flags,
pid_t tid,
uid_t uid,
- status_t *status)
+ status_t *status,
+ audio_port_handle_t portId)
{
size_t frameCount = *pFrameCount;
sp<Track> track;
@@ -1936,7 +1937,7 @@
track = new Track(this, client, streamType, sampleRate, format,
channelMask, frameCount, NULL, sharedBuffer,
- sessionId, uid, *flags, TrackBase::TYPE_DEFAULT);
+ sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
if (lStatus != NO_ERROR) {
@@ -6451,7 +6452,8 @@
uid_t uid,
audio_input_flags_t *flags,
pid_t tid,
- status_t *status)
+ status_t *status,
+ audio_port_handle_t portId)
{
size_t frameCount = *pFrameCount;
sp<RecordTrack> track;
@@ -6559,7 +6561,7 @@
track = new RecordTrack(this, client, sampleRate,
format, channelMask, frameCount, NULL, sessionId, uid,
- *flags, TrackBase::TYPE_DEFAULT);
+ *flags, TrackBase::TYPE_DEFAULT, portId);
lStatus = track->initCheck();
if (lStatus != NO_ERROR) {
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index d261ea5..4eafc38 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -591,7 +591,8 @@
audio_output_flags_t *flags,
pid_t tid,
uid_t uid,
- status_t *status /*non-NULL*/);
+ status_t *status /*non-NULL*/,
+ audio_port_handle_t portId);
AudioStreamOut* getOutput() const;
AudioStreamOut* clearOutput();
@@ -1363,7 +1364,8 @@
uid_t uid,
audio_input_flags_t *flags,
pid_t tid,
- status_t *status /*non-NULL*/);
+ status_t *status /*non-NULL*/,
+ audio_port_handle_t portId);
status_t start(RecordTrack* recordTrack,
AudioSystem::sync_event_t event,
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 4fcb596..9ca2d63 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -65,7 +65,8 @@
uid_t uid,
bool isOut,
alloc_type alloc = ALLOC_CBLK,
- track_type type = TYPE_DEFAULT);
+ track_type type = TYPE_DEFAULT,
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
virtual ~TrackBase();
virtual status_t initCheck() const;
@@ -163,6 +164,7 @@
bool mTerminated;
track_type mType; // must be one of TYPE_DEFAULT, TYPE_OUTPUT, TYPE_PATCH ...
audio_io_handle_t mThreadIoHandle; // I/O handle of the thread the track is attached to
+ audio_port_handle_t mPortId; // unique ID for this track used by audio policy
};
// PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e8e27e4..9746075 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -75,7 +75,8 @@
uid_t clientUid,
bool isOut,
alloc_type alloc,
- track_type type)
+ track_type type,
+ audio_port_handle_t portId)
: RefBase(),
mThread(thread),
mClient(client),
@@ -96,7 +97,8 @@
mId(android_atomic_inc(&nextTrackId)),
mTerminated(false),
mType(type),
- mThreadIoHandle(thread->id())
+ mThreadIoHandle(thread->id()),
+ mPortId(portId)
{
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!isTrustedCallingUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
@@ -343,12 +345,13 @@
audio_session_t sessionId,
uid_t uid,
audio_output_flags_t flags,
- track_type type)
+ track_type type,
+ audio_port_handle_t portId)
: TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
(sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
sessionId, uid, true /*isOut*/,
(type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
- type),
+ type, portId),
mFillingUpStatus(FS_INVALID),
// mRetryCount initialized later when needed
mSharedBuffer(sharedBuffer),
@@ -1477,13 +1480,14 @@
audio_session_t sessionId,
uid_t uid,
audio_input_flags_t flags,
- track_type type)
+ track_type type,
+ audio_port_handle_t portId)
: TrackBase(thread, client, sampleRate, format,
channelMask, frameCount, buffer, sessionId, uid, false /*isOut*/,
(type == TYPE_DEFAULT) ?
((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
- type),
+ type, portId),
mOverflow(false),
mFramesToDrop(0),
mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index c60b49a..ff9e44c 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -116,12 +116,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_t *config,
audio_output_flags_t flags,
int selectedDeviceId,
- const audio_offload_info_t *offloadInfo) = 0;
+ audio_port_handle_t *portId) = 0;
// indicates to the audio policy manager that the output starts being used by corresponding stream.
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
@@ -140,12 +138,11 @@
audio_io_handle_t *input,
audio_session_t session,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t selectedDeviceId,
- input_type_t *inputType) = 0;
+ input_type_t *inputType,
+ audio_port_handle_t *portId) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a714041..c2b282e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -718,12 +718,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t selectedDeviceId,
- const audio_offload_info_t *offloadInfo)
+ audio_port_handle_t *portId)
{
audio_attributes_t attributes;
if (attr != NULL) {
@@ -741,10 +739,16 @@
}
stream_type_to_audio_attributes(*stream, &attributes);
}
+
+ // TODO: check for existing client for this port ID
+ if (*portId == AUDIO_PORT_HANDLE_NONE) {
+ *portId = AudioPort::getNextUniqueId();
+ }
+
sp<SwAudioOutputDescriptor> desc;
if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
- if (!audio_has_proportional_frames(format)) {
+ if (!audio_has_proportional_frames(config->format)) {
return BAD_VALUE;
}
*stream = streamTypefromAttributesInt(&attributes);
@@ -782,11 +786,11 @@
}
ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
- device, samplingRate, format, channelMask, flags);
+ device, config->sample_rate, config->format, config->channel_mask, flags);
*output = getOutputForDevice(device, session, *stream,
- samplingRate, format, channelMask,
- flags, offloadInfo);
+ config->sample_rate, config->format, config->channel_mask,
+ flags, &config->offload_info);
if (*output == AUDIO_IO_HANDLE_NONE) {
mOutputRoutes.removeRoute(session);
return INVALID_OPERATION;
@@ -1411,16 +1415,15 @@
audio_io_handle_t *input,
audio_session_t session,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t selectedDeviceId,
- input_type_t *inputType)
+ input_type_t *inputType,
+ audio_port_handle_t *portId)
{
ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
"session %d, flags %#x",
- attr->source, samplingRate, format, channelMask, session, flags);
+ attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
*input = AUDIO_IO_HANDLE_NONE;
*inputType = API_INPUT_INVALID;
@@ -1437,6 +1440,11 @@
}
halInputSource = inputSource;
+ // TODO: check for existing client for this port ID
+ if (*portId == AUDIO_PORT_HANDLE_NONE) {
+ *portId = AudioPort::getNextUniqueId();
+ }
+
// Explicit routing?
sp<DeviceDescriptor> deviceDesc;
for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
@@ -1486,12 +1494,13 @@
}
*input = getInputForDevice(device, address, session, uid, inputSource,
- samplingRate, format, channelMask, flags,
+ config->sample_rate, config->format, config->channel_mask, flags,
policyMix);
if (*input == AUDIO_IO_HANDLE_NONE) {
mInputRoutes.removeRoute(session);
return INVALID_OPERATION;
}
+
ALOGV("getInputForAttr() returns input type = %d", *inputType);
return NO_ERROR;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 52fa082..f440c37 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -111,12 +111,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t selectedDeviceId,
- const audio_offload_info_t *offloadInfo);
+ audio_port_handle_t *portId);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
@@ -130,12 +128,11 @@
audio_io_handle_t *input,
audio_session_t session,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
audio_port_handle_t selectedDeviceId,
- input_type_t *inputType);
+ input_type_t *inputType,
+ audio_port_handle_t *portId);
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 0c23080..be86cfa 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -151,12 +151,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t selectedDeviceId,
- const audio_offload_info_t *offloadInfo)
+ audio_port_handle_t *portId)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@@ -170,8 +168,9 @@
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
uid = callingUid;
}
- return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
- format, channelMask, flags, selectedDeviceId, offloadInfo);
+ return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid,
+ config,
+ flags, selectedDeviceId, portId);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -262,11 +261,10 @@
audio_session_t session,
pid_t pid,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId)
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@@ -305,9 +303,9 @@
Mutex::Autolock _l(mLock);
// the audio_in_acoustics_t parameter is ignored by get_input()
status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
- samplingRate, format, channelMask,
+ config,
flags, selectedDeviceId,
- &inputType);
+ &inputType, portId);
audioPolicyEffects = mAudioPolicyEffects;
if (status == NO_ERROR) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 8eb4f2d..d800743 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -77,12 +77,10 @@
audio_session_t session,
audio_stream_type_t *stream,
uid_t uid,
- uint32_t samplingRate = 0,
- audio_format_t format = AUDIO_FORMAT_DEFAULT,
- audio_channel_mask_t channelMask = 0,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
- const audio_offload_info_t *offloadInfo = NULL);
+ const audio_config_t *config,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ audio_port_handle_t *portId);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
@@ -97,11 +95,10 @@
audio_session_t session,
pid_t pid,
uid_t uid,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
+ const audio_config_base_t *config,
audio_input_flags_t flags,
- audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+ audio_port_handle_t *portId = NULL);
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session);
virtual status_t stopInput(audio_io_handle_t input,