AudioPolicyManager: Convert dump to use String8 (part 2)

Test: dumpsys of APM, diffs.
Bug: 117333182
Change-Id: I18761416ec9dc97418b41054f85af67e6eb59f3a
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
index c1c3f3c..0843fea 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h
@@ -22,6 +22,7 @@
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
+#include <utils/String8.h>
 
 namespace android {
 
@@ -30,7 +31,7 @@
 public:
     AudioPatch(const struct audio_patch *patch, uid_t uid);
 
-    status_t dump(int fd, int spaces, int index) const;
+    void dump(String8 *dst, int spaces, int index) const;
 
     audio_patch_handle_t mHandle;
     struct audio_patch mPatch;
@@ -47,7 +48,7 @@
 
     status_t listAudioPatches(unsigned int *num_patches, struct audio_patch *patches) const;
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 8fc6fe9..96c00ea 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -43,7 +43,7 @@
 
     void setMix(AudioMix &mix);
 
-    status_t dump(int fd, int spaces, int index) const;
+    void dump(String8 *dst, int spaces, int index) const;
 
 private:
     AudioMix    mMix;                   // Audio policy mix descriptor
@@ -80,7 +80,7 @@
 
     status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
 
-    status_t dump(int fd) const;
+    void dump(String8 *dst) const;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index 04831c6..9fa7486 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -21,6 +21,7 @@
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
+#include <utils/String8.h>
 
 namespace android {
 
@@ -28,7 +29,7 @@
 class EffectDescriptor : public RefBase
 {
 public:
-    status_t dump(int fd);
+    void dump(String8 *dst) const;
 
     int mIo;                // io the effect is attached to
     routing_strategy mStrategy; // routing strategy the effect is associated to
@@ -50,7 +51,7 @@
     uint32_t getMaxEffectsMemory() const;
     bool isNonOffloadableEffectEnabled();
 
-    status_t dump(int fd);
+    void dump(String8 *dst) const;
 
 private:
     status_t setEffectEnabled(const sp<EffectDescriptor> &effectDesc, bool enabled);
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
index e1f6b08..750da55 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
@@ -19,6 +19,7 @@
 #include <system/audio.h>
 #include <Volume.h>
 #include <utils/Errors.h>
+#include <utils/String8.h>
 
 namespace android {
 
@@ -47,7 +48,7 @@
     virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
                                          audio_devices_t device) const = 0;
 
-    virtual status_t dump(int fd) const = 0;
+    virtual void dump(String8 *dst) const = 0;
 };
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
index 3e6b2b4..76ec198 100644
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
@@ -59,7 +59,7 @@
 
     float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const;
 
-    void dump(int fd) const;
+    void dump(String8 *result) const;
 
 private:
     SortedVector<CurvePoint> mCurvePoints;
@@ -144,7 +144,7 @@
         }
     }
 
-    void dump(int fd, int spaces, bool curvePoints = false) const;
+    void dump(String8 *dst, int spaces, bool curvePoints = false) const;
 
 private:
     KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves;
@@ -217,7 +217,7 @@
         return getCurvesFor(stream).hasVolumeIndexForDevice(device);
     }
 
-    virtual status_t dump(int fd) const;
+    void dump(String8 *dst) const override;
 
     ssize_t add(const sp<VolumeCurve> &volumeCurve)
     {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index e78e121..cd1c2f2 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -34,34 +34,29 @@
 {
 }
 
-static String8 dumpPatchEndpoints(
-        int spaces, const char *prefix, int count, const audio_port_config *cfgs)
+static void dumpPatchEndpoints(
+        String8 *dst, int spaces, const char *prefix, int count, const audio_port_config *cfgs)
 {
-    String8 result;
     for (int i = 0; i < count; ++i) {
         const audio_port_config &cfg = cfgs[i];
-        result.appendFormat("%*s  [%s %d] ", spaces, "", prefix, i + 1);
+        dst->appendFormat("%*s  [%s %d] ", spaces, "", prefix, i + 1);
         if (cfg.type == AUDIO_PORT_TYPE_DEVICE) {
             std::string device;
             deviceToString(cfg.ext.device.type, device);
-            result.appendFormat("Device ID %d %s", cfg.id, device.c_str());
+            dst->appendFormat("Device ID %d %s", cfg.id, device.c_str());
         } else {
-            result.appendFormat("Mix ID %d I/O handle %d", cfg.id, cfg.ext.mix.handle);
+            dst->appendFormat("Mix ID %d I/O handle %d", cfg.id, cfg.ext.mix.handle);
         }
-        result.append("\n");
+        dst->append("\n");
     }
-    return result;
 }
 
-status_t AudioPatch::dump(int fd, int spaces, int index) const
+void AudioPatch::dump(String8 *dst, int spaces, int index) const
 {
-    String8 result;
-    result.appendFormat("%*sPatch %d: owner uid %4d, handle %2d, af handle %2d\n",
+    dst->appendFormat("%*sPatch %d: owner uid %4d, handle %2d, af handle %2d\n",
             spaces, "", index + 1, mUid, mHandle, mAfPatchHandle);
-    result.append(dumpPatchEndpoints(spaces, "src ", mPatch.num_sources, mPatch.sources));
-    result.append(dumpPatchEndpoints(spaces, "sink", mPatch.num_sinks, mPatch.sinks));
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
+    dumpPatchEndpoints(dst, spaces, "src ", mPatch.num_sources, mPatch.sources);
+    dumpPatchEndpoints(dst, spaces, "sink", mPatch.num_sinks, mPatch.sinks);
 }
 
 status_t AudioPatchCollection::addAudioPatch(audio_patch_handle_t handle,
@@ -142,16 +137,12 @@
     return NO_ERROR;
 }
 
-status_t AudioPatchCollection::dump(int fd) const
+void AudioPatchCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    snprintf(buffer, SIZE, "\nAudio Patches:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nAudio Patches:\n");
     for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->dump(fd, 2, i);
+        valueAt(i)->dump(dst, 2, i);
     }
-    return NO_ERROR;
 }
 
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 08930f1..3cf8014 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -52,64 +52,55 @@
     return &mMix;
 }
 
