aaudio: improved dumpsys
Add more information about various streams and endpoints.
Bug: 38396780
Test: adb shell dumpsys media.aaudio
Change-Id: I5cc116574bfc3aa93703c182d933dbdfcbefad7a
diff --git a/media/libaaudio/src/utility/HandleTracker.cpp b/media/libaaudio/src/utility/HandleTracker.cpp
index d4202db..35ce95a 100644
--- a/media/libaaudio/src/utility/HandleTracker.cpp
+++ b/media/libaaudio/src/utility/HandleTracker.cpp
@@ -113,7 +113,8 @@
result << "HandleTracker may be deadlocked\n";
}
- result << "Handles:\n";
+ result << "HandleTracker:\n";
+ result << " HandleHeaders:\n";
// atLineStart() can be changed to support an arbitrary line breaking algorithm;
// it should return true when a new line starts.
// For simplicity, we will use a constant 16 items per line.
@@ -125,7 +126,7 @@
for (int i = 0; i < mMaxHandleCount; ++i) {
if (atLineStart(i)) {
- result << " ";
+ result << " ";
}
result << std::hex << std::setw(4) << std::setfill('0') << mHandleHeaders[i]
<< (atLineEnd(i) ? "\n" : " ");
diff --git a/services/oboeservice/AAudioClientTracker.cpp b/services/oboeservice/AAudioClientTracker.cpp
index c0dfc54..c0bea13 100644
--- a/services/oboeservice/AAudioClientTracker.cpp
+++ b/services/oboeservice/AAudioClientTracker.cpp
@@ -39,6 +39,28 @@
: Singleton<AAudioClientTracker>() {
}
+
+std::string AAudioClientTracker::dump() const {
+ std::stringstream result;
+ const bool isLocked = AAudio_tryUntilTrue(
+ [this]()->bool { return mLock.try_lock(); } /* f */,
+ 50 /* times */,
+ 20 /* sleepMs */);
+ if (!isLocked) {
+ result << "AAudioClientTracker may be deadlocked\n";
+ }
+
+ result << "AAudioClientTracker:\n";
+ for (const auto& it : mNotificationClients) {
+ result << it.second->dump();
+ }
+
+ if (isLocked) {
+ mLock.unlock();
+ }
+ return result.str();
+}
+
// Create a tracker for the client.
aaudio_result_t AAudioClientTracker::registerClient(pid_t pid,
const sp<IAAudioClient>& client) {
@@ -81,12 +103,12 @@
aaudio_result_t
AAudioClientTracker::registerClientStream(pid_t pid, sp<AAudioServiceStreamBase> serviceStream) {
aaudio_result_t result = AAUDIO_OK;
- ALOGV("AAudioClientTracker::registerClientStream(%d, %p)\n", pid, serviceStream.get());
+ ALOGD("AAudioClientTracker::registerClientStream(%d, %p)\n", pid, serviceStream.get());
std::lock_guard<std::mutex> lock(mLock);
sp<NotificationClient> notificationClient = mNotificationClients[pid];
if (notificationClient == 0) {
// This will get called the first time the audio server registers an internal stream.
- ALOGV("AAudioClientTracker::registerClientStream(%d,) unrecognized pid\n", pid);
+ ALOGD("AAudioClientTracker::registerClientStream(%d,) unrecognized pid\n", pid);
notificationClient = new NotificationClient(pid);
mNotificationClients[pid] = notificationClient;
}
@@ -98,11 +120,16 @@
aaudio_result_t
AAudioClientTracker::unregisterClientStream(pid_t pid,
sp<AAudioServiceStreamBase> serviceStream) {
- ALOGV("AAudioClientTracker::unregisterClientStream(%d, %p)\n", pid, serviceStream.get());
+ ALOGD("AAudioClientTracker::unregisterClientStream(%d, %p)\n", pid, serviceStream.get());
std::lock_guard<std::mutex> lock(mLock);
auto it = mNotificationClients.find(pid);
if (it != mNotificationClients.end()) {
+ ALOGD("AAudioClientTracker::unregisterClientStream(%d, %p) found NotificationClient\n",
+ pid, serviceStream.get());
it->second->unregisterClientStream(serviceStream);
+ } else {
+ ALOGE("AAudioClientTracker::unregisterClientStream(%d, %p) missing NotificationClient\n",
+ pid, serviceStream.get());
}
return AAUDIO_OK;
}
@@ -131,7 +158,11 @@
aaudio_result_t AAudioClientTracker::NotificationClient::unregisterClientStream(
sp<AAudioServiceStreamBase> serviceStream) {
std::lock_guard<std::mutex> lock(mLock);
+ ALOGD("AAudioClientTracker::NotificationClient() before erase() count = %d\n",
+ (int)mStreams.size());
mStreams.erase(serviceStream);
+ ALOGD("AAudioClientTracker::NotificationClient() after erase() count = %d\n",
+ (int)mStreams.size());
return AAUDIO_OK;
}
@@ -141,7 +172,7 @@
if (aaudioService != nullptr) {
// Copy the current list of streams to another vector because closing them below
// will cause unregisterClientStream() calls back to this object.
- std::set<android::sp<AAudioServiceStreamBase>> streamsToClose;
+ std::set<sp<AAudioServiceStreamBase>> streamsToClose;
{
std::lock_guard<std::mutex> lock(mLock);
@@ -162,3 +193,25 @@
sp<NotificationClient> keep(this);
AAudioClientTracker::getInstance().unregisterClient(mProcessId);
}
+
+
+std::string AAudioClientTracker::NotificationClient::dump() const {
+ std::stringstream result;
+ const bool isLocked = AAudio_tryUntilTrue(
+ [this]()->bool { return mLock.try_lock(); } /* f */,
+ 50 /* times */,
+ 20 /* sleepMs */);
+ if (!isLocked) {
+ result << "AAudioClientTracker::NotificationClient may be deadlocked\n";
+ }
+
+ result << " client: pid = " << mProcessId << " has " << mStreams.size() << " streams\n";
+ for (auto serviceStream : mStreams) {
+ result << " stream: 0x" << std::hex << serviceStream->getHandle() << std::dec << "\n";
+ }
+
+ if (isLocked) {
+ mLock.unlock();
+ }
+ return result.str();
+}
diff --git a/services/oboeservice/AAudioClientTracker.h b/services/oboeservice/AAudioClientTracker.h
index e74c8bf..accf1a7 100644
--- a/services/oboeservice/AAudioClientTracker.h
+++ b/services/oboeservice/AAudioClientTracker.h
@@ -34,6 +34,18 @@
AAudioClientTracker();
~AAudioClientTracker() = default;
+ /**
+ * Returns information about the state of the this class.
+ *
+ * Will attempt to get the object lock, but will proceed
+ * even if it cannot.
+ *
+ * Each line of information ends with a newline.
+ *
+ * @return a string with useful information
+ */
+ std::string dump() const;
+
aaudio_result_t registerClient(pid_t pid, const android::sp<android::IAAudioClient>& client);
void unregisterClient(pid_t pid);
@@ -66,6 +78,8 @@
int32_t getStreamCount();
+ std::string dump() const;
+
aaudio_result_t registerClientStream(android::sp<AAudioServiceStreamBase> serviceStream);
aaudio_result_t unregisterClientStream(android::sp<AAudioServiceStreamBase> serviceStream);
@@ -74,12 +88,12 @@
virtual void binderDied(const android::wp<IBinder>& who);
protected:
- std::mutex mLock;
+ mutable std::mutex mLock;
const pid_t mProcessId;
std::set<android::sp<AAudioServiceStreamBase>> mStreams;
};
- std::mutex mLock;
+ mutable std::mutex mLock;
std::map<pid_t, android::sp<NotificationClient>> mNotificationClients;
android::AAudioService *mAAudioService = nullptr;
};
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 36e678a..02d4a19 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -48,16 +48,17 @@
result << "EndpointManager may be deadlocked\n";
}
+ result << "AAudioEndpointManager:" << "\n";
size_t inputs = mInputs.size();
- result << "Inputs: " << inputs << "\n";
+ result << "Input Endpoints: " << inputs << "\n";
for (const auto &input : mInputs) {
- result << " Input(" << input << ")\n";
+ result << " Input: " << input->dump() << "\n";
}
size_t outputs = mOutputs.size();
- result << "Outputs: " << outputs << "\n";
+ result << "Output Endpoints: " << outputs << "\n";
for (const auto &output : mOutputs) {
- result << " Output(" << output << ")\n";
+ result << " Output: " << output->dump() << "\n";
}
if (isLocked) {
diff --git a/services/oboeservice/AAudioEndpointManager.h b/services/oboeservice/AAudioEndpointManager.h
index 6d3b52b..2511b2f 100644
--- a/services/oboeservice/AAudioEndpointManager.h
+++ b/services/oboeservice/AAudioEndpointManager.h
@@ -34,14 +34,14 @@
~AAudioEndpointManager() = default;
/**
- * Returns EndpointManager information.
+ * Returns information about the state of the this class.
*
* Will attempt to get the object lock, but will proceed
* even if it cannot.
*
* Each line of information ends with a newline.
*
- * @return a string representing the EndpointManager info
+ * @return a string with useful information
*/
std::string dump() const;
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 91f7885..cfcfb11 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -69,7 +69,9 @@
result = ss.str();
ALOGW("%s", result.c_str());
} else {
- result = mHandleTracker.dump() + AAudioEndpointManager::getInstance().dump();
+ result = mHandleTracker.dump()
+ + AAudioClientTracker::getInstance().dump()
+ + AAudioEndpointManager::getInstance().dump();
}
(void)write(fd, result.c_str(), result.size());
return NO_ERROR;
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 1df2365..b519829 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -18,16 +18,17 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <algorithm>
#include <assert.h>
#include <map>
#include <mutex>
+#include <sstream>
+#include <vector>
+
#include <utils/Singleton.h>
#include "AAudioEndpointManager.h"
#include "AAudioServiceEndpoint.h"
-#include <algorithm>
-#include <mutex>
-#include <vector>
#include "core/AudioStreamBuilder.h"
#include "AAudioServiceEndpoint.h"
@@ -44,6 +45,35 @@
// This is the maximum size in frames. The effective size can be tuned smaller at runtime.
#define DEFAULT_BUFFER_CAPACITY (48 * 8)
+std::string AAudioServiceEndpoint::dump() const {
+ std::stringstream result;
+
+ const bool isLocked = AAudio_tryUntilTrue(
+ [this]()->bool { return mLockStreams.try_lock(); } /* f */,
+ 50 /* times */,
+ 20 /* sleepMs */);
+ if (!isLocked) {
+ result << "EndpointManager may be deadlocked\n";
+ }
+
+ AudioStreamInternal *stream = mStreamInternal;
+ if (stream == nullptr) {
+ result << "null stream!" << "\n";
+ } else {
+ result << "mmap stream: rate = " << stream->getSampleRate() << "\n";
+ }
+
+ result << " Registered Streams:" << "\n";
+ for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
+ result << sharedStream->dump();
+ }
+
+ if (isLocked) {
+ mLockStreams.unlock();
+ }
+ return result.str();
+}
+
// Set up an EXCLUSIVE MMAP stream that will be shared.
aaudio_result_t AAudioServiceEndpoint::open(const AAudioStreamConfiguration& configuration) {
mRequestedDeviceId = configuration.getDeviceId();
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 72015b1..a78d3fa 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -36,6 +36,8 @@
public:
virtual ~AAudioServiceEndpoint() = default;
+ std::string dump() const;
+
virtual aaudio_result_t open(const AAudioStreamConfiguration& configuration);
int32_t getSampleRate() const { return mStreamInternal->getSampleRate(); }
@@ -73,7 +75,7 @@
std::atomic<bool> mCallbackEnabled;
- std::mutex mLockStreams;
+ mutable std::mutex mLockStreams;
std::vector<android::sp<AAudioServiceStreamShared>> mRegisteredStreams;
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index c4591b0..c88038f 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -45,6 +45,20 @@
ALOGD("AAudioServiceStreamBase::~AAudioServiceStreamBase() destroyed %p", this);
}
+std::string AAudioServiceStreamBase::dump() const {
+ std::stringstream result;
+
+ result << " -------- handle = 0x" << std::hex << mHandle << std::dec << "\n";
+ result << " state = " << AAudio_convertStreamStateToText(mState) << "\n";
+ result << " format = " << mAudioFormat << "\n";
+ result << " framesPerBurst = " << mFramesPerBurst << "\n";
+ result << " channelCount = " << mSamplesPerFrame << "\n";
+ result << " capacityFrames = " << mCapacityInFrames << "\n";
+ result << " owner uid = " << mOwnerUserId << "\n";
+
+ return result.str();
+}
+
aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request,
aaudio::AAudioStreamConfiguration &configurationOutput) {
std::lock_guard<std::mutex> lock(mLockUpMessageQueue);
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 653b456..0bd2276 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -52,6 +52,8 @@
ILLEGAL_THREAD_ID = 0
};
+ std::string dump() const;
+
// -------------------------------------------------------------------
/**
* Open the device.