Merge "NuPlayer2: fork the native code for MediaPlayer2"
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 741d084..2432cac 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -69,7 +69,8 @@
: mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE)
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
}
@@ -96,9 +97,10 @@
mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
- mProxy(NULL)
+ mProxy(NULL),
+ mPortId(AUDIO_PORT_HANDLE_NONE)
{
- (void)set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
+ mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
uid, pid, pAttributes, selectedDeviceId);
}
@@ -149,11 +151,6 @@
const audio_attributes_t* pAttributes,
audio_port_handle_t selectedDeviceId)
{
- status_t status = NO_ERROR;
- uint32_t channelCount;
- pid_t callingPid;
- pid_t myPid;
-
ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
"notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
"uid %d, pid %d",
@@ -173,8 +170,7 @@
case TRANSFER_CALLBACK:
if (cbf == NULL) {
ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
- status = BAD_VALUE;
- goto exit;
+ return BAD_VALUE;
}
break;
case TRANSFER_OBTAIN:
@@ -182,16 +178,14 @@
break;
default:
ALOGE("Invalid transfer type %d", transferType);
- status = BAD_VALUE;
- goto exit;
+ return BAD_VALUE;
}
mTransfer = transferType;
// invariant that mAudioRecord != 0 is true only after set() returns successfully
if (mAudioRecord != 0) {
ALOGE("Track already in use");
- status = INVALID_OPERATION;
- goto exit;
+ return INVALID_OPERATION;
}
if (pAttributes == NULL) {
@@ -215,18 +209,16 @@
// AudioFlinger capture only supports linear PCM
if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
ALOGE("Format %#x is not linear pcm", format);
- status = BAD_VALUE;
- goto exit;
+ return BAD_VALUE;
}
mFormat = format;
if (!audio_is_input_channel(channelMask)) {
ALOGE("Invalid channel mask %#x", channelMask);
- status = BAD_VALUE;
- goto exit;
+ return BAD_VALUE;
}
mChannelMask = channelMask;
- channelCount = audio_channel_count_from_in_mask(channelMask);
+ uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
mChannelCount = channelCount;
if (audio_is_linear_pcm(format)) {
@@ -235,24 +227,28 @@
mFrameSize = sizeof(uint8_t);
}
- // mFrameCount is initialized in createRecord_l
+ // mFrameCount is initialized in openRecord_l
mReqFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
- // mNotificationFramesAct is initialized in createRecord_l
+ // mNotificationFramesAct is initialized in openRecord_l
- mSessionId = sessionId;
+ if (sessionId == AUDIO_SESSION_ALLOCATE) {
+ mSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ } else {
+ mSessionId = sessionId;
+ }
ALOGV("set(): mSessionId %d", mSessionId);
- callingPid = IPCThreadState::self()->getCallingPid();
- myPid = getpid();
- if (uid == AUDIO_UID_INVALID || (callingPid != myPid)) {
+ int callingpid = IPCThreadState::self()->getCallingPid();
+ int mypid = getpid();
+ if (uid == AUDIO_UID_INVALID || (callingpid != mypid)) {
mClientUid = IPCThreadState::self()->getCallingUid();
} else {
mClientUid = uid;
}
- if (pid == -1 || (callingPid != myPid)) {
- mClientPid = callingPid;
+ if (pid == -1 || (callingpid != mypid)) {
+ mClientPid = callingpid;
} else {
mClientPid = pid;
}
@@ -267,7 +263,7 @@
}
// create the IAudioRecord
- status = createRecord_l(0 /*epoch*/, mOpPackageName);
+ status_t status = openRecord_l(0 /*epoch*/, mOpPackageName);
if (status != NO_ERROR) {
if (mAudioRecordThread != 0) {
@@ -275,9 +271,10 @@
mAudioRecordThread->requestExitAndWait();
mAudioRecordThread.clear();
}
- goto exit;
+ return status;
}
+ mStatus = NO_ERROR;
mUserData = user;
// TODO: add audio hardware input latency here
mLatency = (1000LL * mFrameCount) / mSampleRate;
@@ -292,9 +289,7 @@
mFramesRead = 0;
mFramesReadServerOffset = 0;
-exit:
- mStatus = status;
- return status;
+ return NO_ERROR;
}
// -------------------------------------------------------------------------
@@ -545,29 +540,70 @@
}
// must be called with mLock held
-status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName)
+status_t AudioRecord::openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName)
{
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
- IAudioFlinger::CreateRecordInput input;
- IAudioFlinger::CreateRecordOutput output;
- audio_session_t originalSessionId;
- sp<media::IAudioRecord> record;
- void *iMemPointer;
- audio_track_cblk_t* cblk;
- status_t status;
-
if (audioFlinger == 0) {
ALOGE("Could not get audioflinger");
- status = NO_INIT;
- goto exit;
+ return NO_INIT;
}
+ audio_io_handle_t input;
+
// mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
// After fast request is denied, we will request again if IAudioRecord is re-created.
+ status_t status;
+
+ // Not a conventional loop, but a retry loop for at most two iterations total.
+ // Try first maybe with FAST flag then try again without FAST flag if that fails.
+ // Exits loop normally via a return at the bottom, or with error via a break.
+ // 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
+ };
+ mRoutedDeviceId = mSelectedDeviceId;
+ status = AudioSystem::getInputForAttr(&mAttributes, &input,
+ mSessionId,
+ // FIXME compare to AudioTrack
+ mClientPid,
+ mClientUid,
+ &config,
+ mFlags, &mRoutedDeviceId, &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, "
+ "format %#x, channel mask %#x, flags %#x",
+ mSessionId, mAttributes.source, mSampleRate, mFormat, mChannelMask, mFlags);
+ return BAD_VALUE;
+ }
+
// Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
// we must release it ourselves if anything goes wrong.
+#if 0
+ size_t afFrameCount;
+ status = AudioSystem::getFrameCount(input, &afFrameCount);
+ if (status != NO_ERROR) {
+ ALOGE("getFrameCount(input=%d) status %d", input, status);
+ break;
+ }
+#endif
+
+ uint32_t afSampleRate;
+ status = AudioSystem::getSamplingRate(input, &afSampleRate);
+ if (status != NO_ERROR) {
+ ALOGE("getSamplingRate(input=%d) status %d", input, status);
+ break;
+ }
+ if (mSampleRate == 0) {
+ mSampleRate = afSampleRate;
+ }
+
// Client can only express a preference for FAST. Server will perform additional tests.
if (mFlags & AUDIO_INPUT_FLAG_FAST) {
bool useCaseAllowed =
@@ -586,41 +622,66 @@
if (!useCaseAllowed) {
ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
convertTransferToText(mTransfer));
+ }
+
+ // sample rates must also match
+ bool sampleRateAllowed = mSampleRate == afSampleRate;
+ if (!sampleRateAllowed) {
+ ALOGW("AUDIO_INPUT_FLAG_FAST denied, rates do not match %u Hz, require %u Hz",
+ mSampleRate, afSampleRate);
+ }
+
+ bool fastAllowed = useCaseAllowed && sampleRateAllowed;
+ if (!fastAllowed) {
mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
AUDIO_INPUT_FLAG_RAW));
+ AudioSystem::releaseInput(input, mSessionId);
+ continue; // retry
}
}
- input.attr = mAttributes;
- input.config.sample_rate = mSampleRate;
- input.config.channel_mask = mChannelMask;
- input.config.format = mFormat;
- input.clientInfo.clientUid = mClientUid;
- input.clientInfo.clientPid = mClientPid;
- input.clientInfo.clientTid = -1;
- if (mFlags & AUDIO_INPUT_FLAG_FAST) {
- if (mAudioRecordThread != 0) {
- input.clientInfo.clientTid = mAudioRecordThread->getTid();
- }
- }
- input.opPackageName = opPackageName;
-
- input.flags = mFlags;
// The notification frame count is the period between callbacks, as suggested by the client
// but moderated by the server. For record, the calculations are done entirely on server side.
- input.frameCount = mReqFrameCount;
- input.notificationFrameCount = mNotificationFramesReq;
- input.selectedDeviceId = mSelectedDeviceId;
- input.sessionId = mSessionId;
- originalSessionId = mSessionId;
+ size_t notificationFrames = mNotificationFramesReq;
+ size_t frameCount = mReqFrameCount;
- record = audioFlinger->createRecord(input,
- output,
- &status);
+ audio_input_flags_t flags = mFlags;
+
+ pid_t tid = -1;
+ if (mFlags & AUDIO_INPUT_FLAG_FAST) {
+ if (mAudioRecordThread != 0) {
+ tid = mAudioRecordThread->getTid();
+ }
+ }
+
+ size_t temp = frameCount; // temp may be replaced by a revised value of frameCount,
+ // but we will still need the original value also
+ audio_session_t originalSessionId = mSessionId;
+
+ sp<IMemory> iMem; // for cblk
+ sp<IMemory> bufferMem;
+ sp<media::IAudioRecord> record = audioFlinger->openRecord(input,
+ mSampleRate,
+ mFormat,
+ mChannelMask,
+ opPackageName,
+ &temp,
+ &flags,
+ mClientPid,
+ tid,
+ mClientUid,
+ &mSessionId,
+ ¬ificationFrames,
+ iMem,
+ bufferMem,
+ &status,
+ mPortId);
+ ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
+ "session ID changed from %d to %d", originalSessionId, mSessionId);
if (status != NO_ERROR) {
ALOGE("AudioFlinger could not create record track, status: %d", status);
- goto exit;
+ break;
}
ALOG_ASSERT(record != 0);
@@ -628,41 +689,41 @@
// so we are no longer responsible for releasing it.
mAwaitBoost = false;
- if (output.flags & AUDIO_INPUT_FLAG_FAST) {
- ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
- mReqFrameCount, output.frameCount);
- mAwaitBoost = true;
+ if (mFlags & AUDIO_INPUT_FLAG_FAST) {
+ if (flags & AUDIO_INPUT_FLAG_FAST) {
+ ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu", frameCount, temp);
+ mAwaitBoost = true;
+ } else {
+ ALOGW("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu -> %zu", frameCount, temp);
+ mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
+ AUDIO_INPUT_FLAG_RAW));
+ continue; // retry
+ }
}
- mFlags = output.flags;
- mRoutedDeviceId = output.selectedDeviceId;
- mSessionId = output.sessionId;
- mSampleRate = output.sampleRate;
+ mFlags = flags;
- if (output.cblk == 0) {
+ if (iMem == 0) {
ALOGE("Could not get control block");
- status = NO_INIT;
- goto exit;
+ return NO_INIT;
}
- iMemPointer = output.cblk ->pointer();
+ void *iMemPointer = iMem->pointer();
if (iMemPointer == NULL) {
ALOGE("Could not get control block pointer");
- status = NO_INIT;
- goto exit;
+ return NO_INIT;
}
- cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
+ audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
// Starting address of buffers in shared memory.
// The buffers are either immediately after the control block,
// or in a separate area at discretion of server.
void *buffers;
- if (output.buffers == 0) {
+ if (bufferMem == 0) {
buffers = cblk + 1;
} else {
- buffers = output.buffers->pointer();
+ buffers = bufferMem->pointer();
if (buffers == NULL) {
ALOGE("Could not get buffer pointer");
- status = NO_INIT;
- goto exit;
+ return NO_INIT;
}
}
@@ -672,42 +733,43 @@
mDeathNotifier.clear();
}
mAudioRecord = record;
- mCblkMemory = output.cblk;
- mBufferMemory = output.buffers;
+ mCblkMemory = iMem;
+ mBufferMemory = bufferMem;
IPCThreadState::self()->flushCommands();
mCblk = cblk;
- // note that output.frameCount is the (possibly revised) value of mReqFrameCount
- if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
- ALOGW("Requested frameCount %zu but received frameCount %zu",
- mReqFrameCount, output.frameCount);
+ // note that temp is the (possibly revised) value of frameCount
+ if (temp < frameCount || (frameCount == 0 && temp == 0)) {
+ ALOGW("Requested frameCount %zu but received frameCount %zu", frameCount, temp);
}
+ frameCount = temp;
// Make sure that application is notified with sufficient margin before overrun.
// The computation is done on server side.
- if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
+ if (mNotificationFramesReq > 0 && notificationFrames != mNotificationFramesReq) {
ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu",
- mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
+ mNotificationFramesReq, notificationFrames, frameCount);
}
- mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
+ mNotificationFramesAct = (uint32_t) notificationFrames;
+
//mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
- if (mDeviceCallback != 0 && mInput != output.inputId) {
+ if (mDeviceCallback != 0 && mInput != input) {
if (mInput != AUDIO_IO_HANDLE_NONE) {
AudioSystem::removeAudioDeviceCallback(this, mInput);
}
- AudioSystem::addAudioDeviceCallback(this, output.inputId);
+ AudioSystem::addAudioDeviceCallback(this, input);
}
// We retain a copy of the I/O handle, but don't own the reference
- mInput = output.inputId;
+ mInput = input;
mRefreshRemaining = true;
- mFrameCount = output.frameCount;
+ mFrameCount = frameCount;
// If IAudioRecord is re-created, don't let the requested frameCount
// decrease. This can confuse clients that cache frameCount().
- if (mFrameCount > mReqFrameCount) {
- mReqFrameCount = mFrameCount;
+ if (frameCount > mReqFrameCount) {
+ mReqFrameCount = frameCount;
}
// update proxy
@@ -718,9 +780,17 @@
mDeathNotifier = new DeathNotifier(this);
IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
-exit:
- mStatus = status;
- // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
+ return NO_ERROR;
+
+ // End of retry loop.
+ // The lack of indentation is deliberate, to reduce code churn and ease merges.
+ }
+
+// Arrive here on error, via a break
+ AudioSystem::releaseInput(input, mSessionId);
+ if (status == NO_ERROR) {
+ status = NO_INIT;
+ }
return status;
}
@@ -1152,12 +1222,12 @@
mFlags = mOrigFlags;
- // if the new IAudioRecord is created, createRecord_l() will modify the
+ // if the new IAudioRecord is created, openRecord_l() will modify the
// following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
// It will also delete the strong references on previous IAudioRecord and IMemory
Modulo<uint32_t> position(mProxy->getPosition());
mNewPosition = position + mUpdatePeriod;
- status_t result = createRecord_l(position, mOpPackageName);
+ status_t result = openRecord_l(position, mOpPackageName);
if (result == NO_ERROR) {
if (mActive) {
// callback thread or sync event hasn't changed
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 56ddd4f..5cf2bdb 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -22,7 +22,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include "IAudioFlinger.h"
@@ -31,7 +30,7 @@
enum {
CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_RECORD,
+ OPEN_RECORD,
SAMPLE_RATE,
RESERVED, // obsolete, was CHANNEL_COUNT
FORMAT,
@@ -131,39 +130,102 @@
return track;
}
- virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
- CreateRecordOutput& output,
- status_t *status)
+ virtual sp<media::IAudioRecord> openRecord(
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& opPackageName,
+ size_t *pFrameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid,
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers,
+ status_t *status,
+ audio_port_handle_t portId)
{
Parcel data, reply;
sp<media::IAudioRecord> record;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-
- if (status == nullptr) {
- return record;
+ data.writeInt32((int32_t) input);
+ data.writeInt32(sampleRate);
+ data.writeInt32(format);
+ data.writeInt32(channelMask);
+ data.writeString16(opPackageName);
+ size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
+ data.writeInt64(frameCount);
+ audio_input_flags_t lFlags = flags != NULL ? *flags : AUDIO_INPUT_FLAG_NONE;
+ data.writeInt32(lFlags);
+ data.writeInt32((int32_t) pid);
+ data.writeInt32((int32_t) tid);
+ data.writeInt32((int32_t) clientUid);
+ audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
+ if (sessionId != NULL) {
+ lSessionId = *sessionId;
}
-
- input.writeToParcel(&data);
-
- status_t lStatus = remote()->transact(CREATE_RECORD, data, &reply);
+ 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);
if (lStatus != NO_ERROR) {
- ALOGE("createRecord transaction error %d", lStatus);
- *status = DEAD_OBJECT;
- return record;
+ ALOGE("openRecord error: %s", strerror(-lStatus));
+ } else {
+ frameCount = reply.readInt64();
+ if (pFrameCount != NULL) {
+ *pFrameCount = frameCount;
+ }
+ lFlags = (audio_input_flags_t)reply.readInt32();
+ if (flags != NULL) {
+ *flags = lFlags;
+ }
+ lSessionId = (audio_session_t) reply.readInt32();
+ if (sessionId != NULL) {
+ *sessionId = lSessionId;
+ }
+ size_t lNotificationFrames = (size_t) reply.readInt64();
+ if (notificationFrames != NULL) {
+ *notificationFrames = lNotificationFrames;
+ }
+ lStatus = reply.readInt32();
+ record = interface_cast<media::IAudioRecord>(reply.readStrongBinder());
+ cblk = interface_cast<IMemory>(reply.readStrongBinder());
+ if (cblk != 0 && cblk->pointer() == NULL) {
+ cblk.clear();
+ }
+ buffers = interface_cast<IMemory>(reply.readStrongBinder());
+ if (buffers != 0 && buffers->pointer() == NULL) {
+ buffers.clear();
+ }
+ if (lStatus == NO_ERROR) {
+ if (record == 0) {
+ ALOGE("openRecord should have returned an IAudioRecord");
+ lStatus = UNKNOWN_ERROR;
+ } else if (cblk == 0) {
+ ALOGE("openRecord should have returned a cblk");
+ lStatus = NO_MEMORY;
+ }
+ // buffers is permitted to be 0
+ } else {
+ if (record != 0 || cblk != 0 || buffers != 0) {
+ ALOGE("openRecord returned an IAudioRecord, cblk, "
+ "or buffers but with status %d", lStatus);
+ }
+ }
+ if (lStatus != NO_ERROR) {
+ record.clear();
+ cblk.clear();
+ buffers.clear();
+ }
}
- *status = reply.readInt32();
- if (*status != NO_ERROR) {
- ALOGE("createRecord returned error %d", *status);
- return record;
+ if (status != NULL) {
+ *status = lStatus;
}
-
- record = interface_cast<media::IAudioRecord>(reply.readStrongBinder());
- if (record == 0) {
- ALOGE("createRecord returned a NULL IAudioRecord with status OK");
- *status = DEAD_OBJECT;
- return record;
- }
- output.readFromParcel(&reply);
return record;
}
@@ -837,46 +899,21 @@
status_t BnAudioFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
- // make sure transactions reserved to AudioPolicyManager do not come from other processes
- switch (code) {
- case SET_STREAM_VOLUME:
- case SET_STREAM_MUTE:
- case SET_MODE:
- case OPEN_OUTPUT:
- case OPEN_DUPLICATE_OUTPUT:
- case CLOSE_OUTPUT:
- case SUSPEND_OUTPUT:
- case RESTORE_OUTPUT:
- case OPEN_INPUT:
- case CLOSE_INPUT:
- case INVALIDATE_STREAM:
- case SET_VOICE_VOLUME:
- case MOVE_EFFECTS:
- case LOAD_HW_MODULE:
- case LIST_AUDIO_PORTS:
- case GET_AUDIO_PORT:
- case CREATE_AUDIO_PATCH:
- case RELEASE_AUDIO_PATCH:
- case LIST_AUDIO_PATCHES:
- case SET_AUDIO_PORT_CONFIG:
- ALOGW("%s: transaction %d received from PID %d",
- __func__, code, IPCThreadState::self()->getCallingPid());
- return INVALID_OPERATION;
- default:
- break;
- }
-
// Whitelist of relevant events to trigger log merging.
// Log merging should activate during audio activity of any kind. This are considered the
// most relevant events.
// TODO should select more wisely the items from the list
switch (code) {
case CREATE_TRACK:
- case CREATE_RECORD:
+ case OPEN_RECORD:
case SET_MASTER_VOLUME:
case SET_MASTER_MUTE:
+ case SET_STREAM_VOLUME:
+ case SET_STREAM_MUTE:
case SET_MIC_MUTE:
case SET_PARAMETERS:
+ case OPEN_INPUT:
+ case SET_VOICE_VOLUME:
case CREATE_EFFECT:
case SYSTEM_READY: {
requestLogMerge();
@@ -885,7 +922,6 @@
default:
break;
}
-
switch (code) {
case CREATE_TRACK: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
@@ -912,29 +948,37 @@
output.writeToParcel(reply);
return NO_ERROR;
} break;
- case CREATE_RECORD: {
+ case OPEN_RECORD: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
-
- CreateRecordInput input;
- if (input.readFromParcel((Parcel*)&data) != NO_ERROR) {
- reply->writeInt32(DEAD_OBJECT);
- return NO_ERROR;
- }
-
- status_t status;
- CreateRecordOutput output;
-
- sp<media::IAudioRecord> record = createRecord(input,
- output,
- &status);
-
+ audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
+ uint32_t sampleRate = data.readInt32();
+ audio_format_t format = (audio_format_t) data.readInt32();
+ audio_channel_mask_t channelMask = data.readInt32();
+ const String16& opPackageName = data.readString16();
+ size_t frameCount = data.readInt64();
+ audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
+ pid_t pid = (pid_t) data.readInt32();
+ pid_t tid = (pid_t) data.readInt32();
+ 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<media::IAudioRecord> record = openRecord(input,
+ sampleRate, format, channelMask, opPackageName, &frameCount, &flags,
+ pid, tid, clientUid, &sessionId, ¬ificationFrames, cblk, buffers,
+ &status, portId);
LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
+ reply->writeInt64(frameCount);
+ reply->writeInt32(flags);
+ reply->writeInt32(sessionId);
+ reply->writeInt64(notificationFrames);
reply->writeInt32(status);
- if (status != NO_ERROR) {
- return NO_ERROR;
- }
reply->writeStrongBinder(IInterface::asBinder(record));
- output.writeToParcel(reply);
+ reply->writeStrongBinder(IInterface::asBinder(cblk));
+ reply->writeStrongBinder(IInterface::asBinder(buffers));
return NO_ERROR;
} break;
case SAMPLE_RATE: {
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 53bc1b7..970ae90 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -22,7 +22,6 @@
#include <math.h>
#include <sys/types.h>
-#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/AudioEffect.h>
@@ -832,33 +831,10 @@
// ----------------------------------------------------------------------
+
status_t BnAudioPolicyService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
- // make sure transactions reserved to AudioFlinger do not come from other processes
- switch (code) {
- case START_OUTPUT:
- case STOP_OUTPUT:
- case RELEASE_OUTPUT:
- case GET_INPUT_FOR_ATTR:
- case START_INPUT:
- case STOP_INPUT:
- case RELEASE_INPUT:
- case GET_STRATEGY_FOR_STREAM:
- case GET_OUTPUT_FOR_EFFECT:
- case REGISTER_EFFECT:
- case UNREGISTER_EFFECT:
- case SET_EFFECT_ENABLED:
- case GET_OUTPUT_FOR_ATTR:
- case ACQUIRE_SOUNDTRIGGER_SESSION:
- case RELEASE_SOUNDTRIGGER_SESSION:
- ALOGW("%s: transaction %d received from PID %d",
- __func__, code, IPCThreadState::self()->getCallingPid());
- return INVALID_OPERATION;
- default:
- break;
- }
-
switch (code) {
case SET_DEVICE_CONNECTION_STATE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
diff --git a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
index 7572671..50ce78f 100644
--- a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
@@ -16,7 +16,6 @@
package android.media;
-/* Native code must specify namespace media (media::IAudioRecord) when referring to this class */
interface IAudioRecord {
/* After it's created the track is not active. Call start() to
diff --git a/media/libaudioclient/include/media/AudioClient.h b/media/libaudioclient/include/media/AudioClient.h
index 247af9e..108e326 100644
--- a/media/libaudioclient/include/media/AudioClient.h
+++ b/media/libaudioclient/include/media/AudioClient.h
@@ -19,13 +19,12 @@
#define ANDROID_AUDIO_CLIENT_H
#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
#include <system/audio.h>
#include <utils/String16.h>
namespace android {
-class AudioClient : public Parcelable {
+class AudioClient {
public:
AudioClient() :
clientUid(-1), clientPid(-1), clientTid(-1), packageName("") {}
@@ -35,7 +34,7 @@
pid_t clientTid;
String16 packageName;
- status_t readFromParcel(const Parcel *parcel) override {
+ status_t readFromParcel(Parcel *parcel) {
clientUid = parcel->readInt32();
clientPid = parcel->readInt32();
clientTid = parcel->readInt32();
@@ -43,7 +42,7 @@
return NO_ERROR;
}
- status_t writeToParcel(Parcel *parcel) const override {
+ status_t writeToParcel(Parcel *parcel) const {
parcel->writeInt32(clientUid);
parcel->writeInt32(clientPid);
parcel->writeInt32(clientTid);
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 00c2a88..51596a2 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -570,7 +570,7 @@
// caller must hold lock on mLock for all _l methods
- status_t createRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName);
+ status_t openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName);
// FIXME enum is faster than strcmp() for parameter 'from'
status_t restoreRecord_l(const char *from);
@@ -682,6 +682,7 @@
// May not match the app selection depending on other
// activity and connected devices
wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+ audio_port_handle_t mPortId; // unique ID allocated by audio policy
};
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 24a6e22..66601da 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -231,7 +231,7 @@
audio_stream_type_t stream,
audio_session_t session);
- // Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
+ // Client must successfully hand off the handle reference to AudioFlinger via openRecord(),
// or release it with releaseInput().
static status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 57d9778..9061c26 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -25,7 +25,6 @@
#include <utils/Errors.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
-#include <binder/Parcelable.h>
#include <media/AudioClient.h>
#include <media/IAudioTrack.h>
#include <media/IAudioFlingerClient.h>
@@ -51,9 +50,9 @@
* when calling createTrack() including arguments that will be updated by AudioFlinger
* and returned in CreateTrackOutput object
*/
- class CreateTrackInput : public Parcelable {
+ class CreateTrackInput {
public:
- status_t readFromParcel(const Parcel *parcel) override {
+ status_t readFromParcel(Parcel *parcel) {
/* input arguments*/
memset(&attr, 0, sizeof(audio_attributes_t));
if (parcel->read(&attr, sizeof(audio_attributes_t)) != NO_ERROR) {
@@ -64,9 +63,7 @@
if (parcel->read(&config, sizeof(audio_config_t)) != NO_ERROR) {
return DEAD_OBJECT;
}
- if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
- return DEAD_OBJECT;
- }
+ (void)clientInfo.readFromParcel(parcel);
if (parcel->readInt32() != 0) {
sharedBuffer = interface_cast<IMemory>(parcel->readStrongBinder());
if (sharedBuffer == 0 || sharedBuffer->pointer() == NULL) {
@@ -85,7 +82,7 @@
return NO_ERROR;
}
- status_t writeToParcel(Parcel *parcel) const override {
+ status_t writeToParcel(Parcel *parcel) const {
/* input arguments*/
(void)parcel->write(&attr, sizeof(audio_attributes_t));
(void)parcel->write(&config, sizeof(audio_config_t));
@@ -128,9 +125,9 @@
* when calling createTrack() including arguments that were passed as I/O for update by
* CreateTrackInput.
*/
- class CreateTrackOutput : public Parcelable {
+ class CreateTrackOutput {
public:
- status_t readFromParcel(const Parcel *parcel) override {
+ status_t readFromParcel(Parcel *parcel) {
/* input/output arguments*/
(void)parcel->read(&flags, sizeof(audio_output_flags_t));
frameCount = parcel->readInt64();
@@ -147,7 +144,7 @@
return NO_ERROR;
}
- status_t writeToParcel(Parcel *parcel) const override {
+ status_t writeToParcel(Parcel *parcel) const {
/* input/output arguments*/
(void)parcel->write(&flags, sizeof(audio_output_flags_t));
(void)parcel->writeInt64(frameCount);
@@ -179,140 +176,6 @@
audio_io_handle_t outputId;
};
- /* CreateRecordInput contains all input arguments sent by AudioRecord to AudioFlinger
- * when calling createRecord() including arguments that will be updated by AudioFlinger
- * and returned in CreateRecordOutput object
- */
- class CreateRecordInput : public Parcelable {
- public:
- status_t readFromParcel(const Parcel *parcel) override {
- /* input arguments*/
- memset(&attr, 0, sizeof(audio_attributes_t));
- if (parcel->read(&attr, sizeof(audio_attributes_t)) != NO_ERROR) {
- return DEAD_OBJECT;
- }
- attr.tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE -1] = '\0';
- memset(&config, 0, sizeof(audio_config_base_t));
- if (parcel->read(&config, sizeof(audio_config_base_t)) != NO_ERROR) {
- return DEAD_OBJECT;
- }
- if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
- return DEAD_OBJECT;
- }
- opPackageName = parcel->readString16();
-
- /* input/output arguments*/
- (void)parcel->read(&flags, sizeof(audio_input_flags_t));
- frameCount = parcel->readInt64();
- notificationFrameCount = parcel->readInt64();
- (void)parcel->read(&selectedDeviceId, sizeof(audio_port_handle_t));
- (void)parcel->read(&sessionId, sizeof(audio_session_t));
- return NO_ERROR;
- }
-
- status_t writeToParcel(Parcel *parcel) const override {
- /* input arguments*/
- (void)parcel->write(&attr, sizeof(audio_attributes_t));
- (void)parcel->write(&config, sizeof(audio_config_base_t));
- (void)clientInfo.writeToParcel(parcel);
- (void)parcel->writeString16(opPackageName);
-
- /* input/output arguments*/
- (void)parcel->write(&flags, sizeof(audio_input_flags_t));
- (void)parcel->writeInt64(frameCount);
- (void)parcel->writeInt64(notificationFrameCount);
- (void)parcel->write(&selectedDeviceId, sizeof(audio_port_handle_t));
- (void)parcel->write(&sessionId, sizeof(audio_session_t));
- return NO_ERROR;
- }
-
- /* input */
- audio_attributes_t attr;
- audio_config_base_t config;
- AudioClient clientInfo;
- String16 opPackageName;
-
- /* input/output */
- audio_input_flags_t flags;
- size_t frameCount;
- size_t notificationFrameCount;
- audio_port_handle_t selectedDeviceId;
- audio_session_t sessionId;
- };
-
- /* CreateRecordOutput contains all output arguments returned by AudioFlinger to AudioRecord
- * when calling createRecord() including arguments that were passed as I/O for update by
- * CreateRecordInput.
- */
- class CreateRecordOutput : public Parcelable {
- public:
- status_t readFromParcel(const Parcel *parcel) override {
- /* input/output arguments*/
- (void)parcel->read(&flags, sizeof(audio_input_flags_t));
- frameCount = parcel->readInt64();
- notificationFrameCount = parcel->readInt64();
- (void)parcel->read(&selectedDeviceId, sizeof(audio_port_handle_t));
- (void)parcel->read(&sessionId, sizeof(audio_session_t));
-
- /* output arguments*/
- sampleRate = parcel->readUint32();
- (void)parcel->read(&inputId, sizeof(audio_io_handle_t));
- if (parcel->readInt32() != 0) {
- cblk = interface_cast<IMemory>(parcel->readStrongBinder());
- if (cblk == 0 || cblk->pointer() == NULL) {
- return BAD_VALUE;
- }
- }
- if (parcel->readInt32() != 0) {
- buffers = interface_cast<IMemory>(parcel->readStrongBinder());
- if (buffers == 0 || buffers->pointer() == NULL) {
- return BAD_VALUE;
- }
- }
- return NO_ERROR;
- }
-
- status_t writeToParcel(Parcel *parcel) const override {
- /* input/output arguments*/
- (void)parcel->write(&flags, sizeof(audio_input_flags_t));
- (void)parcel->writeInt64(frameCount);
- (void)parcel->writeInt64(notificationFrameCount);
- (void)parcel->write(&selectedDeviceId, sizeof(audio_port_handle_t));
- (void)parcel->write(&sessionId, sizeof(audio_session_t));
-
- /* output arguments*/
- (void)parcel->writeUint32(sampleRate);
- (void)parcel->write(&inputId, sizeof(audio_io_handle_t));
- if (cblk != 0) {
- (void)parcel->writeInt32(1);
- (void)parcel->writeStrongBinder(IInterface::asBinder(cblk));
- } else {
- (void)parcel->writeInt32(0);
- }
- if (buffers != 0) {
- (void)parcel->writeInt32(1);
- (void)parcel->writeStrongBinder(IInterface::asBinder(buffers));
- } else {
- (void)parcel->writeInt32(0);
- }
-
- return NO_ERROR;
- }
-
- /* input/output */
- audio_input_flags_t flags;
- size_t frameCount;
- size_t notificationFrameCount;
- audio_port_handle_t selectedDeviceId;
- audio_session_t sessionId;
-
- /* output */
- uint32_t sampleRate;
- audio_io_handle_t inputId;
- sp<IMemory> cblk;
- sp<IMemory> buffers;
- };
-
// invariant on exit for all APIs that return an sp<>:
// (return value != 0) == (*status == NO_ERROR)
@@ -323,9 +186,26 @@
CreateTrackOutput& output,
status_t *status) = 0;
- virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
- CreateRecordOutput& output,
- status_t *status) = 0;
+ virtual sp<media::IAudioRecord> openRecord(
+ // On successful return, AudioFlinger takes over the handle
+ // reference and will release it when the track is destroyed.
+ // However on failure, the client is responsible for release.
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& callingPackage,
+ size_t *pFrameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid, // -1 means unused, otherwise must be valid non-0
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers, // return value 0 means it follows cblk
+ status_t *status,
+ audio_port_handle_t portId) = 0;
// FIXME Surprisingly, format/latency don't work for input handles
diff --git a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
index fc9e53c..116b548 100644
--- a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
+++ b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
@@ -49,7 +49,7 @@
int index, int colorFormat, bool metaOnly) = 0;
virtual status_t getFrameAtIndex(
std::vector<VideoFrame*>* frames,
- int frameIndex, int numFrames, int colorFormat, bool metaOnly);
+ int frameIndex, int numFrames, int colorFormat, bool metaOnly) = 0;
virtual MediaAlbumArt* extractAlbumArt() = 0;
virtual const char* extractMetadata(int keyCode) = 0;
};
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 358c743..32fdbd3 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1170,6 +1170,12 @@
ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
source = NULL;
if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) {
+ OMX_ERRORTYPE error = validateInputBuffer(inputBufferHeader);
+ if (error != OMX_ErrorNone) {
+ ALOGE("b/69065651");
+ android_errorWriteLog(0x534e4554, "69065651");
+ return error;
+ }
source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
if (mInputDataIsMeta) {
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index 7b90a01..f6a7b0e 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -434,6 +434,14 @@
}
if (inHeader->nFilledLen > 0) {
+ OMX_ERRORTYPE error = validateInputBuffer(inHeader);
+ if (error != OMX_ErrorNone) {
+ ALOGE("b/69065651");
+ android_errorWriteLog(0x534e4554, "69065651");
+ mSignalledError = true;
+ notify(OMX_EventError, error, 0, 0);
+ return;
+ }
const uint8_t *inputData = NULL;
if (mInputDataIsMeta) {
inputData =
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index a5666da..f6257b1 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -653,6 +653,13 @@
return;
}
+ OMX_ERRORTYPE error = validateInputBuffer(inputBufferHeader);
+ if (error != OMX_ErrorNone) {
+ ALOGE("b/27569635");
+ android_errorWriteLog(0x534e4554, "27569635");
+ notify(OMX_EventError, error, 0, 0);
+ return;
+ }
const uint8_t *source =
inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
@@ -668,14 +675,6 @@
return;
}
} else {
- if (inputBufferHeader->nFilledLen < frameSize) {
- android_errorWriteLog(0x534e4554, "27569635");
- notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
- return;
- } else if (inputBufferHeader->nFilledLen > frameSize) {
- ALOGW("Input buffer contains too many pixels");
- }
-
if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
ConvertYUV420SemiPlanarToYUV420Planar(
source, mConversionBuffer, mWidth, mHeight);
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index fa15ab3..2fbbb44 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -664,4 +664,17 @@
return SimpleSoftOMXComponent::getExtensionIndex(name, index);
}
+OMX_ERRORTYPE SoftVideoEncoderOMXComponent::validateInputBuffer(
+ const OMX_BUFFERHEADERTYPE *inputBufferHeader) {
+ size_t frameSize = mInputDataIsMeta ?
+ max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata))
+ : mWidth * mHeight * 3 / 2;
+ if (inputBufferHeader->nFilledLen < frameSize) {
+ return OMX_ErrorUndefined;
+ } else if (inputBufferHeader->nFilledLen > frameSize) {
+ ALOGW("Input buffer contains more data than expected.");
+ }
+ return OMX_ErrorNone;
+}
+
} // namespace android
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
index db5496a..2d6f31b 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoEncoderOMXComponent.h
@@ -67,6 +67,8 @@
virtual OMX_ERRORTYPE getExtensionIndex(const char *name, OMX_INDEXTYPE *index);
+ OMX_ERRORTYPE validateInputBuffer(const OMX_BUFFERHEADERTYPE *inputBufferHeader);
+
enum {
kInputPortIndex = 0,
kOutputPortIndex = 1,
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index aeb32bb..9cb0357 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -674,11 +674,7 @@
audio_session_t sessionId = input.sessionId;
if (sessionId == AUDIO_SESSION_ALLOCATE) {
sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
- } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
- lStatus = BAD_VALUE;
- goto Exit;
}
-
output.sessionId = sessionId;
output.outputId = AUDIO_IO_HANDLE_NONE;
output.selectedDeviceId = input.selectedDeviceId;
@@ -1572,144 +1568,120 @@
// ----------------------------------------------------------------------------
-sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& input,
- CreateRecordOutput& output,
- status_t *status)
+sp<media::IAudioRecord> AudioFlinger::openRecord(
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& opPackageName,
+ size_t *frameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid,
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers,
+ status_t *status,
+ audio_port_handle_t portId)
{
sp<RecordThread::RecordTrack> recordTrack;
sp<RecordHandle> recordHandle;
sp<Client> client;
status_t lStatus;
- audio_session_t sessionId = input.sessionId;
- audio_port_handle_t portId;
+ audio_session_t lSessionId;
- output.cblk.clear();
- output.buffers.clear();
+ cblk.clear();
+ buffers.clear();
- bool updatePid = (input.clientInfo.clientPid == -1);
+ bool updatePid = (pid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- uid_t clientUid = input.clientInfo.clientUid;
if (!isTrustedCallingUid(callingUid)) {
- ALOGW_IF(clientUid != callingUid,
- "%s uid %d tried to pass itself off as %d",
- __FUNCTION__, callingUid, clientUid);
+ ALOGW_IF((uid_t)clientUid != callingUid,
+ "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
clientUid = callingUid;
updatePid = true;
}
- pid_t clientPid = input.clientInfo.clientPid;
+
if (updatePid) {
const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- ALOGW_IF(clientPid != -1 && clientPid != callingPid,
+ ALOGW_IF(pid != -1 && pid != callingPid,
"%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, clientPid);
- clientPid = callingPid;
+ __func__, callingUid, callingPid, pid);
+ pid = callingPid;
}
// check calling permissions
- if (!recordingAllowed(input.opPackageName, input.clientInfo.clientTid, clientUid)) {
- ALOGE("createRecord() permission denied: recording not allowed");
+ if (!recordingAllowed(opPackageName, tid, clientUid)) {
+ ALOGE("openRecord() permission denied: recording not allowed");
lStatus = PERMISSION_DENIED;
goto Exit;
}
+
+ // further sample rate checks are performed by createRecordTrack_l()
+ if (sampleRate == 0) {
+ ALOGE("openRecord() invalid sample rate %u", sampleRate);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
+
// we don't yet support anything other than linear PCM
- if (!audio_is_valid_format(input.config.format) || !audio_is_linear_pcm(input.config.format)) {
- ALOGE("createRecord() invalid format %#x", input.config.format);
+ if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
+ ALOGE("openRecord() invalid format %#x", format);
lStatus = BAD_VALUE;
goto Exit;
}
// further channel mask checks are performed by createRecordTrack_l()
- if (!audio_is_input_channel(input.config.channel_mask)) {
- ALOGE("createRecord() invalid channel mask %#x", input.config.channel_mask);
+ if (!audio_is_input_channel(channelMask)) {
+ ALOGE("openRecord() invalid channel mask %#x", channelMask);
lStatus = BAD_VALUE;
goto Exit;
}
- if (sessionId == AUDIO_SESSION_ALLOCATE) {
- sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
- } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
- output.sessionId = sessionId;
- output.inputId = AUDIO_IO_HANDLE_NONE;
- output.selectedDeviceId = input.selectedDeviceId;
- output.flags = input.flags;
-
- client = registerPid(clientPid);
-
- // Not a conventional loop, but a retry loop for at most two iterations total.
- // Try first maybe with FAST flag then try again without FAST flag if that fails.
- // Exits loop via break on no error of got exit on error
- // The sp<> references will be dropped when re-entering scope.
- // The lack of indentation is deliberate, to reduce code churn and ease merges.
- for (;;) {
- lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
- sessionId,
- // FIXME compare to AudioTrack
- clientPid,
- clientUid,
- &input.config,
- output.flags, &output.selectedDeviceId, &portId);
-
{
Mutex::Autolock _l(mLock);
- RecordThread *thread = checkRecordThread_l(output.inputId);
+ RecordThread *thread = checkRecordThread_l(input);
if (thread == NULL) {
- ALOGE("createRecord() checkRecordThread_l failed");
+ ALOGE("openRecord() checkRecordThread_l failed");
lStatus = BAD_VALUE;
goto Exit;
}
- ALOGV("createRecord() lSessionId: %d input %d", sessionId, output.inputId);
+ client = registerPid(pid);
- output.sampleRate = input.config.sample_rate;
- output.frameCount = input.frameCount;
- output.notificationFrameCount = input.notificationFrameCount;
+ if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
+ if (audio_unique_id_get_use(*sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
+ lSessionId = *sessionId;
+ } else {
+ // if no audio session id is provided, create one here
+ lSessionId = (audio_session_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ if (sessionId != NULL) {
+ *sessionId = lSessionId;
+ }
+ }
+ ALOGV("openRecord() lSessionId: %d input %d", lSessionId, input);
- recordTrack = thread->createRecordTrack_l(client, &output.sampleRate,
- input.config.format, input.config.channel_mask,
- &output.frameCount, sessionId,
- &output.notificationFrameCount,
- clientUid, &output.flags,
- input.clientInfo.clientTid,
- &lStatus, portId);
+ recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
+ frameCount, lSessionId, notificationFrames,
+ clientUid, flags, tid, &lStatus, portId);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
- // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from
- // audio policy manager without FAST constraint
- if (lStatus == BAD_TYPE) {
- AudioSystem::releaseInput(output.inputId, sessionId);
- recordTrack.clear();
- continue;
+ if (lStatus == NO_ERROR) {
+ // Check if one effect chain was awaiting for an AudioRecord to be created on this
+ // session and move it to this thread.
+ sp<EffectChain> chain = getOrphanEffectChain_l(lSessionId);
+ if (chain != 0) {
+ Mutex::Autolock _l(thread->mLock);
+ thread->addEffectChain_l(chain);
+ }
}
-
- if (lStatus != NO_ERROR) {
- recordTrack.clear();
- goto Exit;
- }
-
- // Check if one effect chain was awaiting for an AudioRecord to be created on this
- // session and move it to this thread.
- sp<EffectChain> chain = getOrphanEffectChain_l(sessionId);
- if (chain != 0) {
- Mutex::Autolock _l(thread->mLock);
- thread->addEffectChain_l(chain);
- }
- break;
- }
- // End of retry loop.
- // The lack of indentation is deliberate, to reduce code churn and ease merges.
}
- output.cblk = recordTrack->getCblk();
- output.buffers = recordTrack->getBuffers();
-
- // return handle to client
- recordHandle = new RecordHandle(recordTrack);
-
-Exit:
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the
// Client destructor is called by the TrackBase destructor with mClientLock held
@@ -1719,8 +1691,17 @@
Mutex::Autolock _cl(mClientLock);
client.clear();
}
+ recordTrack.clear();
+ goto Exit;
}
+ cblk = recordTrack->getCblk();
+ buffers = recordTrack->getBuffers();
+
+ // return handle to client
+ recordHandle = new RecordHandle(recordTrack);
+
+Exit:
*status = lStatus;
return recordHandle;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index bc73ffd..506420c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -118,9 +118,23 @@
CreateTrackOutput& output,
status_t *status);
- virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
- CreateRecordOutput& output,
- status_t *status);
+ virtual sp<media::IAudioRecord> openRecord(
+ audio_io_handle_t input,
+ uint32_t sampleRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ const String16& opPackageName,
+ size_t *pFrameCount,
+ audio_input_flags_t *flags,
+ pid_t pid,
+ pid_t tid,
+ int clientUid,
+ audio_session_t *sessionId,
+ size_t *notificationFrames,
+ sp<IMemory>& cblk,
+ sp<IMemory>& buffers,
+ 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/Effects.cpp b/services/audioflinger/Effects.cpp
index ef6e223..bfb0fe2 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -296,6 +296,43 @@
const bool auxType =
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY;
+ // safeInputOutputSampleCount is 0 if the channel count between input and output
+ // buffers do not match. This prevents automatic accumulation or copying between the
+ // input and output effect buffers without an intermediary effect process.
+ // TODO: consider implementing channel conversion.
+ const size_t safeInputOutputSampleCount =
+ inChannelCount != outChannelCount ? 0
+ : outChannelCount * std::min(
+ mConfig.inputCfg.buffer.frameCount,
+ mConfig.outputCfg.buffer.frameCount);
+ const auto accumulateInputToOutput = [this, safeInputOutputSampleCount]() {
+#ifdef FLOAT_EFFECT_CHAIN
+ accumulate_float(
+ mConfig.outputCfg.buffer.f32,
+ mConfig.inputCfg.buffer.f32,
+ safeInputOutputSampleCount);
+#else
+ accumulate_i16(
+ mConfig.outputCfg.buffer.s16,
+ mConfig.inputCfg.buffer.s16,
+ safeInputOutputSampleCount);
+#endif
+ };
+ const auto copyInputToOutput = [this, safeInputOutputSampleCount]() {
+#ifdef FLOAT_EFFECT_CHAIN
+ memcpy(
+ mConfig.outputCfg.buffer.f32,
+ mConfig.inputCfg.buffer.f32,
+ safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
+
+#else
+ memcpy(
+ mConfig.outputCfg.buffer.s16,
+ mConfig.inputCfg.buffer.s16,
+ safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
+#endif
+ };
+
if (isProcessEnabled()) {
int ret;
if (isProcessImplemented()) {
@@ -308,97 +345,69 @@
static_assert(sizeof(float) <= sizeof(int32_t),
"in-place conversion requires sizeof(float) <= sizeof(int32_t)");
- const int32_t * const p32 = mConfig.inputCfg.buffer.s32;
- float * const pFloat = mConfig.inputCfg.buffer.f32;
- memcpy_to_float_from_q4_27(pFloat, p32, mConfig.inputCfg.buffer.frameCount);
- } else {
- memcpy_to_i16_from_q4_27(mConfig.inputCfg.buffer.s16,
+ memcpy_to_float_from_q4_27(
+ mConfig.inputCfg.buffer.f32,
+ mConfig.inputCfg.buffer.s32,
+ mConfig.inputCfg.buffer.frameCount);
+ } else
+#endif
+ {
+ memcpy_to_i16_from_q4_27(
+ mConfig.inputCfg.buffer.s16,
mConfig.inputCfg.buffer.s32,
mConfig.inputCfg.buffer.frameCount);
}
-#else
- memcpy_to_i16_from_q4_27(mConfig.inputCfg.buffer.s16,
- mConfig.inputCfg.buffer.s32,
- mConfig.inputCfg.buffer.frameCount);
-#endif
}
#ifdef FLOAT_EFFECT_CHAIN
- if (mSupportsFloat) {
- ret = mEffectInterface->process();
- } else {
- { // convert input to int16_t as effect doesn't support float.
- if (!auxType) {
- if (mInConversionBuffer.get() == nullptr) {
- ALOGW("%s: mInConversionBuffer is null, bypassing", __func__);
- goto data_bypass;
- }
- const float * const pIn = mInBuffer->audioBuffer()->f32;
- int16_t * const pIn16 = mInConversionBuffer->audioBuffer()->s16;
- memcpy_to_i16_from_float(
- pIn16, pIn, inChannelCount * mConfig.inputCfg.buffer.frameCount);
+ if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float.
+ if (!auxType) {
+ if (mInConversionBuffer.get() == nullptr) {
+ ALOGW("%s: mInConversionBuffer is null, bypassing", __func__);
+ goto data_bypass;
}
- if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
- if (mOutConversionBuffer.get() == nullptr) {
- ALOGW("%s: mOutConversionBuffer is null, bypassing", __func__);
- goto data_bypass;
- }
- int16_t * const pOut16 = mOutConversionBuffer->audioBuffer()->s16;
- const float * const pOut = mOutBuffer->audioBuffer()->f32;
- memcpy_to_i16_from_float(
- pOut16,
- pOut,
- outChannelCount * mConfig.outputCfg.buffer.frameCount);
- }
+ memcpy_to_i16_from_float(
+ mInConversionBuffer->audioBuffer()->s16,
+ mInBuffer->audioBuffer()->f32,
+ inChannelCount * mConfig.inputCfg.buffer.frameCount);
}
-
- ret = mEffectInterface->process();
-
- { // convert output back to float.
- const int16_t * const pOut16 = mOutConversionBuffer->audioBuffer()->s16;
- float * const pOut = mOutBuffer->audioBuffer()->f32;
- memcpy_to_float_from_i16(
- pOut, pOut16, outChannelCount * mConfig.outputCfg.buffer.frameCount);
+ if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+ if (mOutConversionBuffer.get() == nullptr) {
+ ALOGW("%s: mOutConversionBuffer is null, bypassing", __func__);
+ goto data_bypass;
+ }
+ memcpy_to_i16_from_float(
+ mOutConversionBuffer->audioBuffer()->s16,
+ mOutBuffer->audioBuffer()->f32,
+ outChannelCount * mConfig.outputCfg.buffer.frameCount);
}
}
-#else
+#endif
+
ret = mEffectInterface->process();
+
+#ifdef FLOAT_EFFECT_CHAIN
+ if (!mSupportsFloat) { // convert output int16_t back to float.
+ memcpy_to_float_from_i16(
+ mOutBuffer->audioBuffer()->f32,
+ mOutConversionBuffer->audioBuffer()->s16,
+ outChannelCount * mConfig.outputCfg.buffer.frameCount);
+ }
#endif
} else {
#ifdef FLOAT_EFFECT_CHAIN
data_bypass:
#endif
if (!auxType /* aux effects do not require data bypass */
- && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw
- && inChannelCount == outChannelCount) {
- const size_t sampleCount = std::min(
- mConfig.inputCfg.buffer.frameCount,
- mConfig.outputCfg.buffer.frameCount) * outChannelCount;
-
-#ifdef FLOAT_EFFECT_CHAIN
- const float * const in = mConfig.inputCfg.buffer.f32;
- float * const out = mConfig.outputCfg.buffer.f32;
-
+ && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
- accumulate_float(out, in, sampleCount);
+ accumulateInputToOutput();
} else {
- memcpy(mConfig.outputCfg.buffer.f32, mConfig.inputCfg.buffer.f32,
- sampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
+ copyInputToOutput();
}
-
-#else
- const int16_t * const in = mConfig.inputCfg.buffer.s16;
- int16_t * const out = mConfig.outputCfg.buffer.s16;
-
- if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
- accumulate_i16(out, in, sampleCount);
- } else {
- memcpy(mConfig.outputCfg.buffer.s16, mConfig.inputCfg.buffer.s16,
- sampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
- }
-#endif
}
ret = -ENODATA;
}
+
// force transition to IDLE state when engine is ready
if (mState == STOPPED && ret == -ENODATA) {
mDisableWaitCnt = 1;
@@ -417,21 +426,8 @@
// If an insert effect is idle and input buffer is different from output buffer,
// accumulate input onto output
sp<EffectChain> chain = mChain.promote();
- if (chain != 0
- && chain->activeTrackCnt() != 0
- && inChannelCount == outChannelCount) {
- const size_t sampleCount = std::min(
- mConfig.inputCfg.buffer.frameCount,
- mConfig.outputCfg.buffer.frameCount) * outChannelCount;
-#ifdef FLOAT_EFFECT_CHAIN
- const float * const in = mConfig.inputCfg.buffer.f32;
- float * const out = mConfig.outputCfg.buffer.f32;
- accumulate_float(out, in, sampleCount);
-#else
- const int16_t * const in = mConfig.inputCfg.buffer.s16;
- int16_t * const out = mConfig.outputCfg.buffer.s16;
- accumulate_i16(out, in, sampleCount);
-#endif
+ if (chain.get() != nullptr && chain->activeTrackCnt() != 0) {
+ accumulateInputToOutput();
}
}
}
@@ -927,7 +923,6 @@
(void)EffectBufferHalInterface::allocate(size, &mInConversionBuffer);
}
if (mInConversionBuffer.get() != nullptr) {
- // FIXME: confirm buffer has enough size.
mInConversionBuffer->setFrameCount(inFrameCount);
mEffectInterface->setInBuffer(mInConversionBuffer);
} else if (size > 0) {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 7636df6..b2a1e18 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6708,12 +6708,12 @@
// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
const sp<AudioFlinger::Client>& client,
- uint32_t *pSampleRate,
+ uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t *pFrameCount,
audio_session_t sessionId,
- size_t *pNotificationFrameCount,
+ size_t *notificationFrames,
uid_t uid,
audio_input_flags_t *flags,
pid_t tid,
@@ -6721,30 +6721,16 @@
audio_port_handle_t portId)
{
size_t frameCount = *pFrameCount;
- size_t notificationFrameCount = *pNotificationFrameCount;
sp<RecordTrack> track;
status_t lStatus;
audio_input_flags_t inputFlags = mInput->flags;
- audio_input_flags_t requestedFlags = *flags;
- uint32_t sampleRate;
-
- lStatus = initCheck();
- if (lStatus != NO_ERROR) {
- ALOGE("createRecordTrack_l() audio driver not initialized");
- goto Exit;
- }
-
- if (*pSampleRate == 0) {
- *pSampleRate = mSampleRate;
- }
- sampleRate = *pSampleRate;
// special case for FAST flag considered OK if fast capture is present
if (hasFastCapture()) {
inputFlags = (audio_input_flags_t)(inputFlags | AUDIO_INPUT_FLAG_FAST);
}
- // Check if requested flags are compatible with input stream flags
+ // Check if requested flags are compatible with output stream flags
if ((*flags & inputFlags) != *flags) {
ALOGW("createRecordTrack_l(): mismatch between requested flags (%08x) and"
" input flags (%08x)",
@@ -6799,20 +6785,12 @@
}
}
- // If FAST or RAW flags were corrected, ask caller to request new input from audio policy
- if ((*flags & AUDIO_INPUT_FLAG_FAST) !=
- (requestedFlags & AUDIO_INPUT_FLAG_FAST)) {
- *flags = (audio_input_flags_t) (*flags & ~(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW));
- lStatus = BAD_TYPE;
- goto Exit;
- }
-
// compute track buffer size in frames, and suggest the notification frame count
if (*flags & AUDIO_INPUT_FLAG_FAST) {
// fast track: frame count is exactly the pipe depth
frameCount = mPipeFramesP2;
// ignore requested notificationFrames, and always notify exactly once every HAL buffer
- notificationFrameCount = mFrameCount;
+ *notificationFrames = mFrameCount;
} else {
// not fast track: max notification period is resampled equivalent of one HAL buffer time
// or 20 ms if there is a fast capture
@@ -6831,12 +6809,17 @@
const size_t minFrameCount = maxNotificationFrames *
max(kMinNotifications, minNotificationsByMs);
frameCount = max(frameCount, minFrameCount);
- if (notificationFrameCount == 0 || notificationFrameCount > maxNotificationFrames) {
- notificationFrameCount = maxNotificationFrames;
+ if (*notificationFrames == 0 || *notificationFrames > maxNotificationFrames) {
+ *notificationFrames = maxNotificationFrames;
}
}
*pFrameCount = frameCount;
- *pNotificationFrameCount = notificationFrameCount;
+
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
+ ALOGE("createRecordTrack_l() audio driver not initialized");
+ goto Exit;
+ }
{ // scope for mLock
Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 17f26c5..c7b60d6 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1327,12 +1327,12 @@
sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
const sp<AudioFlinger::Client>& client,
- uint32_t *pSampleRate,
+ uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t *pFrameCount,
audio_session_t sessionId,
- size_t *pNotificationFrameCount,
+ size_t *notificationFrames,
uid_t uid,
audio_input_flags_t *flags,
pid_t tid,
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index a3ea756..d4ce0b4 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -192,7 +192,7 @@
// where for AudioTrack (but not AudioRecord),
// 8-bit PCM samples are stored as 16-bit
const size_t mFrameCount;// size of track buffer given at createTrack() or
- // createRecord(), and then adjusted as needed
+ // openRecord(), and then adjusted as needed
const audio_session_t mSessionId;
uid_t mUid;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 1a32433..f2cb25f 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -355,6 +355,6 @@
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface);
-}; // namespace android
+} // namespace android
#endif // ANDROID_AUDIOPOLICY_INTERFACE_H
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
index 8f00d22..f86e75a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h
@@ -41,4 +41,4 @@
status_t dump(int fd, int spaces) const;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioGain.h b/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
index cea5c0b..4ac508f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioGain.h
@@ -66,4 +66,4 @@
bool mUseInChannelMask;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index d9cd121..65270b6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -121,4 +121,4 @@
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 0be8fc1..f4cbdd9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -214,4 +214,4 @@
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
index 385f257..c1c3f3c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
@@ -16,6 +16,7 @@
#pragma once
+#include "HandleGenerator.h"
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -24,7 +25,7 @@
namespace android {
-class AudioPatch : public RefBase
+class AudioPatch : public RefBase, private HandleGenerator<audio_patch_handle_t>
{
public:
AudioPatch(const struct audio_patch *patch, uid_t uid);
@@ -35,9 +36,6 @@
struct audio_patch mPatch;
uid_t mUid;
audio_patch_handle_t mAfPatchHandle;
-
-private:
- static volatile int32_t mNextUniqueId;
};
class AudioPatchCollection : public DefaultKeyedVector<audio_patch_handle_t, sp<AudioPatch> >
@@ -52,4 +50,4 @@
status_t dump(int fd) const;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index f2756b5..92d98a8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -112,7 +112,7 @@
mAvailableOutputDevices.add(mDefaultOutputDevices);
mAvailableInputDevices.add(defaultInputDevice);
- module = new HwModule("primary");
+ module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
sp<OutputProfile> outProfile;
outProfile = new OutputProfile(String8("primary"));
@@ -121,7 +121,7 @@
new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100));
outProfile->addSupportedDevice(mDefaultOutputDevices);
outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY);
- module->mOutputProfiles.add(outProfile);
+ module->addOutputProfile(outProfile);
sp<InputProfile> inProfile;
inProfile = new InputProfile(String8("primary"));
@@ -129,7 +129,7 @@
inProfile->addAudioProfile(
new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000));
inProfile->addSupportedDevice(defaultInputDevice);
- module->mInputProfiles.add(inProfile);
+ module->addInputProfile(inProfile);
mHwModules.add(module);
}
@@ -143,4 +143,4 @@
bool &mIsSpeakerDrcEnabled;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 0bacef7..8fc6fe9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -83,4 +83,4 @@
status_t dump(int fd) const;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 4f79ed2..d520937 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -18,6 +18,7 @@
#include "AudioCollections.h"
#include "AudioProfile.h"
+#include "HandleGenerator.h"
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/RefBase.h>
@@ -32,7 +33,7 @@
class AudioRoute;
typedef Vector<sp<AudioGain> > AudioGainCollection;
-class AudioPort : public virtual RefBase
+class AudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t>
{
public:
AudioPort(const String8& name, audio_port_type_t type, audio_port_role_t role) :
@@ -152,7 +153,6 @@
uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...).
AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
AudioRouteVector mRoutes; // Routes involving this port
- static volatile int32_t mNextUniqueId;
};
class AudioPortConfig : public virtual RefBase
@@ -176,4 +176,4 @@
struct audio_gain_config mGain;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
index 404e27d..8741c66 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
@@ -349,4 +349,4 @@
bool operator == (const AudioProfile &left, const AudioProfile &right);
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
index df54f48..6b24fde 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -55,4 +55,4 @@
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index cedf22d..0d19373 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -102,4 +102,4 @@
status_t dump(int fd, int spaces) const;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h
index 7e1e24d..0d90f42 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h
@@ -56,4 +56,4 @@
status_t dump(int fd) const;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
index ee95ceb..a007854 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h
@@ -56,4 +56,4 @@
static status_t loadHwModule(cnode *root, sp<HwModule> &module, AudioPolicyConfig &config);
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 1a644d7..92a4c3e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -91,4 +91,4 @@
audio_devices_t mDeviceTypes;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index 9ea0aea..04831c6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -69,4 +69,4 @@
static const uint32_t MAX_EFFECTS_MEMORY = 512;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/Gains.h b/services/audiopolicy/common/managerdefinitions/include/Gains.h
index 34afc8c..8332af9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/Gains.h
+++ b/services/audiopolicy/common/managerdefinitions/include/Gains.h
@@ -56,4 +56,4 @@
static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/HandleGenerator.h b/services/audiopolicy/common/managerdefinitions/include/HandleGenerator.h
new file mode 100644
index 0000000..737a2e0
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/HandleGenerator.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <limits>
+
+namespace android {
+
+template<typename T>
+class HandleGenerator {
+ protected:
+ static T getNextHandle();
+};
+
+template<typename T>
+T HandleGenerator<T>::getNextHandle() {
+ static std::atomic<uint32_t> mNextUniqueId(1);
+ uint32_t id = mNextUniqueId++;
+ while (id > std::numeric_limits<T>::max()) {
+ id -= std::numeric_limits<T>::max();
+ }
+ return static_cast<T>(id);
+}
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 29b6b9c..cb9f49e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -44,12 +44,10 @@
const char *getName() const { return mName.string(); }
-
const DeviceVector &getDeclaredDevices() const { return mDeclaredDevices; }
void setDeclaredDevices(const DeviceVector &devices);
const InputProfileCollection &getInputProfiles() const { return mInputProfiles; }
-
const OutputProfileCollection &getOutputProfiles() const { return mOutputProfiles; }
void setProfiles(const IOProfileCollection &profiles);
@@ -76,6 +74,7 @@
status_t removeInputProfile(const String8& name);
audio_module_handle_t getHandle() const { return mHandle; }
+ void setHandle(audio_module_handle_t handle);
sp<AudioPort> findPortByTagName(const String8 &tagName) const
{
@@ -85,14 +84,13 @@
// TODO remove from here (split serialization)
void dump(int fd);
+private:
+ void refreshSupportedDevices();
+
const String8 mName; // base name of the audio HW module (primary, a2dp ...)
audio_module_handle_t mHandle;
OutputProfileCollection mOutputProfiles; // output profiles exposed by this module
InputProfileCollection mInputProfiles; // input profiles exposed by this module
-
-private:
- void refreshSupportedDevices();
-
uint32_t mHalVersion; // audio HAL API version
DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file.
AudioRouteVector mRoutes;
@@ -114,4 +112,4 @@
status_t dump(int fd) const;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 118f0d2..5545f0a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -34,11 +34,7 @@
{
public:
IOProfile(const String8 &name, audio_port_role_t role)
- : AudioPort(name, AUDIO_PORT_TYPE_MIX, role),
- maxOpenCount((role == AUDIO_PORT_ROLE_SOURCE) ? 1 : 0),
- curOpenCount(0),
- maxActiveCount(1),
- curActiveCount(0) {}
+ : AudioPort(name, AUDIO_PORT_TYPE_MIX, role) {}
// For a Profile aka MixPort, tag name and name are equivalent.
virtual const String8 getTagName() const { return getName(); }
@@ -107,34 +103,6 @@
const DeviceVector &getSupportedDevices() const { return mSupportedDevices; }
- bool canOpenNewIo() {
- if (maxOpenCount == 0 || curOpenCount < maxOpenCount) {
- return true;
- }
- return false;
- }
-
- bool canStartNewIo() {
- if (maxActiveCount == 0 || curActiveCount < maxActiveCount) {
- return true;
- }
- return false;
- }
-
- // Maximum number of input or output streams that can be simultaneously opened for this profile.
- // By convention 0 means no limit. To respect legacy behavior, initialized to 1 for output
- // profiles and 0 for input profiles
- uint32_t maxOpenCount;
- // Number of streams currently opened for this profile.
- uint32_t curOpenCount;
- // Maximum number of input or output streams that can be simultaneously active for this profile.
- // By convention 0 means no limit. To respect legacy behavior, initialized to 0 for output
- // profiles and 1 for input profiles
- uint32_t maxActiveCount;
- // Number of streams currently active for this profile. This is not the number of active clients
- // (AudioTrack or AudioRecord) but the number of active HAL streams.
- uint32_t curActiveCount;
-
private:
DeviceVector mSupportedDevices; // supported devices: this input/output can be routed from/to
};
@@ -151,4 +119,4 @@
explicit OutputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SOURCE) {}
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
index a3de686..7b35f66 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
@@ -51,4 +51,4 @@
virtual ~IVolumeCurvesCollection() {}
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/Serializer.h b/services/audiopolicy/common/managerdefinitions/include/Serializer.h
index 3b0e209..597871d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/Serializer.h
+++ b/services/audiopolicy/common/managerdefinitions/include/Serializer.h
@@ -92,8 +92,6 @@
static const char name[];
static const char role[];
static const char flags[];
- static const char maxOpenCount[];
- static const char maxActiveCount[];
};
typedef IOProfile Element;
@@ -236,4 +234,4 @@
// Children are: ModulesTraits, VolumeTraits
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h b/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h
index 75bfd9d..fc2c273 100644
--- a/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/SessionRoute.h
@@ -115,4 +115,4 @@
const session_route_map_type_t mMapType;
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/SoundTriggerSession.h b/services/audiopolicy/common/managerdefinitions/include/SoundTriggerSession.h
index 420e6d7..f895599 100644
--- a/services/audiopolicy/common/managerdefinitions/include/SoundTriggerSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/SoundTriggerSession.h
@@ -30,4 +30,4 @@
status_t acquireSession(audio_session_t session, audio_io_handle_t ioHandle);
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
index 8822927..50b1037 100644
--- a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
@@ -107,4 +107,4 @@
void setVolumeIndexMax(audio_stream_type_t stream,int volIndexMax);
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
index fc95eb9..63c19d1 100644
--- a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
+++ b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
@@ -58,4 +58,4 @@
template <>
const RuleTypeConverter::Table RuleTypeConverter::mTable[];
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
index e7fcefc..db25ed8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
@@ -230,4 +230,4 @@
}
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
index 635fe4d..ca67b87 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp
@@ -27,14 +27,12 @@
sp<AudioPort> AudioPortVector::findByTagName(const String8 &tagName) const
{
- sp<AudioPort> port = 0;
- for (size_t i = 0; i < size(); i++) {
- if (itemAt(i)->getTagName() == tagName) {
- port = itemAt(i);
- break;
+ for (const auto& port : *this) {
+ if (port->getTagName() == tagName) {
+ return port;
}
}
- return port;
+ return nullptr;
}
status_t AudioRouteVector::dump(int fd, int spaces) const
@@ -55,4 +53,4 @@
return NO_ERROR;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
index e454941..193d4a6 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioGain.cpp
@@ -126,4 +126,4 @@
write(fd, result.string(), result.size());
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 46168a4..624e688 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -236,7 +236,6 @@
mFormat = lConfig.format;
mId = AudioPort::getNextUniqueId();
mIoHandle = *input;
- mProfile->curOpenCount++;
}
return status;
@@ -247,13 +246,6 @@
{
if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
mClientInterface->closeInput(mIoHandle);
- LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
- __FUNCTION__, mProfile->curOpenCount);
- if (isActive()) {
- mProfile->curActiveCount--;
- }
- mProfile->curOpenCount--;
- mIoHandle = AUDIO_IO_HANDLE_NONE;
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index f6ee1c3..f96c5bc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -444,7 +444,6 @@
mFormat = lConfig.format;
mId = AudioPort::getNextUniqueId();
mIoHandle = *output;
- mProfile->curOpenCount++;
}
return status;
@@ -459,14 +458,6 @@
mClientInterface->setParameters(mIoHandle, param.toString());
mClientInterface->closeOutput(mIoHandle);
-
- LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
- __FUNCTION__, mProfile->curOpenCount);
- if (isActive()) {
- mProfile->curActiveCount--;
- }
- mProfile->curOpenCount--;
- mIoHandle = AUDIO_IO_HANDLE_NONE;
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index 32606ea..a9fe48d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -22,15 +22,12 @@
#include "TypeConverter.h"
#include <log/log.h>
-#include <cutils/atomic.h>
#include <utils/String8.h>
namespace android {
-int32_t volatile AudioPatch::mNextUniqueId = 1;
-
AudioPatch::AudioPatch(const struct audio_patch *patch, uid_t uid) :
- mHandle(static_cast<audio_patch_handle_t>(android_atomic_inc(&mNextUniqueId))),
+ mHandle(HandleGenerator<audio_patch_handle_t>::getNextHandle()),
mPatch(*patch),
mUid(uid),
mAfPatchHandle(AUDIO_PATCH_HANDLE_NONE)
@@ -176,4 +173,4 @@
return NO_ERROR;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index fcf9070..d6ea698 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -21,7 +21,6 @@
#include "HwModule.h"
#include "AudioGain.h"
#include <policy.h>
-#include <cutils/atomic.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
@@ -29,8 +28,6 @@
namespace android {
-int32_t volatile AudioPort::mNextUniqueId = 1;
-
// --- AudioPort class implementation
void AudioPort::attach(const sp<HwModule>& module)
{
@@ -40,31 +37,22 @@
// Note that is a different namespace than AudioFlinger unique IDs
audio_port_handle_t AudioPort::getNextUniqueId()
{
- return static_cast<audio_port_handle_t>(android_atomic_inc(&mNextUniqueId));
+ return getNextHandle();
}
audio_module_handle_t AudioPort::getModuleHandle() const
{
- if (mModule == 0) {
- return AUDIO_MODULE_HANDLE_NONE;
- }
- return mModule->mHandle;
+ return mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
}
uint32_t AudioPort::getModuleVersionMajor() const
{
- if (mModule == 0) {
- return 0;
- }
- return mModule->getHalVersionMajor();
+ return mModule != 0 ? mModule->getHalVersionMajor() : 0;
}
const char *AudioPort::getModuleName() const
{
- if (mModule == 0) {
- return "invalid module";
- }
- return mModule->getName();
+ return mModule != 0 ? mModule->getName() : "invalid module";
}
void AudioPort::toAudioPort(struct audio_port *port) const
@@ -74,11 +62,11 @@
SortedVector<audio_format_t> flatenedFormats;
SampleRateVector flatenedRates;
ChannelsVector flatenedChannels;
- for (size_t profileIndex = 0; profileIndex < mProfiles.size(); profileIndex++) {
- if (mProfiles[profileIndex]->isValid()) {
- audio_format_t formatToExport = mProfiles[profileIndex]->getFormat();
- const SampleRateVector &ratesToExport = mProfiles[profileIndex]->getSampleRates();
- const ChannelsVector &channelsToExport = mProfiles[profileIndex]->getChannels();
+ for (const auto& profile : mProfiles) {
+ if (profile->isValid()) {
+ audio_format_t formatToExport = profile->getFormat();
+ const SampleRateVector &ratesToExport = profile->getSampleRates();
+ const ChannelsVector &channelsToExport = profile->getChannels();
if (flatenedFormats.indexOf(formatToExport) < 0) {
flatenedFormats.add(formatToExport);
@@ -130,14 +118,12 @@
void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
{
- size_t indexToImport;
- for (indexToImport = 0; indexToImport < port->mProfiles.size(); indexToImport++) {
- const sp<AudioProfile> &profileToImport = port->mProfiles[indexToImport];
+ for (const auto& profileToImport : port->mProfiles) {
if (profileToImport->isValid()) {
// Import only valid port, i.e. valid format, non empty rates and channels masks
bool hasSameProfile = false;
- for (size_t profileIndex = 0; profileIndex < mProfiles.size(); profileIndex++) {
- if (*mProfiles[profileIndex] == *profileToImport) {
+ for (const auto& profile : mProfiles) {
+ if (*profile == *profileToImport) {
// never import a profile twice
hasSameProfile = true;
break;
@@ -479,4 +465,4 @@
}
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index 98f7a94..fd6fc1c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -233,8 +233,7 @@
return NO_ERROR;
}
- for (size_t i = 0; i < size(); i++) {
- const sp<AudioProfile> profile = itemAt(i);
+ for (const auto& profile : *this) {
if (profile->checkExact(samplingRate, channelMask, format) == NO_ERROR) {
return NO_ERROR;
}
@@ -288,4 +287,4 @@
return AudioPort::compareFormats((*profile1)->getFormat(), (*profile2)->getFormat());
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index 5b57d3d..7cda46b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -290,4 +290,4 @@
return NO_ERROR;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
index e5888e2..1e105f5 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
@@ -416,4 +416,4 @@
return NO_ERROR;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index a2c1165..3b1e751 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -60,7 +60,7 @@
void DeviceVector::refreshTypes()
{
mDeviceTypes = AUDIO_DEVICE_NONE;
- for(size_t i = 0; i < size(); i++) {
+ for (size_t i = 0; i < size(); i++) {
mDeviceTypes |= itemAt(i)->type();
}
ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
@@ -68,7 +68,7 @@
ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
{
- for(size_t i = 0; i < size(); i++) {
+ for (size_t i = 0; i < size(); i++) {
if (item->equals(itemAt(i))) {
return i;
}
@@ -78,12 +78,15 @@
void DeviceVector::add(const DeviceVector &devices)
{
- for (size_t i = 0; i < devices.size(); i++) {
- sp<DeviceDescriptor> device = devices.itemAt(i);
+ bool added = false;
+ for (const auto& device : devices) {
if (indexOf(device) < 0 && SortedVector::add(device) >= 0) {
- refreshTypes();
+ added = true;
}
}
+ if (added) {
+ refreshTypes();
+ }
}
ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
@@ -148,14 +151,12 @@
sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
{
- sp<DeviceDescriptor> device;
- for (size_t i = 0; i < size(); i++) {
- if (itemAt(i)->getId() == id) {
- device = itemAt(i);
- break;
+ for (const auto& device : *this) {
+ if (device->getId() == id) {
+ return device;
}
}
- return device;
+ return nullptr;
}
DeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const
@@ -180,11 +181,9 @@
audio_devices_t type, const String8& address) const
{
DeviceVector devices;
- for (size_t i = 0; i < size(); i++) {
- if (itemAt(i)->type() == type) {
- if (itemAt(i)->mAddress == address) {
- devices.add(itemAt(i));
- }
+ for (const auto& device : *this) {
+ if (device->type() == type && device->mAddress == address) {
+ devices.add(device);
}
}
return devices;
@@ -192,14 +191,12 @@
sp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const String8 &tagName) const
{
- sp<DeviceDescriptor> device;
- for (size_t i = 0; i < size(); i++) {
- if (itemAt(i)->getTagName() == tagName) {
- device = itemAt(i);
- break;
+ for (const auto& device : *this) {
+ if (device->getTagName() == tagName) {
+ return device;
}
}
- return device;
+ return nullptr;
}
status_t DeviceVector::dump(int fd, const String8 &tag, int spaces, bool verbose) const
@@ -248,7 +245,8 @@
// without the test?
// This has been demonstrated to NOT be true (at start up)
// ALOG_ASSERT(mModule != NULL);
- dstConfig->ext.device.hw_module = mModule != 0 ? mModule->mHandle : AUDIO_MODULE_HANDLE_NONE;
+ dstConfig->ext.device.hw_module =
+ mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
}
@@ -259,7 +257,7 @@
port->id = mId;
toAudioPortConfig(&port->active_config);
port->ext.device.type = mDeviceType;
- port->ext.device.hw_module = mModule->mHandle;
+ port->ext.device.hw_module = mModule->getHandle();
strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
}
@@ -312,4 +310,4 @@
AudioPort::log(" ");
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/Gains.cpp b/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
index e3fc9a8..b2dafdd 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
@@ -235,4 +235,4 @@
return decibels;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index cc56fb8..aef7dbe 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -154,10 +154,9 @@
DeviceVector HwModule::getRouteSourceDevices(const sp<AudioRoute> &route) const
{
DeviceVector sourceDevices;
- Vector <sp<AudioPort> > sources = route->getSources();
- for (size_t i = 0; i < sources.size(); i++) {
- if (sources[i]->getType() == AUDIO_PORT_TYPE_DEVICE) {
- sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(sources[i]->getTagName()));
+ for (const auto& source : route->getSources()) {
+ if (source->getType() == AUDIO_PORT_TYPE_DEVICE) {
+ sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(source->getTagName()));
}
}
return sourceDevices;
@@ -173,17 +172,15 @@
void HwModule::refreshSupportedDevices()
{
// Now updating the streams (aka IOProfile until now) supported devices
- for (size_t i = 0; i < mInputProfiles.size(); i++) {
- sp<IOProfile> stream = mInputProfiles[i];
+ for (const auto& stream : mInputProfiles) {
DeviceVector sourceDevices;
- const AudioRouteVector &routes = stream->getRoutes();
- for (size_t j = 0; j < routes.size(); j++) {
- sp<AudioPort> sink = routes[j]->getSink();
+ for (const auto& route : stream->getRoutes()) {
+ sp<AudioPort> sink = route->getSink();
if (sink == 0 || stream != sink) {
ALOGE("%s: Invalid route attached to input stream", __FUNCTION__);
continue;
}
- DeviceVector sourceDevicesForRoute = getRouteSourceDevices(routes[j]);
+ DeviceVector sourceDevicesForRoute = getRouteSourceDevices(route);
if (sourceDevicesForRoute.isEmpty()) {
ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string());
continue;
@@ -196,17 +193,15 @@
}
stream->setSupportedDevices(sourceDevices);
}
- for (size_t i = 0; i < mOutputProfiles.size(); i++) {
- sp<IOProfile> stream = mOutputProfiles[i];
+ for (const auto& stream : mOutputProfiles) {
DeviceVector sinkDevices;
- const AudioRouteVector &routes = stream->getRoutes();
- for (size_t j = 0; j < routes.size(); j++) {
- sp<AudioPort> source = routes[j]->getSources().findByTagName(stream->getTagName());
+ for (const auto& route : stream->getRoutes()) {
+ sp<AudioPort> source = route->getSources().findByTagName(stream->getTagName());
if (source == 0 || stream != source) {
ALOGE("%s: Invalid route attached to output stream", __FUNCTION__);
continue;
}
- sp<DeviceDescriptor> sinkDevice = getRouteSinkDevice(routes[j]);
+ sp<DeviceDescriptor> sinkDevice = getRouteSinkDevice(route);
if (sinkDevice == 0) {
ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string());
continue;
@@ -217,6 +212,12 @@
}
}
+void HwModule::setHandle(audio_module_handle_t handle) {
+ ALOGW_IF(mHandle != AUDIO_MODULE_HANDLE_NONE,
+ "HwModule handle is changing from %d to %d", mHandle, handle);
+ mHandle = handle;
+}
+
void HwModule::dump(int fd)
{
const size_t SIZE = 256;
@@ -252,60 +253,40 @@
sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
{
- sp <HwModule> module;
-
- for (size_t i = 0; i < size(); i++)
- {
- if (strcmp(itemAt(i)->getName(), name) == 0) {
- return itemAt(i);
+ for (const auto& module : *this) {
+ if (strcmp(module->getName(), name) == 0) {
+ return module;
}
}
- return module;
+ return nullptr;
}
-
sp <HwModule> HwModuleCollection::getModuleForDevice(audio_devices_t device) const
{
- sp <HwModule> module;
-
- for (size_t i = 0; i < size(); i++) {
- if (itemAt(i)->getHandle() == 0) {
- continue;
- }
- if (audio_is_output_device(device)) {
- for (size_t j = 0; j < itemAt(i)->mOutputProfiles.size(); j++)
- {
- if (itemAt(i)->mOutputProfiles[j]->supportDevice(device)) {
- return itemAt(i);
- }
- }
- } else {
- for (size_t j = 0; j < itemAt(i)->mInputProfiles.size(); j++) {
- if (itemAt(i)->mInputProfiles[j]->supportDevice(device)) {
- return itemAt(i);
- }
+ for (const auto& module : *this) {
+ const auto& profiles = audio_is_output_device(device) ?
+ module->getOutputProfiles() : module->getInputProfiles();
+ for (const auto& profile : profiles) {
+ if (profile->supportDevice(device)) {
+ return module;
}
}
}
- return module;
+ return nullptr;
}
-sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
- const char *device_address,
- const char *device_name,
- bool matchAdress) const
+sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
+ const char *device_address,
+ const char *device_name,
+ bool matchAdress) const
{
- String8 address = (device_address == NULL) ? String8("") : String8(device_address);
+ String8 address = (device_address == nullptr) ? String8("") : String8(device_address);
// handle legacy remote submix case where the address was not always specified
if (device_distinguishes_on_address(device) && (address.length() == 0)) {
address = String8("0");
}
- for (size_t i = 0; i < size(); i++) {
- const sp<HwModule> hwModule = itemAt(i);
- if (hwModule->mHandle == 0) {
- continue;
- }
+ for (const auto& hwModule : *this) {
DeviceVector declaredDevices = hwModule->getDeclaredDevices();
DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address);
if (!deviceList.isEmpty()) {
@@ -340,4 +321,5 @@
return NO_ERROR;
}
+
} //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fc89672..4f730d5 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -122,16 +122,6 @@
result.append("\n");
write(fd, result.string(), result.size());
mSupportedDevices.dump(fd, String8("Supported"), 4, false);
-
- result.clear();
- snprintf(buffer, SIZE, "\n - maxOpenCount: %u - curOpenCount: %u\n",
- maxOpenCount, curOpenCount);
- result.append(buffer);
- snprintf(buffer, SIZE, " - maxActiveCount: %u - curActiveCount: %u\n",
- maxActiveCount, curActiveCount);
- result.append(buffer);
-
- write(fd, result.string(), result.size());
}
void IOProfile::log()
@@ -139,4 +129,4 @@
// @TODO: forward log to AudioPort
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index aa589f4..4805c3f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -217,8 +217,6 @@
const char MixPortTraits::Attributes::name[] = "name";
const char MixPortTraits::Attributes::role[] = "role";
const char MixPortTraits::Attributes::flags[] = "flags";
-const char MixPortTraits::Attributes::maxOpenCount[] = "maxOpenCount";
-const char MixPortTraits::Attributes::maxActiveCount[] = "maxActiveCount";
status_t MixPortTraits::deserialize(_xmlDoc *doc, const _xmlNode *child, PtrElement &mixPort,
PtrSerializingCtx /*serializingContext*/)
@@ -261,14 +259,6 @@
mixPort->setFlags(InputFlagConverter::maskFromString(flags));
}
}
- string maxOpenCount = getXmlAttribute(child, Attributes::maxOpenCount);
- if (!maxOpenCount.empty()) {
- convertTo(maxOpenCount, mixPort->maxOpenCount);
- }
- string maxActiveCount = getXmlAttribute(child, Attributes::maxActiveCount);
- if (!maxActiveCount.empty()) {
- convertTo(maxActiveCount, mixPort->maxActiveCount);
- }
// Deserialize children
AudioGainTraits::Collection gains;
deserializeCollection<AudioGainTraits>(doc, child, gains, NULL);
@@ -648,4 +638,4 @@
return android::OK;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
index b3019e1..65649fb 100644
--- a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
@@ -223,4 +223,4 @@
return NO_ERROR;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
index 0362037..7273d0d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
@@ -65,4 +65,4 @@
template class TypeConverter<RouteFlagTraits>;
template class TypeConverter<RuleTraits>;
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp b/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
index 14caf7c..ec861c1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
@@ -138,4 +138,4 @@
return NO_ERROR;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 567ff9e..04594f5 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -137,4 +137,4 @@
virtual ~AudioPolicyManagerInterface() {}
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
index 846fa48..b7902cf 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h
@@ -59,4 +59,4 @@
virtual ~AudioPolicyManagerObserver() {}
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
index 6c4be2c..a597e87 100644
--- a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
+++ b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
@@ -76,6 +76,6 @@
template <>
AudioPolicyPluginInterface *EngineInstance::queryInterface() const;
-}; // namespace audio_policy
+} // namespace audio_policy
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
index 759d0c9..2e29a9b 100644
--- a/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
+++ b/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h
@@ -143,4 +143,4 @@
virtual ~AudioPolicyPluginInterface() {}
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index bc5e035..328d23d 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -194,7 +194,7 @@
AudioPolicyManagerObserver *mApmObserver;
};
-}; // namespace audio_policy
+} // namespace audio_policy
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/manager/AudioPolicyFactory.cpp b/services/audiopolicy/manager/AudioPolicyFactory.cpp
index 9910a1f..3efa1b0 100644
--- a/services/audiopolicy/manager/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/manager/AudioPolicyFactory.cpp
@@ -29,4 +29,4 @@
delete interface;
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b363779..ad24439 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -32,7 +32,6 @@
#include <AudioPolicyManagerInterface.h>
#include <AudioPolicyEngineInstance.h>
-#include <cutils/atomic.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <media/AudioParameter.h>
@@ -88,7 +87,7 @@
const char *device_name)
{
ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
-- device, state, device_address, device_name);
+ device, state, device_address, device_name);
// connect/disconnect only 1 device at a time
if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
@@ -183,14 +182,14 @@
checkOutputForAllStrategies();
// outputs must be closed after checkOutputForAllStrategies() is executed
if (!outputs.isEmpty()) {
- for (size_t i = 0; i < outputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
+ for (audio_io_handle_t output : outputs) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
// close unused outputs after device disconnection or direct outputs that have been
// opened by checkOutputsForDevice() to query dynamic parameters
if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
(((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
(desc->mDirectOpenCount == 0))) {
- closeOutput(outputs[i]);
+ closeOutput(output);
}
}
// check again after closing A2DP output to reset mA2dpSuspended if needed
@@ -387,9 +386,6 @@
uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
{
bool createTxPatch = false;
- status_t status;
- audio_patch_handle_t afPatchHandle;
- DeviceVector deviceList;
uint32_t muteWaitMs = 0;
if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
@@ -421,87 +417,53 @@
createTxPatch = true;
}
} else { // create RX path audio patch
- struct audio_patch patch;
-
- patch.num_sources = 1;
- patch.num_sinks = 1;
- deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
- ALOG_ASSERT(!deviceList.isEmpty(),
- "updateCallRouting() selected device not in output device list");
- sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
- deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
- ALOG_ASSERT(!deviceList.isEmpty(),
- "updateCallRouting() no telephony RX device");
- sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
-
- rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
- rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
-
- // request to reuse existing output stream if one is already opened to reach the RX device
- SortedVector<audio_io_handle_t> outputs =
- getOutputsForDevice(rxDevice, mOutputs);
- audio_io_handle_t output = selectOutput(outputs,
- AUDIO_OUTPUT_FLAG_NONE,
- AUDIO_FORMAT_INVALID);
- if (output != AUDIO_IO_HANDLE_NONE) {
- sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
- ALOG_ASSERT(!outputDesc->isDuplicated(),
- "updateCallRouting() RX device output is duplicated");
- outputDesc->toAudioPortConfig(&patch.sources[1]);
- patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
- patch.num_sources = 2;
- }
-
- afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
- ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
- status);
- if (status == NO_ERROR) {
- mCallRxPatch = new AudioPatch(&patch, mUidCached);
- mCallRxPatch->mAfPatchHandle = afPatchHandle;
- mCallRxPatch->mUid = mUidCached;
- }
+ mCallRxPatch = createTelephonyPatch(true /*isRx*/, rxDevice, delayMs);
createTxPatch = true;
}
if (createTxPatch) { // create TX path audio patch
- struct audio_patch patch;
+ mCallTxPatch = createTelephonyPatch(false /*isRx*/, txDevice, delayMs);
+ }
- patch.num_sources = 1;
- patch.num_sinks = 1;
- deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
- ALOG_ASSERT(!deviceList.isEmpty(),
- "updateCallRouting() selected device not in input device list");
- sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
- txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
- deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
- ALOG_ASSERT(!deviceList.isEmpty(),
- "updateCallRouting() no telephony TX device");
- sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
- txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
+ return muteWaitMs;
+}
- SortedVector<audio_io_handle_t> outputs =
- getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
- audio_io_handle_t output = selectOutput(outputs,
- AUDIO_OUTPUT_FLAG_NONE,
- AUDIO_FORMAT_INVALID);
- // request to reuse existing output stream if one is already opened to reach the TX
- // path output device
- if (output != AUDIO_IO_HANDLE_NONE) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
- ALOG_ASSERT(!outputDesc->isDuplicated(),
- "updateCallRouting() RX device output is duplicated");
- outputDesc->toAudioPortConfig(&patch.sources[1]);
- patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
- patch.num_sources = 2;
- }
+sp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
+ bool isRx, audio_devices_t device, uint32_t delayMs) {
+ struct audio_patch patch;
+ patch.num_sources = 1;
+ patch.num_sinks = 1;
+ sp<DeviceDescriptor> txSourceDeviceDesc;
+ if (isRx) {
+ fillAudioPortConfigForDevice(mAvailableOutputDevices, device, &patch.sinks[0]);
+ fillAudioPortConfigForDevice(
+ mAvailableInputDevices, AUDIO_DEVICE_IN_TELEPHONY_RX, &patch.sources[0]);
+ } else {
+ txSourceDeviceDesc = fillAudioPortConfigForDevice(
+ mAvailableInputDevices, device, &patch.sources[0]);
+ fillAudioPortConfigForDevice(
+ mAvailableOutputDevices, AUDIO_DEVICE_OUT_TELEPHONY_TX, &patch.sinks[0]);
+ }
+
+ audio_devices_t outputDevice = isRx ? device : AUDIO_DEVICE_OUT_TELEPHONY_TX;
+ SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(outputDevice, mOutputs);
+ audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
+ // request to reuse existing output stream if one is already opened to reach the target device
+ if (output != AUDIO_IO_HANDLE_NONE) {
+ sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
+ ALOG_ASSERT(!outputDesc->isDuplicated(),
+ "%s() %#x device output %d is duplicated", __func__, outputDevice, output);
+ outputDesc->toAudioPortConfig(&patch.sources[1]);
+ patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
+ patch.num_sources = 2;
+ }
+
+ if (!isRx) {
// terminate active capture if on the same HW module as the call TX source device
// FIXME: would be better to refine to only inputs whose profile connects to the
// call TX device but this information is not in the audio patch and logic here must be
// symmetric to the one in startInput()
- Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
+ for (const auto& activeDesc : mInputs.getActiveInputs()) {
if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
AudioSessionCollection activeSessions =
activeDesc->getAudioSessions(true /*activeOnly*/);
@@ -512,19 +474,29 @@
}
}
}
-
- afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
- ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
- status);
- if (status == NO_ERROR) {
- mCallTxPatch = new AudioPatch(&patch, mUidCached);
- mCallTxPatch->mAfPatchHandle = afPatchHandle;
- mCallTxPatch->mUid = mUidCached;
- }
}
- return muteWaitMs;
+ audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+ status_t status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
+ ALOGW_IF(status != NO_ERROR,
+ "%s() error %d creating %s audio patch", __func__, status, isRx ? "RX" : "TX");
+ sp<AudioPatch> audioPatch;
+ if (status == NO_ERROR) {
+ audioPatch = new AudioPatch(&patch, mUidCached);
+ audioPatch->mAfPatchHandle = afPatchHandle;
+ audioPatch->mUid = mUidCached;
+ }
+ return audioPatch;
+}
+
+sp<DeviceDescriptor> AudioPolicyManager::fillAudioPortConfigForDevice(
+ const DeviceVector& devices, audio_devices_t device, audio_port_config *config) {
+ DeviceVector deviceList = devices.getDevicesFromType(device);
+ ALOG_ASSERT(!deviceList.isEmpty(),
+ "%s() selected device type %#x is not in devices list", __func__, device);
+ sp<DeviceDescriptor> deviceDesc = deviceList.itemAt(0);
+ deviceDesc->toAudioPortConfig(config);
+ return deviceDesc;
}
void AudioPolicyManager::setPhoneState(audio_mode_t state)
@@ -683,9 +655,7 @@
}
}
- Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
+ for (const auto& activeDesc : mInputs.getActiveInputs()) {
audio_devices_t newDevice = getNewInputDevice(activeDesc);
// Force new input selection if the new device can not be reached via current input
if (activeDesc->mProfile->getSupportedDevices().types() &
@@ -721,12 +691,8 @@
sp<IOProfile> profile;
- for (size_t i = 0; i < mHwModules.size(); i++) {
- if (mHwModules[i]->mHandle == 0) {
- continue;
- }
- for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
- sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
+ for (const auto& hwModule : mHwModules) {
+ for (const auto& curProfile : hwModule->getOutputProfiles()) {
if (!curProfile->isCompatibleProfile(device, String8(""),
samplingRate, NULL /*updatedSamplingRate*/,
format, NULL /*updatedFormat*/,
@@ -827,12 +793,7 @@
// Explicit routing?
sp<DeviceDescriptor> deviceDesc;
if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
- for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
- if (mAvailableOutputDevices[i]->getId() == *selectedDeviceId) {
- deviceDesc = mAvailableOutputDevices[i];
- break;
- }
- }
+ deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
}
mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
@@ -926,29 +887,37 @@
}
if (profile != 0) {
+ sp<SwAudioOutputDescriptor> outputDesc = NULL;
+
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if (!desc->isDuplicated() && (profile == desc->mProfile)) {
+ outputDesc = desc;
// reuse direct output if currently open by the same client
// and configured with same parameters
- if ((config->sample_rate == desc->mSamplingRate) &&
- audio_formats_match(config->format, desc->mFormat) &&
- (config->channel_mask == desc->mChannelMask) &&
- (session == desc->mDirectClientSession)) {
- desc->mDirectOpenCount++;
- ALOGV("getOutputForDevice() reusing direct output %d for session %d",
- mOutputs.keyAt(i), session);
- return mOutputs.keyAt(i);
+ if ((config->sample_rate == outputDesc->mSamplingRate) &&
+ audio_formats_match(config->format, outputDesc->mFormat) &&
+ (config->channel_mask == outputDesc->mChannelMask)) {
+ if (session == outputDesc->mDirectClientSession) {
+ outputDesc->mDirectOpenCount++;
+ ALOGV("getOutputForDevice() reusing direct output %d for session %d",
+ mOutputs.keyAt(i), session);
+ return mOutputs.keyAt(i);
+ } else {
+ ALOGV("getOutputForDevice() do not reuse direct output because"
+ "current client (%d) is not the same as requesting client (%d)",
+ outputDesc->mDirectClientSession, session);
+ goto non_direct_output;
+ }
}
}
}
-
- if (!profile->canOpenNewIo()) {
- goto non_direct_output;
+ // close direct output if currently open and configured with different parameters
+ if (outputDesc != NULL) {
+ closeOutput(outputDesc->mIoHandle);
}
- sp<SwAudioOutputDescriptor> outputDesc =
- new SwAudioOutputDescriptor(profile, mpClientInterface);
+ outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
status = outputDesc->open(config, device, String8(""), stream, flags, &output);
// only accept an output with the requested parameters
@@ -1025,21 +994,21 @@
// 4: the first output in the list
if (outputs.size() == 0) {
- return 0;
+ return AUDIO_IO_HANDLE_NONE;
}
if (outputs.size() == 1) {
return outputs[0];
}
int maxCommonFlags = 0;
- audio_io_handle_t outputForFlags = 0;
- audio_io_handle_t outputForPrimary = 0;
- audio_io_handle_t outputForFormat = 0;
+ audio_io_handle_t outputForFlags = AUDIO_IO_HANDLE_NONE;
+ audio_io_handle_t outputForPrimary = AUDIO_IO_HANDLE_NONE;
+ audio_io_handle_t outputForFormat = AUDIO_IO_HANDLE_NONE;
audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
- for (size_t i = 0; i < outputs.size(); i++) {
- sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
+ for (audio_io_handle_t output : outputs) {
+ sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
if (!outputDesc->isDuplicated()) {
// if a valid format is specified, skip output if not compatible
if (format != AUDIO_FORMAT_INVALID) {
@@ -1052,7 +1021,7 @@
}
if (AudioPort::isBetterFormatMatch(
outputDesc->mFormat, bestFormat, format)) {
- outputForFormat = outputs[i];
+ outputForFormat = output;
bestFormat = outputDesc->mFormat;
}
}
@@ -1063,29 +1032,29 @@
if (format != AUDIO_FORMAT_INVALID
&& AudioPort::isBetterFormatMatch(
outputDesc->mFormat, bestFormatForFlags, format)) {
- outputForFlags = outputs[i];
+ outputForFlags = output;
bestFormatForFlags = outputDesc->mFormat;
}
} else {
- outputForFlags = outputs[i];
+ outputForFlags = output;
maxCommonFlags = commonFlags;
bestFormatForFlags = outputDesc->mFormat;
}
- ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
+ ALOGV("selectOutput() commonFlags for output %d, %04x", output, commonFlags);
}
if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
- outputForPrimary = outputs[i];
+ outputForPrimary = output;
}
}
}
- if (outputForFlags != 0) {
+ if (outputForFlags != AUDIO_IO_HANDLE_NONE) {
return outputForFlags;
}
- if (outputForFormat != 0) {
+ if (outputForFormat != AUDIO_IO_HANDLE_NONE) {
return outputForFormat;
}
- if (outputForPrimary != 0) {
+ if (outputForPrimary != AUDIO_IO_HANDLE_NONE) {
return outputForPrimary;
}
@@ -1106,13 +1075,6 @@
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
- if (!outputDesc->isActive()) {
- if (!outputDesc->mProfile->canStartNewIo()) {
- return INVALID_OPERATION;
- }
- outputDesc->mProfile->curActiveCount++;
- }
-
// Routing?
mOutputRoutes.incRouteActivity(session);
@@ -1140,12 +1102,6 @@
if (status != NO_ERROR) {
mOutputRoutes.decRouteActivity(session);
- if (!outputDesc->isActive()) {
- LOG_ALWAYS_FATAL_IF(outputDesc->mProfile->curActiveCount < 1,
- "%s invalid profile active count %u",
- __FUNCTION__, outputDesc->mProfile->curActiveCount);
- outputDesc->mProfile->curActiveCount--;
- }
return status;
}
// Automatically enable the remote submix input when output is started on a re routing mix
@@ -1334,15 +1290,7 @@
}
}
- status_t status = stopSource(outputDesc, stream, forceDeviceUpdate);
-
- if (status == NO_ERROR && !outputDesc->isActive()) {
- LOG_ALWAYS_FATAL_IF(outputDesc->mProfile->curActiveCount < 1,
- "%s invalid profile active count %u",
- __FUNCTION__, outputDesc->mProfile->curActiveCount);
- outputDesc->mProfile->curActiveCount--;
- }
- return status;
+ return stopSource(outputDesc, stream, forceDeviceUpdate);
}
status_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
@@ -1464,12 +1412,7 @@
// Explicit routing?
sp<DeviceDescriptor> deviceDesc;
if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
- for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
- if (mAvailableInputDevices[i]->getId() == *selectedDeviceId) {
- deviceDesc = mAvailableInputDevices[i];
- break;
- }
- }
+ deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
}
mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
@@ -1728,10 +1671,6 @@
}
#endif
- if (!profile->canOpenNewIo()) {
- return AUDIO_IO_HANDLE_NONE;
- }
-
sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile, mpClientInterface);
audio_config_t lConfig = AUDIO_CONFIG_INITIALIZER;
@@ -1796,9 +1735,7 @@
return true;
}
- Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeInput = activeInputs[i];
+ for (const auto& activeInput : mInputs.getActiveInputs()) {
if (!isConcurrentSource(activeInput->inputSource(true)) &&
!is_virtual_input_device(activeInput->mDevice)) {
return false;
@@ -1884,9 +1821,7 @@
}
Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
-
+ for (const auto& activeDesc : activeInputs) {
if (is_virtual_input_device(activeDesc->mDevice)) {
continue;
}
@@ -1926,9 +1861,7 @@
inputDesc->isSoundTrigger() ? soundTriggerSupportsConcurrentCapture() : false;
// if capture is allowed, preempt currently active HOTWORD captures
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
-
+ for (const auto& activeDesc : activeInputs) {
if (is_virtual_input_device(activeDesc->mDevice)) {
continue;
}
@@ -1969,13 +1902,6 @@
setInputDevice(input, device, true /* force */);
if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
- if (!inputDesc->mProfile->canStartNewIo()) {
- mInputRoutes.decRouteActivity(session);
- audioSession->changeActiveCount(-1);
- return INVALID_OPERATION;
- }
- inputDesc->mProfile->curActiveCount++;
-
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -2045,11 +1971,6 @@
if (inputDesc->isActive()) {
setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
} else {
- LOG_ALWAYS_FATAL_IF(inputDesc->mProfile->curActiveCount < 1,
- "%s invalid profile active count %u",
- __FUNCTION__, inputDesc->mProfile->curActiveCount);
- inputDesc->mProfile->curActiveCount--;
-
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
@@ -2135,7 +2056,7 @@
void AudioPolicyManager::closeAllInputs() {
bool patchRemoved = false;
- for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
+ for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
if (patch_index >= 0) {
@@ -2299,21 +2220,21 @@
audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;
- for (size_t i = 0; i < outputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
+ for (audio_io_handle_t output : outputs) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
continue;
}
- ALOGV("selectOutputForMusicEffects activeOnly %d outputs[%zu] flags 0x%08x",
- activeOnly, i, desc->mFlags);
+ ALOGV("selectOutputForMusicEffects activeOnly %d output %d flags 0x%08x",
+ activeOnly, output, desc->mFlags);
if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
- outputOffloaded = outputs[i];
+ outputOffloaded = output;
}
if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
- outputDeepBuffer = outputs[i];
+ outputDeepBuffer = output;
}
if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
- outputPrimary = outputs[i];
+ outputPrimary = output;
}
}
if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
@@ -2424,23 +2345,16 @@
break;
}
if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
- // Loop back through "remote submix"
- if (rSubmixModule == 0) {
- for (size_t j = 0; i < mHwModules.size(); j++) {
- if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
- && mHwModules[j]->mHandle != 0) {
- rSubmixModule = mHwModules[j];
- break;
- }
- }
- }
-
ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
-
if (rSubmixModule == 0) {
- ALOGE(" Unable to find audio module for submix, aborting mix %zu registration", i);
- res = INVALID_OPERATION;
- break;
+ rSubmixModule = mHwModules.getModuleFromName(
+ AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
+ if (rSubmixModule == 0) {
+ ALOGE(" Unable to find audio module for submix, aborting mix %zu registration",
+ i);
+ res = INVALID_OPERATION;
+ break;
+ }
}
String8 address = mixes[i].mDeviceAddress;
@@ -2519,24 +2433,19 @@
status_t res = NO_ERROR;
sp<HwModule> rSubmixModule;
// examine each mix's route type
- for (size_t i = 0; i < mixes.size(); i++) {
- if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
+ for (const auto& mix : mixes) {
+ if ((mix.mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
if (rSubmixModule == 0) {
- for (size_t j = 0; i < mHwModules.size(); j++) {
- if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
- && mHwModules[j]->mHandle != 0) {
- rSubmixModule = mHwModules[j];
- break;
- }
+ rSubmixModule = mHwModules.getModuleFromName(
+ AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX);
+ if (rSubmixModule == 0) {
+ res = INVALID_OPERATION;
+ continue;
}
}
- if (rSubmixModule == 0) {
- res = INVALID_OPERATION;
- continue;
- }
- String8 address = mixes[i].mDeviceAddress;
+ String8 address = mix.mDeviceAddress;
if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
res = INVALID_OPERATION;
@@ -2558,8 +2467,8 @@
rSubmixModule->removeOutputProfile(address);
rSubmixModule->removeInputProfile(address);
- } if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
- if (mPolicyMixes.unregisterMix(mixes[i].mDeviceAddress) != NO_ERROR) {
+ } if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
+ if (mPolicyMixes.unregisterMix(mix.mDeviceAddress) != NO_ERROR) {
res = INVALID_OPERATION;
continue;
}
@@ -2611,7 +2520,7 @@
mAvailableOutputDevices.dump(fd, String8("Available output"));
mAvailableInputDevices.dump(fd, String8("Available input"));
- mHwModules.dump(fd);
+ mHwModulesAll.dump(fd);
mOutputs.dump(fd);
mInputs.dump(fd);
mVolumeCurves->dump(fd);
@@ -2716,23 +2625,23 @@
// do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
// as they are used by stub HALs by convention
if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
- for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
- if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
+ for (const auto& dev : mAvailableOutputDevices) {
+ if (dev->type() == AUDIO_DEVICE_OUT_STUB) {
continue;
}
if (portsWritten < portsMax) {
- mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+ dev->toAudioPort(&ports[portsWritten++]);
}
(*num_ports)++;
}
}
if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
- for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
- if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
+ for (const auto& dev : mAvailableInputDevices) {
+ if (dev->type() == AUDIO_DEVICE_IN_STUB) {
continue;
}
if (portsWritten < portsMax) {
- mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+ dev->toAudioPort(&ports[portsWritten++]);
}
(*num_ports)++;
}
@@ -3227,8 +3136,8 @@
}
}
// reroute outputs if necessary
- for (size_t i = 0; i < affectedStrategies.size(); i++) {
- checkStrategyRoute(affectedStrategies[i], AUDIO_IO_HANDLE_NONE);
+ for (const auto& strategy : affectedStrategies) {
+ checkStrategyRoute(strategy, AUDIO_IO_HANDLE_NONE);
}
// remove input routes associated with this uid
@@ -3250,8 +3159,8 @@
inputsToClose.add(inputDesc->mIoHandle);
}
}
- for (size_t i = 0; i < inputsToClose.size(); i++) {
- closeInput(inputsToClose[i]);
+ for (const auto& input : inputsToClose) {
+ closeInput(input);
}
}
@@ -3428,8 +3337,8 @@
offloaded.push(desc->mIoHandle);
}
}
- for (size_t i = 0; i < offloaded.size(); ++i) {
- closeOutput(offloaded[i]);
+ for (const auto& handle : offloaded) {
+ closeOutput(handle);
}
}
// update master mono for all remaining outputs
@@ -3502,7 +3411,7 @@
// ----------------------------------------------------------------------------
uint32_t AudioPolicyManager::nextAudioPortGeneration()
{
- return android_atomic_inc(&mAudioPortGeneration);
+ return mAudioPortGeneration++;
}
#ifdef USE_XML_AUDIO_POLICY_CONF
@@ -3555,13 +3464,13 @@
#ifdef USE_XML_AUDIO_POLICY_CONF
mVolumeCurves = new VolumeCurvesCollection();
- AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
+ AudioPolicyConfig config(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
mDefaultOutputDevice, speakerDrcEnabled,
static_cast<VolumeCurvesCollection *>(mVolumeCurves));
if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
#else
mVolumeCurves = new StreamDescriptorCollection();
- AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
+ AudioPolicyConfig config(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices,
mDefaultOutputDevice, speakerDrcEnabled);
if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
(ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
@@ -3593,28 +3502,20 @@
// open all output streams needed to access attached devices
audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
- for (size_t i = 0; i < mHwModules.size(); i++) {
- mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
- if (mHwModules[i]->mHandle == 0) {
- ALOGW("could not open HW module %s", mHwModules[i]->getName());
+ for (const auto& hwModule : mHwModulesAll) {
+ hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
+ if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
+ ALOGW("could not open HW module %s", hwModule->getName());
continue;
}
+ mHwModules.push_back(hwModule);
// open all output streams needed to access attached devices
// except for direct output streams that are only opened when they are actually
// required by an app.
// This also validates mAvailableOutputDevices list
- for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
- {
- const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
-
- if (!outProfile->canOpenNewIo()) {
- ALOGE("Invalid Output profile max open count %u for profile %s",
- outProfile->maxOpenCount, outProfile->getTagName().c_str());
- continue;
- }
-
+ for (const auto& outProfile : hwModule->getOutputProfiles()) {
if (!outProfile->hasSupportedDevices()) {
- ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
+ ALOGW("Output profile contains no device on module %s", hwModule->getName());
continue;
}
if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
@@ -3648,13 +3549,13 @@
if (status != NO_ERROR) {
ALOGW("Cannot open output stream for device %08x on hw module %s",
outputDesc->mDevice,
- mHwModules[i]->getName());
+ hwModule->getName());
} else {
- for (size_t k = 0; k < supportedDevices.size(); k++) {
- ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
+ for (const auto& dev : supportedDevices) {
+ ssize_t index = mAvailableOutputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
- mAvailableOutputDevices[index]->attach(mHwModules[i]);
+ mAvailableOutputDevices[index]->attach(hwModule);
}
}
if (mPrimaryOutput == 0 &&
@@ -3672,18 +3573,9 @@
}
// open input streams needed to access attached devices to validate
// mAvailableInputDevices list
- for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
- {
- const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
-
- if (!inProfile->canOpenNewIo()) {
- ALOGE("Invalid Input profile max open count %u for profile %s",
- inProfile->maxOpenCount, inProfile->getTagName().c_str());
- continue;
- }
-
+ for (const auto& inProfile : hwModule->getInputProfiles()) {
if (!inProfile->hasSupportedDevices()) {
- ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
+ ALOGW("Input profile contains no device on module %s", hwModule->getName());
continue;
}
// chose first device present in profile's SupportedDevices also part of
@@ -3705,14 +3597,13 @@
&input);
if (status == NO_ERROR) {
- const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
- for (size_t k = 0; k < supportedDevices.size(); k++) {
- ssize_t index = mAvailableInputDevices.indexOf(supportedDevices[k]);
+ for (const auto& dev : inProfile->getSupportedDevices()) {
+ ssize_t index = mAvailableInputDevices.indexOf(dev);
// give a valid ID to an attached device once confirmed it is reachable
if (index >= 0) {
sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
if (!devDesc->isAttached()) {
- devDesc->attach(mHwModules[i]);
+ devDesc->attach(hwModule);
devDesc->importAudioPort(inProfile, true);
}
}
@@ -3721,7 +3612,7 @@
} else {
ALOGW("Cannot open input stream for device %08x on hw module %s",
profileType,
- mHwModules[i]->getName());
+ hwModule->getName());
}
}
}
@@ -3771,6 +3662,7 @@
mOutputs.clear();
mInputs.clear();
mHwModules.clear();
+ mHwModulesAll.clear();
}
status_t AudioPolicyManager::initCheck()
@@ -3842,19 +3734,15 @@
}
// then look for output profiles that can be routed to this device
SortedVector< sp<IOProfile> > profiles;
- for (size_t i = 0; i < mHwModules.size(); i++)
- {
- if (mHwModules[i]->mHandle == 0) {
- continue;
- }
- for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
- {
- sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
+ for (const auto& hwModule : mHwModules) {
+ for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
+ sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
if (profile->supportDevice(device)) {
if (!device_distinguishes_on_address(device) ||
profile->supportDeviceAddress(address)) {
profiles.add(profile);
- ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
+ ALOGV("checkOutputsForDevice(): adding profile %zu from module %s",
+ j, hwModule->getName());
}
}
}
@@ -3889,12 +3777,6 @@
continue;
}
- if (!profile->canOpenNewIo()) {
- ALOGW("Max Output number %u already opened for this profile %s",
- profile->maxOpenCount, profile->getTagName().c_str());
- continue;
- }
-
ALOGV("opening output for device %08x with params %s profile %p name %s",
device, address.string(), profile.get(), profile->getName().string());
desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
@@ -4024,17 +3906,13 @@
}
}
// Clear any profiles associated with the disconnected device.
- for (size_t i = 0; i < mHwModules.size(); i++)
- {
- if (mHwModules[i]->mHandle == 0) {
- continue;
- }
- for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
- {
- sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
+ for (const auto& hwModule : mHwModules) {
+ for (size_t j = 0; j < hwModule->getOutputProfiles().size(); j++) {
+ sp<IOProfile> profile = hwModule->getOutputProfiles()[j];
if (profile->supportDevice(device)) {
ALOGV("checkOutputsForDevice(): "
- "clearing direct output profile %zu on module %zu", j, i);
+ "clearing direct output profile %zu on module %s",
+ j, hwModule->getName());
profile->clearAudioProfiles();
}
}
@@ -4068,23 +3946,18 @@
// then look for input profiles that can be routed to this device
SortedVector< sp<IOProfile> > profiles;
- for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
- {
- if (mHwModules[module_idx]->mHandle == 0) {
- continue;
- }
+ for (const auto& hwModule : mHwModules) {
for (size_t profile_index = 0;
- profile_index < mHwModules[module_idx]->mInputProfiles.size();
- profile_index++)
- {
- sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
+ profile_index < hwModule->getInputProfiles().size();
+ profile_index++) {
+ sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
if (profile->supportDevice(device)) {
if (!device_distinguishes_on_address(device) ||
profile->supportDeviceAddress(address)) {
profiles.add(profile);
- ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
- profile_index, module_idx);
+ ALOGV("checkInputsForDevice(): adding profile %zu from module %s",
+ profile_index, hwModule->getName());
}
}
}
@@ -4100,7 +3973,6 @@
for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
sp<IOProfile> profile = profiles[profile_index];
-
// nothing to do if one input is already opened for this profile
size_t input_index;
for (input_index = 0; input_index < mInputs.size(); input_index++) {
@@ -4116,12 +3988,6 @@
continue;
}
- if (!profile->canOpenNewIo()) {
- ALOGW("Max Input number %u already opened for this profile %s",
- profile->maxOpenCount, profile->getTagName().c_str());
- continue;
- }
-
desc = new AudioInputDescriptor(profile, mpClientInterface);
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = desc->open(nullptr,
@@ -4178,17 +4044,14 @@
}
}
// Clear any profiles associated with the disconnected device.
- for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
- if (mHwModules[module_index]->mHandle == 0) {
- continue;
- }
+ for (const auto& hwModule : mHwModules) {
for (size_t profile_index = 0;
- profile_index < mHwModules[module_index]->mInputProfiles.size();
+ profile_index < hwModule->getInputProfiles().size();
profile_index++) {
- sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
+ sp<IOProfile> profile = hwModule->getInputProfiles()[profile_index];
if (profile->supportDevice(device)) {
- ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
- profile_index, module_index);
+ ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %s",
+ profile_index, hwModule->getName());
profile->clearAudioProfiles();
}
}
@@ -4340,14 +4203,14 @@
ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
strategy, srcOutputs[0], dstOutputs[0]);
// mute strategy while moving tracks from one output to another
- for (size_t i = 0; i < srcOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
+ for (audio_io_handle_t srcOut : srcOutputs) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOut);
if (isStrategyActive(desc, strategy)) {
setStrategyMute(strategy, true, desc);
setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
}
sp<AudioSourceDescriptor> source =
- getSourceForStrategyOnOutput(srcOutputs[i], strategy);
+ getSourceForStrategyOnOutput(srcOut, strategy);
if (source != 0){
connectAudioSource(source);
}
@@ -4541,9 +4404,8 @@
routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
audio_devices_t curDevices =
getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
- SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs);
- for (size_t i = 0; i < outputs.size(); i++) {
- sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
+ for (audio_io_handle_t output : getOutputsForDevice(curDevices, mOutputs)) {
+ sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
curDevices |= outputDesc->device();
}
@@ -5027,14 +4889,8 @@
// TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
// the best matching profile, not the first one.
- for (size_t i = 0; i < mHwModules.size(); i++)
- {
- if (mHwModules[i]->mHandle == 0) {
- continue;
- }
- for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
- {
- sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
+ for (const auto& hwModule : mHwModules) {
+ for (const auto& profile : hwModule->getInputProfiles()) {
// profile->log();
if (profile->isCompatibleProfile(device, address, samplingRate,
&samplingRate /*updatedSamplingRate*/,
@@ -5514,7 +5370,7 @@
bool supportsAC3 = false;
bool supportsOtherSurround = false;
bool supportsIEC61937 = false;
- for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
+ for (ssize_t formatIndex = 0; formatIndex < (ssize_t)formats.size(); formatIndex++) {
audio_format_t format = formats[formatIndex];
switch (format) {
case AUDIO_FORMAT_AC3:
@@ -5610,8 +5466,7 @@
} else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
bool supports5dot1 = false;
// Are there any channel masks that can be considered "surround"?
- for (size_t maskIndex = 0; maskIndex < channelMasks.size(); maskIndex++) {
- audio_channel_mask_t channelMask = channelMasks[maskIndex];
+ for (audio_channel_mask_t channelMask : channelMasks) {
if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
supports5dot1 = true;
break;
@@ -5648,10 +5503,8 @@
}
profiles.setFormats(formats);
}
- const FormatVector &supportedFormats = profiles.getSupportedFormats();
- for (size_t formatIndex = 0; formatIndex < supportedFormats.size(); formatIndex++) {
- audio_format_t format = supportedFormats[formatIndex];
+ for (audio_format_t format : profiles.getSupportedFormats()) {
ChannelsVector channelMasks;
SampleRateVector samplingRates;
AudioParameter requestedParameters;
@@ -5687,4 +5540,4 @@
}
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 2d41bd1..6038e33 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -16,6 +16,8 @@
#pragma once
+#include <atomic>
+
#include <stdint.h>
#include <sys/types.h>
#include <cutils/config_utils.h>
@@ -266,7 +268,7 @@
{
return mDefaultOutputDevice;
}
-protected:
+
void addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc);
void removeOutput(audio_io_handle_t output);
void addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc);
@@ -468,6 +470,9 @@
}
uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
+ sp<AudioPatch> createTelephonyPatch(bool isRx, audio_devices_t device, uint32_t delayMs);
+ sp<DeviceDescriptor> fillAudioPortConfigForDevice(
+ const DeviceVector& devices, audio_devices_t device, audio_port_config *config);
// if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force
// the re-evaluation of the output device.
@@ -530,9 +535,11 @@
EffectDescriptorCollection mEffects; // list of registered audio effects
bool mA2dpSuspended; // true if A2DP output is suspended
sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
- HwModuleCollection mHwModules;
+ HwModuleCollection mHwModules; // contains only modules that have been loaded successfully
+ HwModuleCollection mHwModulesAll; // normally not needed, used during construction and for
+ // dumps
- volatile int32_t mAudioPortGeneration;
+ std::atomic<uint32_t> mAudioPortGeneration;
AudioPatchCollection mAudioPatches;
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 31c9575..b064f8c 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -233,4 +233,4 @@
return AudioSystem::newAudioUniqueId(use);
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 84b1073..7fe363d 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -744,4 +744,4 @@
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 59d5d14..623180e 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -192,6 +192,6 @@
KeyedVector< audio_session_t, EffectVector* > mOutputSessions;
};
-}; // namespace android
+} // namespace android
#endif // ANDROID_AUDIOPOLICYEFFECTS_H
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 1ee5ccf..7dd6d70 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -778,4 +778,4 @@
}
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 7af2e74..af0c823 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -1146,4 +1146,4 @@
int aps_set_voice_volume(void *service, float volume, int delay_ms);
};
-}; // namespace android
+} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 268697e..833a230 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -577,6 +577,6 @@
audio_mode_t mPhoneState;
};
-}; // namespace android
+} // namespace android
#endif // ANDROID_AUDIOPOLICYSERVICE_H
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 20bd5e4..6abfa81 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -243,29 +243,10 @@
}
if (!cameraFound) {
- hardware::camera::common::V1_0::CameraResourceCost cost;
- res = mCameraProviderManager->getResourceCost(cameraId, &cost);
- if (res != OK) {
- ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
- continue;
- }
- std::set<String8> conflicting;
- for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
- conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
- }
-
- {
- Mutex::Autolock lock(mCameraStatesLock);
- mCameraStates.emplace(id8,
- std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
- }
+ addStates(id8);
}
onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
-
- if (mFlashlight->hasFlashUnit(id8)) {
- mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
- }
}
return OK;
@@ -300,6 +281,31 @@
enumerateProviders();
}
+void CameraService::addStates(const String8 id) {
+ std::string cameraId(id.c_str());
+ hardware::camera::common::V1_0::CameraResourceCost cost;
+ status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
+ if (res != OK) {
+ ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
+ return;
+ }
+ std::set<String8> conflicting;
+ for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
+ conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
+ }
+
+ {
+ Mutex::Autolock lock(mCameraStatesLock);
+ mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
+ conflicting));
+ }
+
+ if (mFlashlight->hasFlashUnit(id)) {
+ mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
+ }
+ logDeviceAdded(id, "Device added");
+}
+
void CameraService::onDeviceStatusChanged(const String8& id,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
@@ -311,8 +317,13 @@
if (state == nullptr) {
if (newStatus == StatusInternal::PRESENT) {
- ALOGW("%s: Unknown camera ID %s, probably newly registered?",
+ ALOGI("%s: Unknown camera ID %s, a new camera is added",
__FUNCTION__, id.string());
+
+ // First add as absent to make sure clients are notified below
+ addStates(id);
+
+ updateStatus(newStatus, id);
} else {
ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
}
@@ -2229,8 +2240,11 @@
mClientPackageName);
mOpsActive = false;
+ // This function is called when a client disconnects. This should
+ // release the camera, but actually only if it was in a proper
+ // functional state, i.e. with status NOT_AVAILABLE
std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
- StatusInternal::ENUMERATING};
+ StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
// Transition to PRESENT if the camera is not in either of the rejected states
sCameraService->updateStatus(StatusInternal::PRESENT,
@@ -2322,7 +2336,7 @@
CameraService::CameraState::CameraState(const String8& id, int cost,
const std::set<String8>& conflicting) : mId(id),
- mStatus(StatusInternal::PRESENT), mCost(cost), mConflicting(conflicting) {}
+ mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
CameraService::CameraState::~CameraState() {}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 6d5dde8..e9373a6 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -512,6 +512,9 @@
// Eumerate all camera providers in the system
status_t enumerateProviders();
+ // Add a new camera to camera and torch state lists
+ void addStates(const String8 id);
+
// Check if we can connect, before we acquire the service lock.
// The returned originalClientPid is the PID of the original process that wants to connect to
// camera.
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index caa0703..9348ecd 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -26,6 +26,10 @@
LOCAL_32_BIT_ONLY := true
LOCAL_INIT_RC := android.hardware.media.omx@1.0-service.rc
+ifeq ($(PRODUCT_FULL_TREBLE),true)
+LOCAL_CFLAGS += -DUSE_VNDBINDER
+endif
+
include $(BUILD_EXECUTABLE)
# service seccomp policy
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index 701ca6e..6f14a42 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -40,8 +40,10 @@
signal(SIGPIPE, SIG_IGN);
SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
+#ifdef USE_VNDBINDER
android::ProcessState::initWithDriver("/dev/vndbinder");
android::ProcessState::self()->startThreadPool();
+#endif // USE_VNDBINDER
::android::hardware::configureRpcThreadpool(64, false);