OSDN Git Service

resolved conflicts for merge of f285c91e to master
authorElliott Hughes <enh@google.com>
Thu, 22 May 2014 17:14:43 +0000 (10:14 -0700)
committerElliott Hughes <enh@google.com>
Thu, 22 May 2014 17:14:43 +0000 (10:14 -0700)
Change-Id: I4c995e297d09c0854a42142cc57dce8b771acf65

1  2 
camera/VendorTagDescriptor.cpp
media/libnbaio/NBLog.cpp
services/audioflinger/AudioFlinger.cpp
services/audioflinger/FastMixer.cpp
services/audioflinger/Threads.cpp
services/medialog/MediaLogService.cpp

index 59dce91,0000000..3f72f34
mode 100644,000000..100644
--- /dev/null
@@@ -1,458 -1,0 +1,458 @@@
-         fdprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
 +/*
 + * Copyright (C) 2014 The Android Open Source Project
 + *
 + * Licensed under the Apache License, Version 2.0 (the "License");
 + * you may not use this file except in compliance with the License.
 + * You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +#define LOG_TAG "VendorTagDescriptor"
 +
 +#include <binder/Parcel.h>
 +#include <utils/Errors.h>
 +#include <utils/Log.h>
 +#include <utils/Mutex.h>
 +#include <utils/Vector.h>
 +#include <utils/SortedVector.h>
 +#include <system/camera_metadata.h>
 +#include <camera_metadata_hidden.h>
 +
 +#include "camera/VendorTagDescriptor.h"
 +
 +#include <stdio.h>
 +#include <string.h>
 +
 +namespace android {
 +
 +extern "C" {
 +
 +static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
 +static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
 +static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
 +static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
 +static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
 +
 +} /* extern "C" */
 +
 +
 +static Mutex sLock;
 +static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
 +
 +VendorTagDescriptor::VendorTagDescriptor() {}
 +
 +VendorTagDescriptor::~VendorTagDescriptor() {
 +    size_t len = mReverseMapping.size();
 +    for (size_t i = 0; i < len; ++i)  {
 +        delete mReverseMapping[i];
 +    }
 +}
 +
 +status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
 +            /*out*/
 +            sp<VendorTagDescriptor>& descriptor) {
 +    if (vOps == NULL) {
 +        ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
 +        return BAD_VALUE;
 +    }
 +
 +    int tagCount = vOps->get_tag_count(vOps);
 +    if (tagCount < 0 || tagCount > INT32_MAX) {
 +        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
 +        return BAD_VALUE;
 +    }
 +
 +    Vector<uint32_t> tagArray;
 +    LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
 +            "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
 +
 +    vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
 +
 +    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
 +    desc->mTagCount = tagCount;
 +
 +    SortedVector<String8> sections;
 +    KeyedVector<uint32_t, String8> tagToSectionMap;
 +
 +    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
 +        uint32_t tag = tagArray[i];
 +        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
 +            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
 +            return BAD_VALUE;
 +        }
 +        const char *tagName = vOps->get_tag_name(vOps, tag);
 +        if (tagName == NULL) {
 +            ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
 +            return BAD_VALUE;
 +        }
 +        desc->mTagToNameMap.add(tag, String8(tagName));
 +        const char *sectionName = vOps->get_section_name(vOps, tag);
 +        if (sectionName == NULL) {
 +            ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
 +            return BAD_VALUE;
 +        }
 +
 +        String8 sectionString(sectionName);
 +
 +        sections.add(sectionString);
 +        tagToSectionMap.add(tag, sectionString);
 +
 +        int tagType = vOps->get_tag_type(vOps, tag);
 +        if (tagType < 0 || tagType >= NUM_TYPES) {
 +            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
 +            return BAD_VALUE;
 +        }
 +        desc->mTagToTypeMap.add(tag, tagType);
 +    }
 +
 +    desc->mSections = sections;
 +
 +    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
 +        uint32_t tag = tagArray[i];
 +        String8 sectionString = tagToSectionMap.valueFor(tag);
 +
 +        // Set up tag to section index map
 +        ssize_t index = sections.indexOf(sectionString);
 +        LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
 +        desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
 +
 +        // Set up reverse mapping
 +        ssize_t reverseIndex = -1;
 +        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
 +            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
 +            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
 +        }
 +        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
 +    }
 +
 +    descriptor = desc;
 +    return OK;
 +}
 +
 +status_t VendorTagDescriptor::createFromParcel(const Parcel* parcel,
 +            /*out*/
 +            sp<VendorTagDescriptor>& descriptor) {
 +    status_t res = OK;
 +    if (parcel == NULL) {
 +        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
 +        return BAD_VALUE;
 +    }
 +
 +    int32_t tagCount = 0;
 +    if ((res = parcel->readInt32(&tagCount)) != OK) {
 +        ALOGE("%s: could not read tag count from parcel", __FUNCTION__);
 +        return res;
 +    }
 +
 +    if (tagCount < 0 || tagCount > INT32_MAX) {
 +        ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
 +        return BAD_VALUE;
 +    }
 +
 +    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
 +    desc->mTagCount = tagCount;
 +
 +    uint32_t tag, sectionIndex;
 +    uint32_t maxSectionIndex = 0;
 +    int32_t tagType;
 +    Vector<uint32_t> allTags;
 +    for (int32_t i = 0; i < tagCount; ++i) {
 +        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&tag))) != OK) {
 +            ALOGE("%s: could not read tag id from parcel for index %d", __FUNCTION__, i);
 +            break;
 +        }
 +        if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
 +            ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
 +            res = BAD_VALUE;
 +            break;
 +        }
 +        if ((res = parcel->readInt32(&tagType)) != OK) {
 +            ALOGE("%s: could not read tag type from parcel for tag %d", __FUNCTION__, tag);
 +            break;
 +        }
 +        if (tagType < 0 || tagType >= NUM_TYPES) {
 +            ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
 +            res = BAD_VALUE;
 +            break;
 +        }
 +        String8 tagName = parcel->readString8();
 +        if (tagName.isEmpty()) {
 +            ALOGE("%s: parcel tag name was NULL for tag %d.", __FUNCTION__, tag);
 +            res = NOT_ENOUGH_DATA;
 +            break;
 +        }
 +
 +        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionIndex))) != OK) {
 +            ALOGE("%s: could not read section index for tag %d.", __FUNCTION__, tag);
 +            break;
 +        }
 +
 +        maxSectionIndex = (maxSectionIndex >= sectionIndex) ? maxSectionIndex : sectionIndex;
 +
 +        allTags.add(tag);
 +        desc->mTagToNameMap.add(tag, tagName);
 +        desc->mTagToSectionMap.add(tag, sectionIndex);
 +        desc->mTagToTypeMap.add(tag, tagType);
 +    }
 +
 +    if (res != OK) {
 +        return res;
 +    }
 +
 +    size_t sectionCount;
 +    if (tagCount > 0) {
 +        if ((res = parcel->readInt32(reinterpret_cast<int32_t*>(&sectionCount))) != OK) {
 +            ALOGE("%s: could not read section count for.", __FUNCTION__);
 +            return res;
 +        }
 +        if (sectionCount < (maxSectionIndex + 1)) {
 +            ALOGE("%s: Incorrect number of sections defined, received %d, needs %d.",
 +                    __FUNCTION__, sectionCount, (maxSectionIndex + 1));
 +            return BAD_VALUE;
 +        }
 +        LOG_ALWAYS_FATAL_IF(desc->mSections.setCapacity(sectionCount) <= 0,
 +                "Vector capacity must be positive");
 +        for (size_t i = 0; i < sectionCount; ++i) {
 +            String8 sectionName = parcel->readString8();
 +            if (sectionName.isEmpty()) {
 +                ALOGE("%s: parcel section name was NULL for section %d.", __FUNCTION__, i);
 +                return NOT_ENOUGH_DATA;
 +            }
 +            desc->mSections.add(sectionName);
 +        }
 +    }
 +
 +    LOG_ALWAYS_FATAL_IF(tagCount != allTags.size(), "tagCount must be the same as allTags size");
 +    // Set up reverse mapping
 +    for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
 +        uint32_t tag = allTags[i];
 +        String8 sectionString = desc->mSections[desc->mTagToSectionMap.valueFor(tag)];
 +
 +        ssize_t reverseIndex = -1;
 +        if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
 +            KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
 +            reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
 +        }
 +        desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
 +    }
 +
 +    descriptor = desc;
 +    return res;
 +}
 +
 +int VendorTagDescriptor::getTagCount() const {
 +    size_t size = mTagToNameMap.size();
 +    if (size == 0) {
 +        return VENDOR_TAG_COUNT_ERR;
 +    }
 +    return size;
 +}
 +
 +void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
 +    size_t size = mTagToNameMap.size();
 +    for (size_t i = 0; i < size; ++i) {
 +        tagArray[i] = mTagToNameMap.keyAt(i);
 +    }
 +}
 +
 +const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
 +    ssize_t index = mTagToSectionMap.indexOfKey(tag);
 +    if (index < 0) {
 +        return VENDOR_SECTION_NAME_ERR;
 +    }
 +    return mSections[mTagToSectionMap.valueAt(index)].string();
 +}
 +
 +const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
 +    ssize_t index = mTagToNameMap.indexOfKey(tag);
 +    if (index < 0) {
 +        return VENDOR_TAG_NAME_ERR;
 +    }
 +    return mTagToNameMap.valueAt(index).string();
 +}
 +
 +int VendorTagDescriptor::getTagType(uint32_t tag) const {
 +    ssize_t index = mTagToNameMap.indexOfKey(tag);
 +    if (index < 0) {
 +        return VENDOR_TAG_TYPE_ERR;
 +    }
 +    return mTagToTypeMap.valueFor(tag);
 +}
 +
 +status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const {
 +    status_t res = OK;
 +    if (parcel == NULL) {
 +        ALOGE("%s: parcel argument was NULL.", __FUNCTION__);
 +        return BAD_VALUE;
 +    }
 +
 +    if ((res = parcel->writeInt32(mTagCount)) != OK) {
 +        return res;
 +    }
 +
 +    size_t size = mTagToNameMap.size();
 +    uint32_t tag, sectionIndex;
 +    int32_t tagType;
 +    for (size_t i = 0; i < size; ++i) {
 +        tag = mTagToNameMap.keyAt(i);
 +        String8 tagName = mTagToNameMap[i];
 +        sectionIndex = mTagToSectionMap.valueFor(tag);
 +        tagType = mTagToTypeMap.valueFor(tag);
 +        if ((res = parcel->writeInt32(tag)) != OK) break;
 +        if ((res = parcel->writeInt32(tagType)) != OK) break;
 +        if ((res = parcel->writeString8(tagName)) != OK) break;
 +        if ((res = parcel->writeInt32(sectionIndex)) != OK) break;
 +    }
 +
 +    size_t numSections = mSections.size();
 +    if (numSections > 0) {
 +        if ((res = parcel->writeInt32(numSections)) != OK) return res;
 +        for (size_t i = 0; i < numSections; ++i) {
 +            if ((res = parcel->writeString8(mSections[i])) != OK) return res;
 +        }
 +    }
 +
 +    return res;
 +}
 +
 +SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
 +    return mSections;
 +}
 +
 +status_t VendorTagDescriptor::lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const {
 +    ssize_t index = mReverseMapping.indexOfKey(section);
 +    if (index < 0) {
 +        ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
 +        return BAD_VALUE;
 +    }
 +
 +    ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
 +    if (nameIndex < 0) {
 +        ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
 +        return BAD_VALUE;
 +    }
 +
 +    if (tag != NULL) {
 +        *tag = mReverseMapping[index]->valueAt(nameIndex);
 +    }
 +    return OK;
 +}
 +
 +void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
 +
 +    size_t size = mTagToNameMap.size();
 +    if (size == 0) {
-     fdprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
++        dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
 +                indentation, "");
 +        return;
 +    }
 +
