Add use for audio_unique_id_t
Bug: 25641253
Bug: 21019153
Change-Id: I65dc128e760c245f3d90559635a8981b186c87d7
(cherry picked from commit eeecb980ff4c202d0a3c4b0bfe040dce2f73336d)
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index e3f2d60..901a0fd 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -150,9 +150,9 @@
// Allocate a new unique ID for use as an audio session ID or I/O handle.
// If unable to contact AudioFlinger, returns AUDIO_UNIQUE_ID_ALLOCATE instead.
// FIXME If AudioFlinger were to ever exhaust the unique ID namespace,
- // this method could fail by returning either AUDIO_UNIQUE_ID_ALLOCATE
+ // this method could fail by returning either a reserved ID like AUDIO_UNIQUE_ID_ALLOCATE
// or an unspecified existing unique ID.
- static audio_unique_id_t newAudioUniqueId();
+ static audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
static void acquireAudioSessionId(int audioSession, pid_t pid);
static void releaseAudioSessionId(int audioSession, pid_t pid);
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 3b69ecf..e28f79d 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -182,7 +182,7 @@
virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
- virtual audio_unique_id_t newAudioUniqueId() = 0;
+ virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
virtual void acquireAudioSessionId(int audioSession, pid_t pid) = 0;
virtual void releaseAudioSessionId(int audioSession, pid_t pid) = 0;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index ec57d96..1701f80 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -231,7 +231,7 @@
// mNotificationFramesAct is initialized in openRecord_l
if (sessionId == AUDIO_SESSION_ALLOCATE) {
- mSessionId = AudioSystem::newAudioUniqueId();
+ mSessionId = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
} else {
mSessionId = sessionId;
}
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 56c600d..1af5660 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -394,11 +394,11 @@
return result;
}
-audio_unique_id_t AudioSystem::newAudioUniqueId()
+audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
- return af->newAudioUniqueId();
+ return af->newAudioUniqueId(use);
}
void AudioSystem::acquireAudioSessionId(int audioSession, pid_t pid)
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index f0074b6..36c1d10 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -438,7 +438,7 @@
mNotificationFramesReq = notificationFrames;
mNotificationFramesAct = 0;
if (sessionId == AUDIO_SESSION_ALLOCATE) {
- mSessionId = AudioSystem::newAudioUniqueId();
+ mSessionId = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
} else {
mSessionId = sessionId;
}
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 0bf503a..e1de111 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -612,10 +612,11 @@
return (uint32_t) reply.readInt32();
}
- virtual audio_unique_id_t newAudioUniqueId()
+ virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32((int32_t) use);
status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
audio_unique_id_t id = AUDIO_SESSION_ALLOCATE;
if (status == NO_ERROR) {
@@ -1208,7 +1209,7 @@
} break;
case NEW_AUDIO_SESSION_ID: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32(newAudioUniqueId());
+ reply->writeInt32(newAudioUniqueId((audio_unique_id_use_t) data.readInt32()));
return NO_ERROR;
} break;
case ACQUIRE_AUDIO_SESSION_ID: {
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 337e963..7e502af 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -63,7 +63,7 @@
mLeftVolume = mRightVolume = 1.0;
mVideoWidth = mVideoHeight = 0;
mLockThreadId = 0;
- mAudioSessionId = AudioSystem::newAudioUniqueId();
+ mAudioSessionId = AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
mSendLevel = 0;
mRetransmitEndpointValid = false;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 0a3a832..ada1580 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -175,7 +175,7 @@
mHardwareStatus(AUDIO_HW_IDLE),
mMasterVolume(1.0f),
mMasterMute(false),
- mNextUniqueId(1),
+ mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX), // zero has a special meaning, so unavailable
mMode(AUDIO_MODE_INVALID),
mBtNrecIsOff(false),
mIsLowRamDevice(true),
@@ -611,6 +611,11 @@
PlaybackThread *effectThread = NULL;
if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
+ if (audio_unique_id_get_use(*sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
+ ALOGE("createTrack() invalid session ID %d", *sessionId);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
lSessionId = *sessionId;
// check if an effect chain with the same session ID is present on another
// output thread and move it here.
@@ -626,7 +631,7 @@
}
} else {
// if no audio session id is provided, create one here
- lSessionId = nextUniqueId();
+ lSessionId = nextUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
if (sessionId != NULL) {
*sessionId = lSessionId;
}
@@ -1481,10 +1486,14 @@
client = registerPid(pid);
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 = nextUniqueId();
+ lSessionId = nextUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
if (sessionId != NULL) {
*sessionId = lSessionId;
}
@@ -1617,7 +1626,7 @@
mHardwareStatus = AUDIO_HW_IDLE;
}
- audio_module_handle_t handle = nextUniqueId();
+ audio_module_handle_t handle = nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
@@ -1762,8 +1771,14 @@
}
audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
+
if (*output == AUDIO_IO_HANDLE_NONE) {
- *output = nextUniqueId();
+ *output = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
+ } else {
+ // Audio Policy does not currently request a specific output handle.
+ // If this is ever needed, see openInput_l() for example code.
+ ALOGE("openOutput_l requested output handle %d is not AUDIO_IO_HANDLE_NONE", *output);
+ return 0;
}
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
@@ -1880,7 +1895,7 @@
return AUDIO_IO_HANDLE_NONE;
}
- audio_io_handle_t id = nextUniqueId();
+ audio_io_handle_t id = nextUniqueId(AUDIO_UNIQUE_ID_USE_OUTPUT);
DuplicatingThread *thread = new DuplicatingThread(this, thread1, id, mSystemReady);
thread->addOutputTrack(thread2);
mPlaybackThreads.add(id, thread);
@@ -2034,8 +2049,18 @@
return 0;
}
+ // Audio Policy can request a specific handle for hardware hotword.
+ // The goal here is not to re-open an already opened input.
+ // It is to use a pre-assigned I/O handle.
if (*input == AUDIO_IO_HANDLE_NONE) {
- *input = nextUniqueId();
+ *input = nextUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
+ } else if (audio_unique_id_get_use(*input) != AUDIO_UNIQUE_ID_USE_INPUT) {
+ ALOGE("openInput_l() requested input handle %d is invalid", *input);
+ return 0;
+ } else if (mRecordThreads.indexOfKey(*input) >= 0) {
+ // This should not happen in a transient state with current design.
+ ALOGE("openInput_l() requested input handle %d is already assigned", *input);
+ return 0;
}
audio_config_t halconfig = *config;
@@ -2239,9 +2264,9 @@
}
-audio_unique_id_t AudioFlinger::newAudioUniqueId()
+audio_unique_id_t AudioFlinger::newAudioUniqueId(audio_unique_id_use_t use)
{
- return nextUniqueId();
+ return nextUniqueId(use);
}
void AudioFlinger::acquireAudioSessionId(int audioSession, pid_t pid)
@@ -2363,6 +2388,23 @@
return;
}
+// checkThread_l() must be called with AudioFlinger::mLock held
+AudioFlinger::ThreadBase *AudioFlinger::checkThread_l(audio_io_handle_t ioHandle) const
+{
+ ThreadBase *thread = NULL;
+ switch (audio_unique_id_get_use(ioHandle)) {
+ case AUDIO_UNIQUE_ID_USE_OUTPUT:
+ thread = checkPlaybackThread_l(ioHandle);
+ break;
+ case AUDIO_UNIQUE_ID_USE_INPUT:
+ thread = checkRecordThread_l(ioHandle);
+ break;
+ default:
+ break;
+ }
+ return thread;
+}
+
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
{
@@ -2382,9 +2424,14 @@
return mRecordThreads.valueFor(input).get();
}
-uint32_t AudioFlinger::nextUniqueId()
+audio_unique_id_t AudioFlinger::nextUniqueId(audio_unique_id_use_t use)
{
- return (uint32_t) android_atomic_inc(&mNextUniqueId);
+ int32_t base = android_atomic_add(AUDIO_UNIQUE_ID_USE_MAX, &mNextUniqueId);
+ // We have no way of recovering from wraparound
+ LOG_ALWAYS_FATAL_IF(base == 0, "unique ID overflow");
+ LOG_ALWAYS_FATAL_IF((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX);
+ ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
+ return (audio_unique_id_t) (base | use);
}
AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index f2f11e3..858ebbb 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -196,7 +196,7 @@
virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
- virtual audio_unique_id_t newAudioUniqueId();
+ virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
virtual void acquireAudioSessionId(int audioSession, pid_t pid);
@@ -517,6 +517,7 @@
};
+ ThreadBase *checkThread_l(audio_io_handle_t ioHandle) const;
PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;
MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
@@ -547,15 +548,17 @@
const sp<AudioIoDescriptor>& ioDesc,
pid_t pid = 0);
- // Allocate an audio_io_handle_t, session ID, effect ID, or audio_module_handle_t.
+ // Allocate an audio_unique_id_t.
+ // Specific types are audio_io_handle_t, audio_session_t, effect ID (int),
+ // audio_module_handle_t, and audio_patch_handle_t.
// They all share the same ID space, but the namespaces are actually independent
// because there are separate KeyedVectors for each kind of ID.
- // The return value is uint32_t, but is cast to signed for some IDs.
+ // The return value is cast to the specific type depending on how the ID will be used.
// FIXME This API does not handle rollover to zero (for unsigned IDs),
// or from positive to negative (for signed IDs).
// Thus it may fail by returning an ID of the wrong sign,
// or by returning a non-unique ID.
- uint32_t nextUniqueId();
+ audio_unique_id_t nextUniqueId(audio_unique_id_use_t use);
status_t moveEffectChain_l(int sessionId,
PlaybackThread *srcThread,
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index a6cb9c0..5fcc0fe 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -349,7 +349,7 @@
exit:
ALOGV("createAudioPatch() status %d", status);
if (status == NO_ERROR) {
- *handle = audioflinger->nextUniqueId();
+ *handle = audioflinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
newPatch->mHandle = *handle;
newPatch->mHalHandle = halHandle;
mPatches.add(newPatch);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e3036c6..a684c1e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1342,7 +1342,7 @@
ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get());
if (effect == 0) {
- int id = mAudioFlinger->nextUniqueId();
+ audio_unique_id_t id = mAudioFlinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
// Check CPU and memory usage
lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id);
if (lStatus != NO_ERROR) {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 7641bb9..e0aae5e 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -343,7 +343,7 @@
virtual void onAudioPatchListUpdate() = 0;
- virtual audio_unique_id_t newAudioUniqueId() = 0;
+ virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index e19a8ee..8130792 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -66,6 +66,7 @@
virtual void attach(const sp<HwModule>& module);
bool isAttached() { return mModule != 0; }
+ // Audio port IDs are in a different namespace than AudioFlinger unique IDs
static audio_port_handle_t getNextUniqueId();
virtual void toAudioPort(struct audio_port *port) const;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index bda59ad..031444b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -36,6 +36,7 @@
mModule = module;
}
+// 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));
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4ca9d0c..f48cbd4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2870,8 +2870,8 @@
audio_io_handle_t *ioHandle,
audio_devices_t *device)
{
- *session = (audio_session_t)mpClientInterface->newAudioUniqueId();
- *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId();
+ *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+ *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
*device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index c4790b5..f1c0d1a 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -228,9 +228,9 @@
clientConfig, deviceConfig, patchHandle);
}
-audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId()
+audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId(audio_unique_id_use_t use)
{
- return AudioSystem::newAudioUniqueId();
+ return AudioSystem::newAudioUniqueId(use);
}
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 8d15eac..cecd617 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -522,7 +522,7 @@
const audio_config_base_t *clientConfig,
const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle);
- virtual audio_unique_id_t newAudioUniqueId();
+ virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
private:
AudioPolicyService *mAudioPolicyService;