Merge "Keep effects sessions active when the caller dies."
This commit is contained in:
committed by
Android (Google) Code Review
commit
4332168439
@@ -108,6 +108,8 @@ public:
|
||||
static unsigned int getInputFramesLost(audio_io_handle_t ioHandle);
|
||||
|
||||
static int newAudioSessionId();
|
||||
static void acquireAudioSessionId(int audioSession);
|
||||
static void releaseAudioSessionId(int audioSession);
|
||||
|
||||
// types of io configuration change events received with ioConfigChanged()
|
||||
enum io_config_event {
|
||||
|
||||
@@ -139,6 +139,9 @@ public:
|
||||
|
||||
virtual int newAudioSessionId() = 0;
|
||||
|
||||
virtual void acquireAudioSessionId(int audioSession) = 0;
|
||||
virtual void releaseAudioSessionId(int audioSession) = 0;
|
||||
|
||||
virtual status_t queryNumberEffects(uint32_t *numEffects) = 0;
|
||||
|
||||
virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0;
|
||||
|
||||
@@ -114,6 +114,7 @@ AudioRecord::~AudioRecord()
|
||||
}
|
||||
mAudioRecord.clear();
|
||||
IPCThreadState::self()->flushCommands();
|
||||
AudioSystem::releaseAudioSessionId(mSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +234,7 @@ status_t AudioRecord::set(
|
||||
mInputSource = (uint8_t)inputSource;
|
||||
mFlags = flags;
|
||||
mInput = input;
|
||||
AudioSystem::acquireAudioSessionId(mSessionId);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
@@ -465,6 +467,7 @@ status_t AudioRecord::openRecord_l(
|
||||
((uint16_t)flags) << 16,
|
||||
&mSessionId,
|
||||
&status);
|
||||
|
||||
if (record == 0) {
|
||||
LOGE("AudioFlinger could not create record track, status: %d", status);
|
||||
return status;
|
||||
|
||||
@@ -356,6 +356,20 @@ int AudioSystem::newAudioSessionId() {
|
||||
return af->newAudioSessionId();
|
||||
}
|
||||
|
||||
void AudioSystem::acquireAudioSessionId(int audioSession) {
|
||||
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
||||
if (af != 0) {
|
||||
af->acquireAudioSessionId(audioSession);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSystem::releaseAudioSessionId(int audioSession) {
|
||||
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
||||
if (af != 0) {
|
||||
af->releaseAudioSessionId(audioSession);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
|
||||
|
||||
@@ -134,6 +134,7 @@ AudioTrack::~AudioTrack()
|
||||
}
|
||||
mAudioTrack.clear();
|
||||
IPCThreadState::self()->flushCommands();
|
||||
AudioSystem::releaseAudioSessionId(mSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +260,7 @@ status_t AudioTrack::set(
|
||||
mNewPosition = 0;
|
||||
mUpdatePeriod = 0;
|
||||
mFlags = flags;
|
||||
AudioSystem::acquireAudioSessionId(mSessionId);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* //device/extlibs/pv/android/IAudioflinger.cpp
|
||||
/*
|
||||
**
|
||||
** Copyright 2007, The Android Open Source Project
|
||||
**
|
||||
@@ -63,6 +63,8 @@ enum {
|
||||
GET_RENDER_POSITION,
|
||||
GET_INPUT_FRAMES_LOST,
|
||||
NEW_AUDIO_SESSION_ID,
|
||||
ACQUIRE_AUDIO_SESSION_ID,
|
||||
RELEASE_AUDIO_SESSION_ID,
|
||||
QUERY_NUM_EFFECTS,
|
||||
QUERY_EFFECT,
|
||||
GET_EFFECT_DESCRIPTOR,
|
||||
@@ -526,6 +528,22 @@ public:
|
||||
return id;
|
||||
}
|
||||
|
||||
virtual void acquireAudioSessionId(int audioSession)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
|
||||
data.writeInt32(audioSession);
|
||||
remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply);
|
||||
}
|
||||
|
||||
virtual void releaseAudioSessionId(int audioSession)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
|
||||
data.writeInt32(audioSession);
|
||||
remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply);
|
||||
}
|
||||
|
||||
virtual status_t queryNumberEffects(uint32_t *numEffects)
|
||||
{
|
||||
Parcel data, reply;
|
||||
@@ -919,6 +937,18 @@ status_t BnAudioFlinger::onTransact(
|
||||
reply->writeInt32(newAudioSessionId());
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case ACQUIRE_AUDIO_SESSION_ID: {
|
||||
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
||||
int audioSession = data.readInt32();
|
||||
acquireAudioSessionId(audioSession);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case RELEASE_AUDIO_SESSION_ID: {
|
||||
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
||||
int audioSession = data.readInt32();
|
||||
releaseAudioSessionId(audioSession);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case QUERY_NUM_EFFECTS: {
|
||||
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
||||
uint32_t numEffects;
|
||||
|
||||
@@ -61,12 +61,14 @@ MediaPlayer::MediaPlayer()
|
||||
mVideoWidth = mVideoHeight = 0;
|
||||
mLockThreadId = 0;
|
||||
mAudioSessionId = AudioSystem::newAudioSessionId();
|
||||
AudioSystem::acquireAudioSessionId(mAudioSessionId);
|
||||
mSendLevel = 0;
|
||||
}
|
||||
|
||||
MediaPlayer::~MediaPlayer()
|
||||
{
|
||||
LOGV("destructor");
|
||||
AudioSystem::releaseAudioSessionId(mAudioSessionId);
|
||||
disconnect();
|
||||
IPCThreadState::self()->flushCommands();
|
||||
}
|
||||
@@ -618,7 +620,11 @@ status_t MediaPlayer::setAudioSessionId(int sessionId)
|
||||
if (sessionId < 0) {
|
||||
return BAD_VALUE;
|
||||
}
|
||||
mAudioSessionId = sessionId;
|
||||
if (sessionId != mAudioSessionId) {
|
||||
AudioSystem::releaseAudioSessionId(mAudioSessionId);
|
||||
AudioSystem::acquireAudioSessionId(sessionId);
|
||||
mAudioSessionId = sessionId;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,6 +264,14 @@ status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.append("Global session refs:\n");
|
||||
result.append(" session pid cnt\n");
|
||||
for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
|
||||
AudioSessionRef *r = mAudioSessionRefs[i];
|
||||
snprintf(buffer, SIZE, " %7d %3d %3d\n", r->sessionid, r->pid, r->cnt);
|
||||
result.append(buffer);
|
||||
}
|
||||
write(fd, result.string(), result.size());
|
||||
return NO_ERROR;
|
||||
}
|
||||
@@ -892,6 +900,25 @@ void AudioFlinger::removeNotificationClient(pid_t pid)
|
||||
LOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
|
||||
mNotificationClients.removeItem(pid);
|
||||
}
|
||||
|
||||
LOGV("%d died, releasing its sessions", pid);
|
||||
int num = mAudioSessionRefs.size();
|
||||
bool removed = false;
|
||||
for (int i = 0; i< num; i++) {
|
||||
AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
|
||||
LOGV(" pid %d @ %d", ref->pid, i);
|
||||
if (ref->pid == pid) {
|
||||
LOGV(" removing entry for pid %d session %d", pid, ref->sessionid);
|
||||
mAudioSessionRefs.removeAt(i);
|
||||
delete ref;
|
||||
removed = true;
|
||||
i--;
|
||||
num--;
|
||||
}
|
||||
}
|
||||
if (removed) {
|
||||
purgeStaleEffects_l();
|
||||
}
|
||||
}
|
||||
|
||||
// audioConfigChanged_l() must be called with AudioFlinger::mLock held
|
||||
@@ -5042,6 +5069,109 @@ int AudioFlinger::newAudioSessionId()
|
||||
return nextUniqueId();
|
||||
}
|
||||
|
||||
void AudioFlinger::acquireAudioSessionId(int audioSession)
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
int caller = IPCThreadState::self()->getCallingPid();
|
||||
LOGV("acquiring %d from %d", audioSession, caller);
|
||||
int num = mAudioSessionRefs.size();
|
||||
for (int i = 0; i< num; i++) {
|
||||
AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
|
||||
if (ref->sessionid == audioSession && ref->pid == caller) {
|
||||
ref->cnt++;
|
||||
LOGV(" incremented refcount to %d", ref->cnt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
AudioSessionRef *ref = new AudioSessionRef();
|
||||
ref->sessionid = audioSession;
|
||||
ref->pid = caller;
|
||||
ref->cnt = 1;
|
||||
mAudioSessionRefs.push(ref);
|
||||
LOGV(" added new entry for %d", ref->sessionid);
|
||||
}
|
||||
|
||||
void AudioFlinger::releaseAudioSessionId(int audioSession)
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
int caller = IPCThreadState::self()->getCallingPid();
|
||||
LOGV("releasing %d from %d", audioSession, caller);
|
||||
int num = mAudioSessionRefs.size();
|
||||
for (int i = 0; i< num; i++) {
|
||||
AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
|
||||
if (ref->sessionid == audioSession && ref->pid == caller) {
|
||||
ref->cnt--;
|
||||
LOGV(" decremented refcount to %d", ref->cnt);
|
||||
if (ref->cnt == 0) {
|
||||
mAudioSessionRefs.removeAt(i);
|
||||
delete ref;
|
||||
purgeStaleEffects_l();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOGW("session id %d not found for pid %d", audioSession, caller);
|
||||
}
|
||||
|
||||
void AudioFlinger::purgeStaleEffects_l() {
|
||||
|
||||
LOGV("purging stale effects");
|
||||
|
||||
Vector< sp<EffectChain> > chains;
|
||||
|
||||
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
|
||||
sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
|
||||
for (size_t j = 0; j < t->mEffectChains.size(); j++) {
|
||||
sp<EffectChain> ec = t->mEffectChains[j];
|
||||
chains.push(ec);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < mRecordThreads.size(); i++) {
|
||||
sp<RecordThread> t = mRecordThreads.valueAt(i);
|
||||
for (size_t j = 0; j < t->mEffectChains.size(); j++) {
|
||||
sp<EffectChain> ec = t->mEffectChains[j];
|
||||
chains.push(ec);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < chains.size(); i++) {
|
||||
sp<EffectChain> ec = chains[i];
|
||||
int sessionid = ec->sessionId();
|
||||
sp<ThreadBase> t = ec->mThread.promote();
|
||||
if (t == 0) {
|
||||
continue;
|
||||
}
|
||||
size_t numsessionrefs = mAudioSessionRefs.size();
|
||||
bool found = false;
|
||||
for (size_t k = 0; k < numsessionrefs; k++) {
|
||||
AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
|
||||
if (ref->sessionid == sessionid) {
|
||||
LOGV(" session %d still exists for %d with %d refs",
|
||||
sessionid, ref->pid, ref->cnt);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// remove all effects from the chain
|
||||
while (ec->mEffects.size()) {
|
||||
sp<EffectModule> effect = ec->mEffects[0];
|
||||
effect->unPin();
|
||||
Mutex::Autolock _l (t->mLock);
|
||||
t->removeEffect_l(effect);
|
||||
for (size_t j = 0; j < effect->mHandles.size(); j++) {
|
||||
sp<EffectHandle> handle = effect->mHandles[j].promote();
|
||||
if (handle != 0) {
|
||||
handle->mEffect.clear();
|
||||
}
|
||||
}
|
||||
AudioSystem::unregisterEffect(effect->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
|
||||
AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) const
|
||||
{
|
||||
@@ -5199,6 +5329,7 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
|
||||
}
|
||||
uint32_t numEffects = 0;
|
||||
effect_descriptor_t d;
|
||||
d.flags = 0; // prevent compiler warning
|
||||
bool found = false;
|
||||
|
||||
lStatus = EffectQueryNumberEffects(&numEffects);
|
||||
@@ -5302,7 +5433,7 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
|
||||
mClients.add(pid, client);
|
||||
}
|
||||
|
||||
// create effect on selected output trhead
|
||||
// create effect on selected output thread
|
||||
handle = thread->createEffect_l(client, effectClient, priority, sessionId,
|
||||
&desc, enabled, &lStatus);
|
||||
if (handle != 0 && id != NULL) {
|
||||
@@ -5344,7 +5475,7 @@ status_t AudioFlinger::moveEffects(int sessionId, int srcOutput, int dstOutput)
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
// moveEffectChain_l mustbe called with both srcThread and dstThread mLocks held
|
||||
// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
|
||||
status_t AudioFlinger::moveEffectChain_l(int sessionId,
|
||||
AudioFlinger::PlaybackThread *srcThread,
|
||||
AudioFlinger::PlaybackThread *dstThread,
|
||||
@@ -5370,7 +5501,7 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId,
|
||||
// correct buffer sizes and audio parameters and effect engines reconfigured accordingly
|
||||
int dstOutput = dstThread->id();
|
||||
sp<EffectChain> dstChain;
|
||||
uint32_t strategy;
|
||||
uint32_t strategy = 0; // prevent compiler warning
|
||||
sp<EffectModule> effect = chain->getEffectFromId_l(0);
|
||||
while (effect != 0) {
|
||||
srcThread->removeEffect_l(effect);
|
||||
@@ -5632,14 +5763,17 @@ void AudioFlinger::ThreadBase::setMode(uint32_t mode)
|
||||
}
|
||||
|
||||
void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
|
||||
const wp<EffectHandle>& handle) {
|
||||
const wp<EffectHandle>& handle,
|
||||
bool unpiniflast) {
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
LOGV("disconnectEffect() %p effect %p", this, effect.get());
|
||||
// delete the effect module if removing last handle on it
|
||||
if (effect->removeHandle(handle) == 0) {
|
||||
removeEffect_l(effect);
|
||||
AudioSystem::unregisterEffect(effect->id());
|
||||
if (!effect->isPinned() || unpiniflast) {
|
||||
removeEffect_l(effect);
|
||||
AudioSystem::unregisterEffect(effect->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5847,6 +5981,9 @@ AudioFlinger::EffectModule::EffectModule(const wp<ThreadBase>& wThread,
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) {
|
||||
mPinned = true;
|
||||
}
|
||||
LOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
|
||||
return;
|
||||
Error:
|
||||
@@ -5938,7 +6075,7 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
|
||||
// Prevent calls to process() and other functions on effect interface from now on.
|
||||
// The effect engine will be released by the destructor when the last strong reference on
|
||||
// this object is released which can happen after next process is called.
|
||||
if (size == 0) {
|
||||
if (size == 0 && !mPinned) {
|
||||
mState = DESTROYED;
|
||||
}
|
||||
|
||||
@@ -5955,9 +6092,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
|
||||
void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpiniflast)
|
||||
{
|
||||
LOGV("disconnect() %p handle %p ", this, handle.unsafe_get());
|
||||
// keep a strong reference on this EffectModule to avoid calling the
|
||||
@@ -5966,7 +6101,7 @@ void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
|
||||
{
|
||||
sp<ThreadBase> thread = mThread.promote();
|
||||
if (thread != 0) {
|
||||
thread->disconnectEffect(keep, handle);
|
||||
thread->disconnectEffect(keep, handle, unpiniflast);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6533,11 +6668,14 @@ AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
|
||||
const sp<IEffectClient>& effectClient,
|
||||
int32_t priority)
|
||||
: BnEffect(),
|
||||
mEffect(effect), mEffectClient(effectClient), mClient(client),
|
||||
mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
|
||||
mPriority(priority), mHasControl(false), mEnabled(false)
|
||||
{
|
||||
LOGV("constructor %p", this);
|
||||
|
||||
if (client == 0) {
|
||||
return;
|
||||
}
|
||||
int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
|
||||
mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
|
||||
if (mCblkMemory != 0) {
|
||||
@@ -6556,7 +6694,7 @@ AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
|
||||
AudioFlinger::EffectHandle::~EffectHandle()
|
||||
{
|
||||
LOGV("Destructor %p", this);
|
||||
disconnect();
|
||||
disconnect(false);
|
||||
LOGV("Destructor DONE %p", this);
|
||||
}
|
||||
|
||||
@@ -6605,12 +6743,16 @@ status_t AudioFlinger::EffectHandle::disable()
|
||||
|
||||
void AudioFlinger::EffectHandle::disconnect()
|
||||
{
|
||||
LOGV("disconnect %p", this);
|
||||
disconnect(true);
|
||||
}
|
||||
|
||||
void AudioFlinger::EffectHandle::disconnect(bool unpiniflast)
|
||||
{
|
||||
LOGV("disconnect(%s)", unpiniflast ? "true" : "false");
|
||||
if (mEffect == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mEffect->disconnect(this);
|
||||
mEffect->disconnect(this, unpiniflast);
|
||||
|
||||
sp<ThreadBase> thread = mEffect->thread().promote();
|
||||
if (thread != 0) {
|
||||
@@ -6619,11 +6761,11 @@ void AudioFlinger::EffectHandle::disconnect()
|
||||
|
||||
// release sp on module => module destructor can be called now
|
||||
mEffect.clear();
|
||||
if (mCblk) {
|
||||
mCblk->~effect_param_cblk_t(); // destroy our shared-structure.
|
||||
}
|
||||
mCblkMemory.clear(); // and free the shared memory
|
||||
if (mClient != 0) {
|
||||
if (mCblk) {
|
||||
mCblk->~effect_param_cblk_t(); // destroy our shared-structure.
|
||||
}
|
||||
mCblkMemory.clear(); // and free the shared memory
|
||||
Mutex::Autolock _l(mClient->audioFlinger()->mLock);
|
||||
mClient.clear();
|
||||
}
|
||||
@@ -6643,6 +6785,7 @@ status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
if (mEffect == 0) return DEAD_OBJECT;
|
||||
if (mClient == 0) return INVALID_OPERATION;
|
||||
|
||||
// handle commands that are not forwarded transparently to effect engine
|
||||
if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
|
||||
@@ -6749,15 +6892,15 @@ status_t AudioFlinger::EffectHandle::onTransact(
|
||||
|
||||
void AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
|
||||
{
|
||||
bool locked = tryLock(mCblk->lock);
|
||||
bool locked = mCblk ? tryLock(mCblk->lock) : false;
|
||||
|
||||
snprintf(buffer, size, "\t\t\t%05d %05d %01u %01u %05u %05u\n",
|
||||
(mClient == NULL) ? getpid() : mClient->pid(),
|
||||
mPriority,
|
||||
mHasControl,
|
||||
!locked,
|
||||
mCblk->clientIndex,
|
||||
mCblk->serverIndex
|
||||
mCblk ? mCblk->clientIndex : 0,
|
||||
mCblk ? mCblk->serverIndex : 0
|
||||
);
|
||||
|
||||
if (locked) {
|
||||
|
||||
@@ -149,6 +149,10 @@ public:
|
||||
|
||||
virtual int newAudioSessionId();
|
||||
|
||||
virtual void acquireAudioSessionId(int audioSession);
|
||||
|
||||
virtual void releaseAudioSessionId(int audioSession);
|
||||
|
||||
virtual status_t queryNumberEffects(uint32_t *numEffects);
|
||||
|
||||
virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
|
||||
@@ -215,6 +219,7 @@ private:
|
||||
status_t initCheck() const;
|
||||
virtual void onFirstRef();
|
||||
audio_hw_device_t* findSuitableHwDev_l(uint32_t devices);
|
||||
void purgeStaleEffects_l();
|
||||
|
||||
// Internal dump utilites.
|
||||
status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
|
||||
@@ -436,7 +441,8 @@ private:
|
||||
int *enabled,
|
||||
status_t *status);
|
||||
void disconnectEffect(const sp< EffectModule>& effect,
|
||||
const wp<EffectHandle>& handle);
|
||||
const wp<EffectHandle>& handle,
|
||||
bool unpiniflast);
|
||||
|
||||
// return values for hasAudioSession (bit field)
|
||||
enum effect_state {
|
||||
@@ -519,6 +525,7 @@ private:
|
||||
// updated mSuspendedSessions when an effect chain is removed
|
||||
void updateSuspendedSessionsOnRemoveEffectChain_l(const sp<EffectChain>& chain);
|
||||
|
||||
friend class AudioFlinger;
|
||||
friend class Track;
|
||||
friend class TrackBase;
|
||||
friend class PlaybackThread;
|
||||
@@ -607,7 +614,6 @@ private:
|
||||
|
||||
protected:
|
||||
friend class ThreadBase;
|
||||
friend class AudioFlinger;
|
||||
friend class TrackHandle;
|
||||
friend class PlaybackThread;
|
||||
friend class MixerThread;
|
||||
@@ -1100,7 +1106,7 @@ private:
|
||||
wp<ThreadBase>& thread() { return mThread; }
|
||||
|
||||
status_t addHandle(sp<EffectHandle>& handle);
|
||||
void disconnect(const wp<EffectHandle>& handle);
|
||||
void disconnect(const wp<EffectHandle>& handle, bool unpiniflast);
|
||||
size_t removeHandle (const wp<EffectHandle>& handle);
|
||||
|
||||
effect_descriptor_t& desc() { return mDescriptor; }
|
||||
@@ -1115,9 +1121,15 @@ private:
|
||||
|
||||
sp<EffectHandle> controlHandle();
|
||||
|
||||
bool isPinned() { return mPinned; }
|
||||
void unPin() { mPinned = false; }
|
||||
|
||||
status_t dump(int fd, const Vector<String16>& args);
|
||||
|
||||
protected:
|
||||
friend class EffectHandle;
|
||||
friend class AudioFlinger;
|
||||
bool mPinned;
|
||||
|
||||
// Maximum time allocated to effect engines to complete the turn off sequence
|
||||
static const uint32_t MAX_DISABLE_TIME_MS = 10000;
|
||||
@@ -1169,6 +1181,7 @@ private:
|
||||
uint32_t *replySize,
|
||||
void *pReplyData);
|
||||
virtual void disconnect();
|
||||
virtual void disconnect(bool unpiniflast);
|
||||
virtual sp<IMemory> getCblk() const;
|
||||
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
||||
Parcel* reply, uint32_t flags);
|
||||
@@ -1196,7 +1209,8 @@ private:
|
||||
void dump(char* buffer, size_t size);
|
||||
|
||||
protected:
|
||||
|
||||
friend class AudioFlinger;
|
||||
friend class EffectModule;
|
||||
EffectHandle(const EffectHandle&);
|
||||
EffectHandle& operator =(const EffectHandle&);
|
||||
|
||||
@@ -1288,7 +1302,7 @@ private:
|
||||
status_t dump(int fd, const Vector<String16>& args);
|
||||
|
||||
protected:
|
||||
|
||||
friend class AudioFlinger;
|
||||
EffectChain(const EffectChain&);
|
||||
EffectChain& operator =(const EffectChain&);
|
||||
|
||||
@@ -1344,6 +1358,12 @@ private:
|
||||
hwDev(dev), stream(in) {}
|
||||
};
|
||||
|
||||
struct AudioSessionRef {
|
||||
int sessionid;
|
||||
pid_t pid;
|
||||
int cnt;
|
||||
};
|
||||
|
||||
friend class RecordThread;
|
||||
friend class PlaybackThread;
|
||||
|
||||
@@ -1369,6 +1389,7 @@ private:
|
||||
uint32_t mMode;
|
||||
bool mBtNrec;
|
||||
|
||||
Vector<AudioSessionRef*> mAudioSessionRefs;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user