-status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
+void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sAudio Policy Mix %d:\n", spaces, "", index+1);
-    result.append(buffer);
+    dst->appendFormat("%*sAudio Policy Mix %d:\n", spaces, "", index + 1);
     std::string mixTypeLiteral;
     if (!MixTypeConverter::toString(mMix.mMixType, mixTypeLiteral)) {
         ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMix.mMixType);
-        return BAD_VALUE;
+        return;
     }
-    snprintf(buffer, SIZE, "%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
-    result.append(buffer);
+    dst->appendFormat("%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
+
     std::string routeFlagLiteral;
     RouteFlagTypeConverter::maskToString(mMix.mRouteFlags, routeFlagLiteral);
-    snprintf(buffer, SIZE, "%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
-    result.append(buffer);
+    dst->appendFormat("%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
+
     std::string deviceLiteral;
     deviceToString(mMix.mDeviceType, deviceLiteral);
-    snprintf(buffer, SIZE, "%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
-    result.append(buffer);
+    dst->appendFormat("%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
+
+    dst->appendFormat("%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
 
     int indexCriterion = 0;
     for (const auto &criterion : mMix.mCriteria) {
-        snprintf(buffer, SIZE, "%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
-        result.append(buffer);
+        dst->appendFormat("%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
+
         std::string usageLiteral;
         if (!UsageTypeConverter::toString(criterion.mValue.mUsage, usageLiteral)) {
             ALOGE("%s: failed to convert usage %d", __FUNCTION__, criterion.mValue.mUsage);
-            return BAD_VALUE;
+            return;
         }
-        snprintf(buffer, SIZE, "%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
-        result.append(buffer);
+        dst->appendFormat("%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
+
         if (mMix.mMixType == MIX_TYPE_RECORDERS) {
             std::string sourceLiteral;
             if (!SourceTypeConverter::toString(criterion.mValue.mSource, sourceLiteral)) {
                 ALOGE("%s: failed to convert source %d", __FUNCTION__, criterion.mValue.mSource);
-                return BAD_VALUE;
+                return;
             }
-            snprintf(buffer, SIZE, "%*s- Source:%s\n", spaces + 4, "", sourceLiteral.c_str());
-            result.append(buffer);
+            dst->appendFormat("%*s- Source:%s\n", spaces + 4, "", sourceLiteral.c_str());
+
         }
-        snprintf(buffer, SIZE, "%*s- Uid:%d\n", spaces + 4, "", criterion.mValue.mUid);
-        result.append(buffer);
+        dst->appendFormat("%*s- Uid:%d\n", spaces + 4, "", criterion.mValue.mUid);
+
         std::string ruleLiteral;
         if (!RuleTypeConverter::toString(criterion.mRule, ruleLiteral)) {
             ALOGE("%s: failed to convert source %d", __FUNCTION__,criterion.mRule);
-            return BAD_VALUE;
+            return;
         }
-        snprintf(buffer, SIZE, "%*s- Rule:%s\n", spaces + 4, "", ruleLiteral.c_str());
-        result.append(buffer);
+        dst->appendFormat("%*s- Rule:%s\n", spaces + 4, "", ruleLiteral.c_str());
     }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
 }
 
 status_t AudioPolicyMixCollection::registerMix(const String8& address, AudioMix mix,
@@ -349,14 +340,12 @@
     return NO_ERROR;
 }
 
-status_t AudioPolicyMixCollection::dump(int fd) const
+void AudioPolicyMixCollection::dump(String8 *dst) const
 {
-    std::string log("\nAudio Policy Mix:\n");
-    write(fd, log.c_str(), log.size());
+    dst->append("\nAudio Policy Mix:\n");
     for (size_t i = 0; i < size(); i++) {
-        valueAt(i)->dump(fd, 2, i);
+        valueAt(i)->dump(dst, 2, i);
     }
-    return NO_ERROR;
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 7b2341e..8bbb798 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -22,25 +22,13 @@
 
 namespace android {
 
-status_t EffectDescriptor::dump(int fd)
+void EffectDescriptor::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " I/O: %d\n", mIo);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Session: %d\n", mSession);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Name: %s\n",  mDesc.name);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " %s\n",  mEnabled ? "Enabled" : "Disabled");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
+    dst->appendFormat(" I/O: %d\n", mIo);
+    dst->appendFormat(" Strategy: %d\n", mStrategy);
+    dst->appendFormat(" Session: %d\n", mSession);
+    dst->appendFormat(" Name: %s\n",  mDesc.name);
+    dst->appendFormat(" %s\n",  mEnabled ? "Enabled" : "Disabled");
 }
 
 EffectDescriptorCollection::EffectDescriptorCollection() :
@@ -174,24 +162,16 @@
     return MAX_EFFECTS_MEMORY;
 }
 
-status_t EffectDescriptorCollection::dump(int fd)
+void EffectDescriptorCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE,
+    dst->appendFormat(
             "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB, Max memory used: %d KB\n",
              (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory, mTotalEffectsMemoryMaxUsed);
-    write(fd, buffer, strlen(buffer));
-
-    snprintf(buffer, SIZE, "Registered effects:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("Registered effects:\n");
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, "- Effect %d dump:\n", keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        dst->appendFormat("- Effect %d dump:\n", keyAt(i));
+        valueAt(i)->dump(dst);
     }
-    return NO_ERROR;
 }
 
 }; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp b/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
index ac3f1bc..620f361 100644
--- a/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/VolumeCurve.cpp
@@ -68,81 +68,56 @@
     return decibels;
 }
 
-void VolumeCurve::dump(int fd) const
+void VolumeCurve::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, " {");
-    result.append(buffer);
+    dst->append(" {");
     for (size_t i = 0; i < mCurvePoints.size(); i++) {
-        snprintf(buffer, SIZE, "(%3d, %5d)",
+        dst->appendFormat("(%3d, %5d)",
                  mCurvePoints[i].mIndex, mCurvePoints[i].mAttenuationInMb);
-        result.append(buffer);
-        result.append(i == (mCurvePoints.size() - 1) ? " }\n" : ", ");
+        dst->append(i == (mCurvePoints.size() - 1) ? " }\n" : ", ");
     }
-    write(fd, result.string(), result.size());
 }
 
-void VolumeCurvesForStream::dump(int fd, int spaces = 0, bool curvePoints) const
+void VolumeCurvesForStream::dump(String8 *dst, int spaces = 0, bool curvePoints) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
     if (!curvePoints) {
-        snprintf(buffer, SIZE, "%s         %02d         %02d         ",
+        dst->appendFormat("%s         %02d         %02d         ",
                  mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
-        result.append(buffer);
         for (size_t i = 0; i < mIndexCur.size(); i++) {
-            snprintf(buffer, SIZE, "%04x : %02d, ", mIndexCur.keyAt(i), mIndexCur.valueAt(i));
-            result.append(buffer);
+            dst->appendFormat("%04x : %02d, ", mIndexCur.keyAt(i), mIndexCur.valueAt(i));
         }
-        result.append("\n");
-        write(fd, result.string(), result.size());
+        dst->append("\n");
         return;
     }
 
     for (size_t i = 0; i < size(); i++) {
         std::string deviceCatLiteral;
         DeviceCategoryConverter::toString(keyAt(i), deviceCatLiteral);
-        snprintf(buffer, SIZE, "%*s %s :",
+        dst->appendFormat("%*s %s :",
                  spaces, "", deviceCatLiteral.c_str());
-        write(fd, buffer, strlen(buffer));
-        valueAt(i)->dump(fd);
+        valueAt(i)->dump(dst);
     }
-    result.append("\n");
-    write(fd, result.string(), result.size());
+    dst->append("\n");
 }
 
-status_t VolumeCurvesCollection::dump(int fd) const
+void VolumeCurvesCollection::dump(String8 *dst) const
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "\nStreams dump:\n");
-    write(fd, buffer, strlen(buffer));
-    snprintf(buffer, SIZE,
+    dst->append("\nStreams dump:\n");
+    dst->append(
              " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
-    write(fd, buffer, strlen(buffer));
     for (size_t i = 0; i < size(); i++) {
-        snprintf(buffer, SIZE, " %02zu      ", i);
-        write(fd, buffer, strlen(buffer));
-        valueAt(i).dump(fd);
+        dst->appendFormat(" %02zu      ", i);
+        valueAt(i).dump(dst);
     }
-    snprintf(buffer, SIZE, "\nVolume Curves for Use Cases (aka Stream types) dump:\n");
-    write(fd, buffer, strlen(buffer));
+    dst->append("\nVolume Curves for Use Cases (aka Stream types) dump:\n");
     for (size_t i = 0; i < size(); i++) {
         std::string streamTypeLiteral;
         StreamTypeConverter::toString(keyAt(i), streamTypeLiteral);
-        snprintf(buffer, SIZE,
+        dst->appendFormat(
                  " %s (%02zu): Curve points for device category (index, attenuation in millibel)\n",
                  streamTypeLiteral.c_str(), i);
-        write(fd, buffer, strlen(buffer));
-        valueAt(i).dump(fd, 2, true);
+        valueAt(i).dump(dst, 2, true);
     }
-
-    return NO_ERROR;
 }
 
 } // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 21f893a..3e8c462 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2686,53 +2686,52 @@
     return res;
 }
 
-
-status_t AudioPolicyManager::dump(int fd)
+void AudioPolicyManager::dump(String8 *dst) const
 {
-    String8 result;
-    result.appendFormat("\nAudioPolicyManager Dump: %p\n", this);
-    result.appendFormat(" Primary Output: %d\n",
+    dst->appendFormat("\nAudioPolicyManager Dump: %p\n", this);
+    dst->appendFormat(" Primary Output: %d\n",
              hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
     std::string stateLiteral;
     AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
-    result.appendFormat(" Phone state: %s\n", stateLiteral.c_str());
+    dst->appendFormat(" Phone state: %s\n", stateLiteral.c_str());
     const char* forceUses[AUDIO_POLICY_FORCE_USE_CNT] = {
         "communications", "media", "record", "dock", "system",
         "HDMI system audio", "encoded surround output", "vibrate ringing" };
     for (audio_policy_force_use_t i = AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
          i < AUDIO_POLICY_FORCE_USE_CNT; i = (audio_policy_force_use_t)((int)i + 1)) {
-        result.appendFormat(" Force use for %s: %d\n",
+        dst->appendFormat(" Force use for %s: %d\n",
                 forceUses[i], mEngine->getForceUse(i));
     }
-    result.appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
-    result.appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
-    result.appendFormat(" Config source: %s\n", getConfig().getSource().c_str());
-    mAvailableOutputDevices.dump(&result, String8("Available output"));
-    mAvailableInputDevices.dump(&result, String8("Available input"));
-    mHwModulesAll.dump(&result);
-    mOutputs.dump(&result);
-    mInputs.dump(&result);
-    write(fd, result.string(), result.size());
-
-    // TODO convert these to dump to string.
-    mVolumeCurves->dump(fd);
-    mEffects.dump(fd);
-    mAudioPatches.dump(fd);
-    mPolicyMixes.dump(fd);
-
-    result.clear();
-    mAudioSources.dump(&result);
+    dst->appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
+    dst->appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
+    dst->appendFormat(" Config source: %s\n", mConfig.getSource().c_str()); // getConfig not const
+    mAvailableOutputDevices.dump(dst, String8("Available output"));
+    mAvailableInputDevices.dump(dst, String8("Available input"));
+    mHwModulesAll.dump(dst);
+    mOutputs.dump(dst);
+    mInputs.dump(dst);
+    mVolumeCurves->dump(dst);
+    mEffects.dump(dst);
+    mAudioPatches.dump(dst);
+    mPolicyMixes.dump(dst);
+    mAudioSources.dump(dst);
     if (!mSurroundFormats.empty()) {
-        result.append("\nEnabled Surround Formats:\n");
+        dst->append("\nEnabled Surround Formats:\n");
         size_t i = 0;
         for (const auto& fmt : mSurroundFormats) {
-            result.append(i++ == 0 ? "  " : ", ");
+            dst->append(i++ == 0 ? "  " : ", ");
             std::string sfmt;
             FormatConverter::toString(fmt, sfmt);
-            result.append(sfmt.c_str());
+            dst->append(sfmt.c_str());
         }
-        result.append("\n");
+        dst->append("\n");
     }
+}
+
+status_t AudioPolicyManager::dump(int fd)
+{
+    String8 result;
+    dump(&result);
     write(fd, result.string(), result.size());
     return NO_ERROR;
 }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index fcb9d25..f559b7f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -186,7 +186,9 @@
 
         virtual bool isSourceActive(audio_source_t source) const;
 
-        virtual status_t dump(int fd);
+        void dump(String8 *dst) const; // helper for dump(int fd)
+
+        status_t dump(int fd) override;
 
         virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);