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

Commit 9ff80058 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change I60bed5d3 into eclair

* changes:
  Log for issue 2203561.
parents f29a0aa6 7f698b4c
Loading
Loading
Loading
Loading
+119 −0
Original line number Diff line number Diff line
@@ -459,6 +459,61 @@ status_t AudioPolicyManagerGeneric::getStreamVolumeIndex(AudioSystem::stream_typ
    return NO_ERROR;
}

status_t AudioPolicyManagerGeneric::dump(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
    result.append(buffer);
    snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
    result.append(buffer);
    snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
    result.append(buffer);
    snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
    result.append(buffer);
    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
    result.append(buffer);
    snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
    result.append(buffer);
    snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
    result.append(buffer);
    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
    result.append(buffer);
    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
    result.append(buffer);
    write(fd, result.string(), result.size());

    snprintf(buffer, SIZE, "\nOutputs dump:\n");
    write(fd, buffer, strlen(buffer));
    for (size_t i = 0; i < mOutputs.size(); i++) {
        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
        write(fd, buffer, strlen(buffer));
        mOutputs.valueAt(i)->dump(fd);
    }

    snprintf(buffer, SIZE, "\nInputs dump:\n");
    write(fd, buffer, strlen(buffer));
    for (size_t i = 0; i < mInputs.size(); i++) {
        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
        write(fd, buffer, strlen(buffer));
        mInputs.valueAt(i)->dump(fd);
    }

    snprintf(buffer, SIZE, "\nStreams dump:\n");
    write(fd, buffer, strlen(buffer));
    snprintf(buffer, SIZE, " Stream  Index Min  Index Max  Index Cur  Mute Count  Can be muted\n");
    write(fd, buffer, strlen(buffer));
    for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
        snprintf(buffer, SIZE, " %02d", i);
        mStreams[i].dump(buffer + 3, SIZE);
        write(fd, buffer, strlen(buffer));
    }

    return NO_ERROR;
}

// ----------------------------------------------------------------------------
// AudioPolicyManagerGeneric
// ----------------------------------------------------------------------------
@@ -815,6 +870,35 @@ uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::refCount()
    return refcount;
}

status_t AudioPolicyManagerGeneric::AudioOutputDescriptor::dump(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
    result.append(buffer);
    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
    result.append(buffer);
    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
    result.append(buffer);
    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
    result.append(buffer);
    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
    result.append(buffer);
    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
    result.append(buffer);
    snprintf(buffer, SIZE, " Stream refCount\n");
    result.append(buffer);
    for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
        snprintf(buffer, SIZE, " %02d     %d\n", i, mRefCount[i]);
        result.append(buffer);
    }
    write(fd, result.string(), result.size());

    return NO_ERROR;
}

// --- AudioInputDescriptor class implementation

AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
@@ -823,4 +907,39 @@ AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
{
}

status_t AudioPolicyManagerGeneric::AudioInputDescriptor::dump(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
    result.append(buffer);
    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
    result.append(buffer);
    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
    result.append(buffer);
    snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
    result.append(buffer);
    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
    result.append(buffer);
    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
    result.append(buffer);
    write(fd, result.string(), result.size());

    return NO_ERROR;
}

// --- StreamDescriptor class implementation

void AudioPolicyManagerGeneric::StreamDescriptor::dump(char* buffer, size_t size)
{
    snprintf(buffer, size, "      %02d         %02d         %02d         %02d          %d\n",
            mIndexMin,
            mIndexMax,
            mIndexCur,
            mMuteCount,
            mCanBeMuted);
}

}; // namespace android
+7 −0
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ public:
        virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
        virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);

        virtual status_t dump(int fd);