-             fdprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
++    dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
 +            indentation, "", size);
 +    for (size_t i = 0; i < size; ++i) {
 +        uint32_t tag =  mTagToNameMap.keyAt(i);
 +
 +        if (verbosity < 1) {
-         fdprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
++            dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
 +            continue;
 +        }
 +        String8 name = mTagToNameMap.valueAt(i);
 +        uint32_t sectionId = mTagToSectionMap.valueFor(tag);
 +        String8 sectionName = mSections[sectionId];
 +        int type = mTagToTypeMap.valueFor(tag);
 +        const char* typeName = (type >= 0 && type < NUM_TYPES) ?
 +                camera_metadata_type_names[type] : "UNKNOWN";
++        dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
 +            "", tag, name.string(), type, typeName, sectionName.string());
 +    }
 +
 +}
 +
 +status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
 +    status_t res = OK;
 +    Mutex::Autolock al(sLock);
 +    sGlobalVendorTagDescriptor = desc;
 +
 +    vendor_tag_ops_t* opsPtr = NULL;
 +    if (desc != NULL) {
 +        opsPtr = &(desc->mVendorOps);
 +        opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
 +        opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
 +        opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
 +        opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
 +        opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
 +    }
 +    if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
 +        ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
 +                , __FUNCTION__, strerror(-res), res);
 +    }
 +    return res;
 +}
 +
 +void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
 +    Mutex::Autolock al(sLock);
 +    set_camera_metadata_vendor_ops(NULL);
 +    sGlobalVendorTagDescriptor.clear();
 +}
 +
 +sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
 +    Mutex::Autolock al(sLock);
 +    return sGlobalVendorTagDescriptor;
 +}
 +
 +extern "C" {
 +
 +int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v) {
 +    Mutex::Autolock al(sLock);
 +    if (sGlobalVendorTagDescriptor == NULL) {
 +        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
 +        return VENDOR_TAG_COUNT_ERR;
 +    }
 +    return sGlobalVendorTagDescriptor->getTagCount();
 +}
 +
 +void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray) {
 +    Mutex::Autolock al(sLock);
 +    if (sGlobalVendorTagDescriptor == NULL) {
 +        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
 +        return;
 +    }
 +    sGlobalVendorTagDescriptor->getTagArray(tagArray);
 +}
 +
 +const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag) {
 +    Mutex::Autolock al(sLock);
 +    if (sGlobalVendorTagDescriptor == NULL) {
 +        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
 +        return VENDOR_SECTION_NAME_ERR;
 +    }
 +    return sGlobalVendorTagDescriptor->getSectionName(tag);
 +}
 +
 +const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag) {
 +    Mutex::Autolock al(sLock);
 +    if (sGlobalVendorTagDescriptor == NULL) {
 +        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
 +        return VENDOR_TAG_NAME_ERR;
 +    }
 +    return sGlobalVendorTagDescriptor->getTagName(tag);
 +}
 +
 +int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag) {
 +    Mutex::Autolock al(sLock);
 +    if (sGlobalVendorTagDescriptor == NULL) {
 +        ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
 +        return VENDOR_TAG_TYPE_ERR;
 +    }
 +    return sGlobalVendorTagDescriptor->getTagType(tag);
 +}
 +
 +} /* extern "C" */
 +} /* namespace android */
