Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f68be1a authored by The Android Open Source Project's avatar The Android Open Source Project
Browse files

auto import from //branches/cupcake_rel/...@140373

parent ebad147e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -814,7 +814,7 @@ struct ResTable_config
        ORIENTATION_ANY  = 0x0000,
        ORIENTATION_PORT = 0x0001,
        ORIENTATION_LAND = 0x0002,
        ORIENTATION_SQUARE = 0x0002,
        ORIENTATION_SQUARE = 0x0003,
    };
    
    enum {
+71 −90
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@

namespace android {

static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
static const char* kHardwareLockedString = "Hardware lock is taken\n";

//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
static const unsigned long kBufferRecoveryInUsecs = 2000;
static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
@@ -243,12 +246,6 @@ bool AudioFlinger::streamForcedToSpeaker(int streamType)
            streamType == AudioSystem::NOTIFICATION);
}

bool AudioFlinger::streamDisablesA2dp(int streamType)
{
    return (streamType == AudioSystem::VOICE_CALL ||
            streamType == AudioSystem::BLUETOOTH_SCO);
}

status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
@@ -301,19 +298,40 @@ status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args
    return NO_ERROR;
}

status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
static bool tryLock(Mutex& mutex)
{
    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
        dumpPermissionDenial(fd, args);
    } else {
    bool locked = false;
    for (int i = 0; i < kDumpLockRetries; ++i) {
            if (mLock.tryLock() == NO_ERROR) {
        if (mutex.tryLock() == NO_ERROR) {
            locked = true;
            break;
        }
        usleep(kDumpLockSleep);
    }
    return locked;
}

status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
{
    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
        dumpPermissionDenial(fd, args);
    } else {
        // get state of hardware lock
        bool hardwareLocked = tryLock(mHardwareLock);
        if (!hardwareLocked) {
            String8 result(kHardwareLockedString);
            write(fd, result.string(), result.size());
        } else {
            mHardwareLock.unlock();
        }

        bool locked = tryLock(mLock);

        // failed to lock - AudioFlinger is probably deadlocked
        if (!locked) {
            String8 result(kDeadlockedString);
            write(fd, result.string(), result.size());
        }

        dumpClients(fd, args);
        dumpInternals(fd, args);
@@ -496,6 +514,14 @@ status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
        }
        LOGV("setOutput done\n");
    }
    // setRouting() is always called at least for mode == AudioSystem::MODE_IN_CALL when 
    // SCO is enabled, whatever current mode is so we can safely handle A2DP disabling only
    // in this case to avoid doing it several times.
    if (mode == AudioSystem::MODE_IN_CALL &&
        (mask & AudioSystem::ROUTE_BLUETOOTH_SCO)) {
        AutoMutex lock(&mLock);
        handleRouteDisablesA2dp_l(routes);
    }
#endif

    // do nothing if only A2DP routing is affected
@@ -672,8 +698,6 @@ status_t AudioFlinger::setStreamMute(int stream, bool muted)
        mHardwareMixerThread->setStreamMute(stream, muted);
    }

    

    return NO_ERROR;
}

@@ -837,12 +861,10 @@ void AudioFlinger::handleForcedSpeakerRoute(int command)
}

#ifdef WITH_A2DP
// handleStreamDisablesA2dp_l() must be called with AudioFlinger::mLock held
void AudioFlinger::handleStreamDisablesA2dp_l(int command)
{
    switch(command) {
    case ACTIVE_TRACK_ADDED:
// handleRouteDisablesA2dp_l() must be called with AudioFlinger::mLock held
void AudioFlinger::handleRouteDisablesA2dp_l(int routes)
{
   if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) {
        if (mA2dpDisableCount++ == 0) {
            if (mA2dpEnabled) {
                setA2dpEnabled_l(false);
@@ -850,10 +872,7 @@ void AudioFlinger::handleStreamDisablesA2dp_l(int command)
            }
        }
        LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
        }
        break;
    case ACTIVE_TRACK_REMOVED:
        {
   } else {
        if (mA2dpDisableCount > 0) {
            if (--mA2dpDisableCount == 0) {
                if (mA2dpSuppressed) {
@@ -866,8 +885,6 @@ void AudioFlinger::handleStreamDisablesA2dp_l(int command)
            LOGE("mA2dpDisableCount is already zero");
        }
    }
        break;
    }
}
#endif

@@ -1500,13 +1517,6 @@ void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
        if (streamForcedToSpeaker(track->type())) {
            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
        }        
#ifdef WITH_A2DP
        // AudioFlinger::mLock must be locked before calling
        // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
        if (streamDisablesA2dp(track->type())) {
            mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_ADDED);
        }
#endif
    }
}

@@ -1524,13 +1534,6 @@ void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
        if (streamForcedToSpeaker(track->type())) {
            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
        }
#ifdef WITH_A2DP
        // AudioFlinger::mLock must be locked before calling
        // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
        if (streamDisablesA2dp(track->type())) {
            mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_REMOVED);
        }
