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) {
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index ce1ae4d..1c41ce1 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -332,7 +332,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 5958f4f..211ec98 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 8ef6b1fc..d333f59 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2784,8 +2784,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;