Simple merge
@@@ -461,7 -695,7 +461,7 @@@ static int compare_uint32_t(const void 
  void FastMixerDumpState::dump(int fd) const
  {
      if (mCommand == FastMixerState::INITIAL) {
-         fdprintf(fd, "  FastMixer not initialized\n");
 -        dprintf(fd, "FastMixer not initialized\n");
++        dprintf(fd, "  FastMixer not initialized\n");
          return;
      }
  #define COMMAND_MAX 32
      double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
              (mMeasuredWarmupTs.tv_nsec / 1000000.0);
      double mixPeriodSec = (double) mFrameCount / (double) mSampleRate;
-     fdprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
-                  "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
-                  "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
-                  "            mixPeriod=%.2f ms\n",
 -    dprintf(fd, "FastMixer command=%s writeSequence=%u framesWritten=%u\n"
 -                 "          numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
 -                 "          sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
 -                 "          mixPeriod=%.2f ms\n",
++    dprintf(fd, "  FastMixer command=%s writeSequence=%u framesWritten=%u\n"
++                "            numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
++                "            sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
++                "            mixPeriod=%.2f ms\n",
                   string, mWriteSequence, mFramesWritten,
                   mNumTracks, mWriteErrors, mUnderruns, mOverruns,
                   mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
          previousCpukHz = sampleCpukHz;
  #endif
      }
 -    dprintf(fd, "Simple moving statistics over last %.1f seconds:\n", wall.n() * mixPeriodSec);
 -    dprintf(fd, "  wall clock time in ms per mix cycle:\n"
 -                "    mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
 -                wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6, wall.stddev()*1e-6);
 -    dprintf(fd, "  raw CPU load in us per mix cycle:\n"
 -                "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
 -                loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
 -                loadNs.stddev()*1e-3);
 +    if (n) {
-         fdprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
-                      wall.n() * mixPeriodSec);
-         fdprintf(fd, "    wall clock time in ms per mix cycle:\n"
-                      "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                      wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
-                      wall.stddev()*1e-6);
-         fdprintf(fd, "    raw CPU load in us per mix cycle:\n"
-                      "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                      loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
-                      loadNs.stddev()*1e-3);
++        dprintf(fd, "  Simple moving statistics over last %.1f seconds:\n",
++                    wall.n() * mixPeriodSec);
++        dprintf(fd, "    wall clock time in ms per mix cycle:\n"
++                    "      mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
++                    wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6,
++                    wall.stddev()*1e-6);
++        dprintf(fd, "    raw CPU load in us per mix cycle:\n"
++                    "      mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
++                    loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
++                    loadNs.stddev()*1e-3);
 +    } else {
-         fdprintf(fd, "  No FastMixer statistics available currently\n");
++        dprintf(fd, "  No FastMixer statistics available currently\n");
 +    }
  #ifdef CPU_FREQUENCY_STATISTICS
-     fdprintf(fd, "  CPU clock frequency in MHz:\n"
-                  "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
-                  kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
-     fdprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
-                  "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
-                  loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
+     dprintf(fd, "  CPU clock frequency in MHz:\n"
+                 "    mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+                 kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
+     dprintf(fd, "  adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
+                 "    mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
+                 loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
  #endif
      if (tail != NULL) {
          qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
              left.sample(tail[i]);
              right.sample(tail[n - (i + 1)]);
          }
-         fdprintf(fd, "  Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
-                      "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
-                      "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
-                      left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
-                      right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
-                      right.stddev()*1e-6);
 -        dprintf(fd, "Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
 -                    "  left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
 -                    "  right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
++        dprintf(fd, "  Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
++                    "    left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
++                    "    right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+                     left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
+                     right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
+                     right.stddev()*1e-6);
          delete[] tail;
      }
  #endif
      // Instead we always display all tracks, with an indication
      // of whether we think the track is active.
      uint32_t trackMask = mTrackMask;
-     fdprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
 -    dprintf(fd, "Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
++    dprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
              FastMixerState::kMaxFastTracks, trackMask);
-     fdprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
 -    dprintf(fd, "Index Active Full Partial Empty  Recent Ready\n");
++    dprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
      for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
          bool isActive = trackMask & 1;
          const FastTrackDump *ftDump = &mTracks[i];
              mostRecent = "?";
              break;
          }
-         fdprintf(fd, "  %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
 -        dprintf(fd, "%5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
++        dprintf(fd, "  %5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
                  (underruns.mBitFields.mFull) & UNDERRUN_MASK,
                  (underruns.mBitFields.mPartial) & UNDERRUN_MASK,
                  (underruns.mBitFields.mEmpty) & UNDERRUN_MASK,
@@@ -505,31 -413,47 +505,31 @@@ void AudioFlinger::ThreadBase::dumpBase
  
      bool locked = AudioFlinger::dumpTryLock(mLock);
      if (!locked) {
-         fdprintf(fd, "thread %p maybe dead locked\n", this);
 -        snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this);
 -        write(fd, buffer, strlen(buffer));
 -    }
 -
 -    snprintf(buffer, SIZE, "io handle: %d\n", mId);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "TID: %d\n", getTid());
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "Sample rate: %u\n", mSampleRate);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "HAL frame count: %zu\n", mFrameCount);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "Channel Count: %u\n", mChannelCount);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "Channel Mask: 0x%08x\n", mChannelMask);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "Format: %d\n", mFormat);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "Frame size: %zu\n", mFrameSize);
 -    result.append(buffer);
 -
 -    snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
 -    result.append(buffer);
 -    result.append(" Index Command");
 -    for (size_t i = 0; i < mNewParameters.size(); ++i) {
 -        snprintf(buffer, SIZE, "\n %02zu    ", i);
 -        result.append(buffer);
 -        result.append(mNewParameters[i]);
 -    }
 -
 -    snprintf(buffer, SIZE, "\n\nPending config events: \n");
 -    result.append(buffer);
 -    for (size_t i = 0; i < mConfigEvents.size(); i++) {
 -        mConfigEvents[i]->dump(buffer, SIZE);
 -        result.append(buffer);
++        dprintf(fd, "thread %p maybe dead locked\n", this);
 +    }
 +