#endif
    }
}

@@ -1598,8 +1601,8 @@ AudioFlinger::MixerThread::TrackBase::TrackBase(
                new(mCblk) audio_track_cblk_t();
                // clear all buffers
                mCblk->frameCount = frameCount;
                mCblk->sampleRate = sampleRate;
                mCblk->channels = channelCount;
                mCblk->sampleRate = (uint16_t)sampleRate;
                mCblk->channels = (uint16_t)channelCount;
                if (sharedBuffer == 0) {
                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
@@ -1622,8 +1625,8 @@ AudioFlinger::MixerThread::TrackBase::TrackBase(
           new(mCblk) audio_track_cblk_t();
           // clear all buffers
           mCblk->frameCount = frameCount;
           mCblk->sampleRate = sampleRate;
           mCblk->channels = channelCount;
           mCblk->sampleRate = (uint16_t)sampleRate;
           mCblk->channels = (uint16_t)channelCount;
           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
           // Force underrun condition to avoid false underrun callback until first data is
@@ -1680,7 +1683,7 @@ sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
}

int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
    return mCblk->sampleRate;
    return (int)mCblk->sampleRate;
}

int AudioFlinger::MixerThread::TrackBase::channelCount() const {
@@ -1693,11 +1696,12 @@ void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t
    int16_t *bufferEnd = bufferStart + frames * cblk->channels;

    // Check validity of returned pointer in case the track control block would have been corrupted.
    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd) {
        LOGW("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
                server %d, serverBase %d, user %d, userBase %d",
    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd || 
            cblk->channels == 2 && ((unsigned long)bufferStart & 3) ) {
        LOGE("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
                server %d, serverBase %d, user %d, userBase %d, channels %d",
                bufferStart, bufferEnd, mBuffer, mBufferEnd,
                cblk->server, cblk->serverBase, cblk->user, cblk->userBase);
                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channels);
        return 0;
    }

@@ -1864,12 +1868,14 @@ void AudioFlinger::MixerThread::Track::flush()
    // STOPPED state
    mState = STOPPED;

    mCblk->lock.lock();
    // NOTE: reset() will reset cblk->user and cblk->server with
    // the risk that at the same time, the AudioMixer is trying to read
    // data. In this case, getNextBuffer() would return a NULL pointer
    // as audio buffer => the AudioMixer code MUST always test that pointer
    // returned by getNextBuffer() is not NULL!
    reset();
    mCblk->lock.unlock();
}

void AudioFlinger::MixerThread::Track::reset()
@@ -2478,19 +2484,6 @@ status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* record

    mRecordTrack = recordTrack;

#ifdef WITH_A2DP
    { // scope for lock2

        // AudioFlinger::mLock must be locked before calling
        // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
        AutoMutex lock2(&mAudioFlinger->mLock);

        // Currently there is no way to detect if we are recording over SCO,
        // so we disable A2DP during any recording.
        mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_ADDED);
    }
#endif

    // signal thread to start
    LOGV("Signal record thread");
    mWaitWorkCV.signal();
@@ -2503,18 +2496,6 @@ void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack
    LOGV("AudioRecordThread::stop");
    AutoMutex lock(&mLock);
    if (mActive && (recordTrack == mRecordTrack.get())) {
#ifdef WITH_A2DP
        { // scope for lock2
    
            // AudioFlinger::mLock must be locked before calling
            // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
            AutoMutex lock2(&mAudioFlinger->mLock);

            // Currently there is no way to detect if we are recording over SCO,
            // so we disable A2DP during any recording.
            mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_REMOVED);
        }
#endif
        mActive = false;
        mStopped.wait(mLock);
    }
+1 −2
Original line number Diff line number Diff line
@@ -165,7 +165,6 @@ private:
    void                    checkA2dpEnabledChange_l();
#endif
    static bool             streamForcedToSpeaker(int streamType);
    static bool             streamDisablesA2dp(int streamType);
    
    // Management of forced route to speaker for certain track types.
    enum force_speaker_command {
@@ -176,7 +175,7 @@ private:
    };
    void                    handleForcedSpeakerRoute(int command);
#ifdef WITH_A2DP
    void                    handleStreamDisablesA2dp_l(int command);
    void                    handleRouteDisablesA2dp_l(int routes);
#endif

    // Internal dump utilites.
+4 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
*/

#define LOG_TAG "AudioMixer"
//#define LOG_NDEBUG 0

#include <stdint.h>
#include <string.h>
@@ -780,8 +781,10 @@ void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, void*

        // in == NULL can happen if the track was flushed just after having
        // been enabled for mixing.
        if (in == NULL) {
        if (in == NULL || ((unsigned long)in & 3)) {
            memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
            LOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
                    in, i, t.channelCount, t.needs);
            return;
        }
        size_t outFrames = b.frameCount;