Add use for audio_unique_id_t
Bug: 25641253
Bug: 21019153
Change-Id: I65dc128e760c245f3d90559635a8981b186c87d7
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) {