-     fdprintf(fd, "  I/O handle: %d\n", mId);
-     fdprintf(fd, "  TID: %d\n", getTid());
-     fdprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
-     fdprintf(fd, "  Sample rate: %u\n", mSampleRate);
-     fdprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
-     fdprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
-     fdprintf(fd, "  Channel Count: %u\n", mChannelCount);
-     fdprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
++    dprintf(fd, "  I/O handle: %d\n", mId);
++    dprintf(fd, "  TID: %d\n", getTid());
++    dprintf(fd, "  Standby: %s\n", mStandby ? "yes" : "no");
++    dprintf(fd, "  Sample rate: %u\n", mSampleRate);
++    dprintf(fd, "  HAL frame count: %zu\n", mFrameCount);
++    dprintf(fd, "  HAL buffer size: %u bytes\n", mBufferSize);
++    dprintf(fd, "  Channel Count: %u\n", mChannelCount);
++    dprintf(fd, "  Channel Mask: 0x%08x (%s)\n", mChannelMask,
 +            channelMaskToString(mChannelMask, mType != RECORD).string());
-     fdprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
-     fdprintf(fd, "  Frame size: %zu\n", mFrameSize);
-     fdprintf(fd, "  Pending config events:");
++    dprintf(fd, "  Format: 0x%x (%s)\n", mFormat, formatToString(mFormat));
++    dprintf(fd, "  Frame size: %zu\n", mFrameSize);
++    dprintf(fd, "  Pending config events:");
 +    size_t numConfig = mConfigEvents.size();
 +    if (numConfig) {
 +        for (size_t i = 0; i < numConfig; i++) {
 +            mConfigEvents[i]->dump(buffer, SIZE);
-             fdprintf(fd, "\n    %s", buffer);
++            dprintf(fd, "\n    %s", buffer);
 +        }
-         fdprintf(fd, "\n");
++        dprintf(fd, "\n");
 +    } else {
-         fdprintf(fd, " none\n");
++        dprintf(fd, " none\n");
      }
 -    result.append("\n");
 -
 -    write(fd, result.string(), result.size());
  
      if (locked) {
          mLock.unlock();
@@@ -1189,64 -1091,60 +1189,63 @@@ void AudioFlinger::PlaybackThread::dump
      write(fd, result.string(), result.length());
      result.clear();
  
 -    snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
 -    result.append(buffer);
 -    Track::appendDumpHeader(result);
 -    for (size_t i = 0; i < mTracks.size(); ++i) {
 -        sp<Track> track = mTracks[i];
 -        if (track != 0) {
 -            track->dump(buffer, SIZE);
 -            result.append(buffer);
 +    // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
 +    FastTrackUnderruns underruns = getFastTrackUnderruns(0);
-     fdprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
++    dprintf(fd, "  Normal mixer raw underrun counters: partial=%u empty=%u\n",
 +            underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
 +
 +    size_t numtracks = mTracks.size();
 +    size_t numactive = mActiveTracks.size();
-     fdprintf(fd, "  %d Tracks", numtracks);
++    dprintf(fd, "  %d Tracks", numtracks);
 +    size_t numactiveseen = 0;
 +    if (numtracks) {
-         fdprintf(fd, " of which %d are active\n", numactive);
++        dprintf(fd, " of which %d are active\n", numactive);
 +        Track::appendDumpHeader(result);
 +        for (size_t i = 0; i < numtracks; ++i) {
 +            sp<Track> track = mTracks[i];
 +            if (track != 0) {
 +                bool active = mActiveTracks.indexOf(track) >= 0;
 +                if (active) {
 +                    numactiveseen++;
 +                }
 +                track->dump(buffer, SIZE, active);
 +                result.append(buffer);
 +            }
          }
 +    } else {
 +        result.append("\n");
      }
 -
 -    snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
 -    result.append(buffer);
 -    Track::appendDumpHeader(result);
 -    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
 -        sp<Track> track = mActiveTracks[i].promote();
 -        if (track != 0) {
 -            track->dump(buffer, SIZE);
 -            result.append(buffer);
 +    if (numactiveseen != numactive) {
 +        // some tracks in the active list were not in the tracks list
 +        snprintf(buffer, SIZE, "  The following tracks are in the active list but"
 +                " not in the track list\n");
 +        result.append(buffer);
 +        Track::appendDumpHeader(result);
 +        for (size_t i = 0; i < numactive; ++i) {
 +            sp<Track> track = mActiveTracks[i].promote();
 +            if (track != 0 && mTracks.indexOf(track) < 0) {
 +                track->dump(buffer, SIZE, true);
 +                result.append(buffer);
 +            }
          }
      }
 -    write(fd, result.string(), result.size());
  
 -    // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
 -    FastTrackUnderruns underruns = getFastTrackUnderruns(0);
 -    dprintf(fd, "Normal mixer raw underrun counters: partial=%u empty=%u\n",
 -            underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
 +    write(fd, result.string(), result.size());
  }
  
  void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
  {
-     fdprintf(fd, "\nOutput thread %p:\n", this);
-     fdprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
-     fdprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
-     fdprintf(fd, "  Total writes: %d\n", mNumWrites);
-     fdprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
-     fdprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
-     fdprintf(fd, "  Suspend count: %d\n", mSuspended);
-     fdprintf(fd, "  Sink buffer : %p\n", mSinkBuffer);
-     fdprintf(fd, "  Mixer buffer: %p\n", mMixerBuffer);
-     fdprintf(fd, "  Effect buffer: %p\n", mEffectBuffer);
-     fdprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
 -    const size_t SIZE = 256;
 -    char buffer[SIZE];
 -    String8 result;
 -
 -    snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "Normal frame count: %zu\n", mNormalFrameCount);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n",
 -            ns2ms(systemTime() - mLastWriteTime));
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "suspend count: %d\n", mSuspended);
 -    result.append(buffer);
 -    snprintf(buffer, SIZE, "mix buffer : %p\n", mMixBuffer);
 -    result.append(buffer);
 -    write(fd, result.string(), result.size());
 -    dprintf(fd, "Fast track availMask=%#x\n", mFastTrackAvailMask);
++    dprintf(fd, "\nOutput thread %p:\n", this);
++    dprintf(fd, "  Normal frame count: %zu\n", mNormalFrameCount);
++    dprintf(fd, "  Last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
++    dprintf(fd, "  Total writes: %d\n", mNumWrites);
++    dprintf(fd, "  Delayed writes: %d\n", mNumDelayedWrites);
++    dprintf(fd, "  Blocked in write: %s\n", mInWrite ? "yes" : "no");
++    dprintf(fd, "  Suspend count: %d\n", mSuspended);
++    dprintf(fd, "  Sink buffer : %p\n", mSinkBuffer);
++    dprintf(fd, "  Mixer buffer: %p\n", mMixerBuffer);
++    dprintf(fd, "  Effect buffer: %p\n", mEffectBuffer);
++    dprintf(fd, "  Fast track availMask=%#x\n", mFastTrackAvailMask);
  
      dumpBase(fd, args);
  }
@@@ -3673,7 -3468,9 +3672,7 @@@ void AudioFlinger::MixerThread::dumpInt
  
      PlaybackThread::dumpInternals(fd, args);
  
-     fdprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
 -    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
 -    result.append(buffer);
 -    write(fd, result.string(), result.size());
++    dprintf(fd, "  AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames());
  
      // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
      const FastMixerDumpState copy(mFastMixerDumpState);
@@@ -5360,14 -4955,30 +5359,14 @@@ void AudioFlinger::RecordThread::dump(i
  
  void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
  {
-     fdprintf(fd, "\nInput thread %p:\n", this);
 -    const size_t SIZE = 256;
 -    char buffer[SIZE];
 -    String8 result;
 -
 -    snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
 -    result.append(buffer);
++    dprintf(fd, "\nInput thread %p:\n", this);
  
 -    if (mActiveTrack != 0) {
 -        snprintf(buffer, SIZE, "In index: %zu\n", mRsmpInIndex);
 -        result.append(buffer);
 -        snprintf(buffer, SIZE, "Buffer size: %zu bytes\n", mBufferSize);
 -        result.append(buffer);
 -        snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != NULL));
 -        result.append(buffer);
 -        snprintf(buffer, SIZE, "Out channel count: %u\n", mReqChannelCount);
 -        result.append(buffer);
 -        snprintf(buffer, SIZE, "Out sample rate: %u\n", mReqSampleRate);
 -        result.append(buffer);
 +    if (mActiveTracks.size() > 0) {
-         fdprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
++        dprintf(fd, "  Buffer size: %zu bytes\n", mBufferSize);
      } else {
-         fdprintf(fd, "  No active record clients\n");
 -        result.append("No active record client\n");
++        dprintf(fd, "  No active record clients\n");
      }
  
 -    write(fd, result.string(), result.size());
 -
      dumpBase(fd, args);
  }
  
@@@ -5377,40 -4988,23 +5376,40 @@@ void AudioFlinger::RecordThread::dumpTr
      char buffer[SIZE];
      String8 result;
  
 -    snprintf(buffer, SIZE, "Input thread %p tracks\n", this);
 -    result.append(buffer);
 -    RecordTrack::appendDumpHeader(result);
 -    for (size_t i = 0; i < mTracks.size(); ++i) {
 -        sp<RecordTrack> track = mTracks[i];
 -        if (track != 0) {
 -            track->dump(buffer, SIZE);
 -            result.append(buffer);
 +    size_t numtracks = mTracks.size();
 +    size_t numactive = mActiveTracks.size();
 +    size_t numactiveseen = 0;
-     fdprintf(fd, "  %d Tracks", numtracks);
++    dprintf(fd, "  %d Tracks", numtracks);
 +    if (numtracks) {
-         fdprintf(fd, " of which %d are active\n", numactive);
++        dprintf(fd, " of which %d are active\n", numactive);
 +        RecordTrack::appendDumpHeader(result);
 +        for (size_t i = 0; i < numtracks ; ++i) {
 +            sp<RecordTrack> track = mTracks[i];
 +            if (track != 0) {
 +                bool active = mActiveTracks.indexOf(track) >= 0;
 +                if (active) {
 +                    numactiveseen++;
 +                }
 +                track->dump(buffer, SIZE, active);
 +                result.append(buffer);
 +            }
          }
-         fdprintf(fd, "\n");
 +    } else {
++        dprintf(fd, "\n");
      }
  
 -    if (mActiveTrack != 0) {
 -        snprintf(buffer, SIZE, "\nInput thread %p active tracks\n", this);
 +    if (numactiveseen != numactive) {
 +        snprintf(buffer, SIZE, "  The following tracks are in the active list but"
 +                " not in the track list\n");
          result.append(buffer);
          RecordTrack::appendDumpHeader(result);
 -        mActiveTrack->dump(buffer, SIZE);
 -        result.append(buffer);
 +        for (size_t i = 0; i < numactive; ++i) {
 +            sp<RecordTrack> track = mActiveTracks[i];
 +            if (mTracks.indexOf(track) < 0) {
 +                track->dump(buffer, SIZE, true);
 +                result.append(buffer);
 +            }
 +        }
  
      }
      write(fd, result.string(), result.size());
Simple merge