private:

        enum routing_strategy {
@@ -93,6 +95,7 @@ private:
        public:
            AudioOutputDescriptor();

            status_t    dump(int fd);

            uint32_t device();
            void changeRefCount(AudioSystem::stream_type, int delta);
@@ -115,6 +118,8 @@ private:
        public:
            AudioInputDescriptor();

            status_t    dump(int fd);

            uint32_t mSamplingRate;                     //
            uint32_t mFormat;                           // input configuration
            uint32_t mChannels;                         //
@@ -130,6 +135,8 @@ private:
            StreamDescriptor()
            :   mIndexMin(0), mIndexMax(1), mIndexCur(1), mMuteCount(0), mCanBeMuted(true) {}

            void dump(char* buffer, size_t size);

            int mIndexMin;      // min volume index
            int mIndexMax;      // max volume index
            int mIndexCur;      // current volume index
+97 −2
Original line number Diff line number Diff line
@@ -43,6 +43,12 @@

namespace android {

static const char* kDeadlockedString = "AudioPolicyService may be deadlocked\n";
static const char* kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";

static const int kDumpLockRetries = 50;
static const int kDumpLockSleep = 20000;

static bool checkPermission() {
#ifndef HAVE_ANDROID_OS
    return true;
@@ -335,17 +341,65 @@ void AudioPolicyService::binderDied(const wp<IBinder>& who) {
    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
}

static bool tryLock(Mutex& mutex)
{
    bool locked = false;
    for (int i = 0; i < kDumpLockRetries; ++i) {
        if (mutex.tryLock() == NO_ERROR) {
            locked = true;
            break;
        }
        usleep(kDumpLockSleep);
    }
    return locked;
}

status_t AudioPolicyService::dumpInternals(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
    result.append(buffer);
    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
    result.append(buffer);
    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
    result.append(buffer);

    write(fd, result.string(), result.size());
    return NO_ERROR;
}

status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
{
    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
        dumpPermissionDenial(fd, args);
        dumpPermissionDenial(fd);
    } else {
        bool locked = tryLock(mLock);
        if (!locked) {
            String8 result(kDeadlockedString);
            write(fd, result.string(), result.size());
        }

        dumpInternals(fd);
        if (mAudioCommandThread != NULL) {
            mAudioCommandThread->dump(fd);
        }
        if (mTonePlaybackThread != NULL) {
            mTonePlaybackThread->dump(fd);
        }

        if (mpPolicyManager) {
            mpPolicyManager->dump(fd);
        }

        if (locked) mLock.unlock();
    }
    return NO_ERROR;
}

status_t AudioPolicyService::dumpPermissionDenial(int fd, const Vector<String16>& args)
status_t AudioPolicyService::dumpPermissionDenial(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
@@ -609,6 +663,36 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
    return false;
}

status_t AudioPolicyService::AudioCommandThread::dump(int fd)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;

    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
    result.append(buffer);
    write(fd, result.string(), result.size());

    bool locked = tryLock(mLock);
    if (!locked) {
        String8 result2(kCmdDeadlockedString);
        write(fd, result2.string(), result2.size());
    }

    snprintf(buffer, SIZE, "- Commands:\n");
    result = String8(buffer);
    result.append("   Command Time        Status  Wait pParam\n");
    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
        mAudioCommands[i]->dump(buffer, SIZE);
        result.append(buffer);
    }
    write(fd, result.string(), result.size());

    if (locked) mLock.unlock();

    return NO_ERROR;
}

void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
{
    AudioCommand *command = new AudioCommand();
@@ -808,4 +892,15 @@ void AudioPolicyService::AudioCommandThread::exit()
    requestExitAndWait();
}

void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
{
    snprintf(buffer, size, "   %02d      %06d.%03d  %03d     %01u    %p\n",
            mCommand,
            (int)ns2s(mTime),
            (int)ns2ms(mTime)%1000,
            mStatus,
            mWaitStatus,
            mParam);
}

}; // namespace android
+7 −1
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ private:
                        AudioPolicyService();
    virtual             ~AudioPolicyService();

            status_t dumpInternals(int fd);

    // Thread used for tone playback and to send audio config commands to audio flinger
    // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone()
    // and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause
@@ -133,6 +135,8 @@ private:
        AudioCommandThread ();
        virtual             ~AudioCommandThread();

                    status_t    dump(int fd);

        // Thread virtuals
        virtual     void        onFirstRef();
        virtual     bool        threadLoop();
@@ -149,6 +153,8 @@ private:
        // descriptor for requested tone playback event
        class AudioCommand {
        public:
            void dump(char* buffer, size_t size);

            int mCommand;   // START_TONE, STOP_TONE ...
            nsecs_t mTime;  // time stamp
            Condition mCond; // condition for status return
@@ -188,7 +194,7 @@ private:
    };

    // Internal dump utilities.
    status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
    status_t dumpPermissionDenial(int fd);


    Mutex   mLock;      // prevents concurrent access to AudioPolicy manager functions changing device