Audio-Debugging

In diesem Artikel finden Sie einige Tipps und Tricks zur Fehlerbehebung bei Android-Audioinhalten.

Teebecken

Das „Te-Sink“ ist eine AudioFlinger-Debugging-Funktion, die nur in benutzerdefinierten Builds verfügbar ist, zur Aufbewahrung eines kurzen Ausschnitts aus den letzten Audioinhalten für eine spätere Analyse. So lässt sich vergleichen, was tatsächlich abgespielt oder aufgenommen wurde. im Vergleich zu den Erwartungen.

Aus Datenschutzgründen ist die Tee-Senke standardmäßig sowohl während der Kompilierung als auch Laufzeit verfügbar. Um die Tee-Senke zu verwenden, müssen Sie sie durch eine Neukompilierung aktivieren. und auch durch Festlegen einer Eigenschaft. Deaktivieren Sie diese Funktion unbedingt, Debugging abgeschlossen Die Tee-Senke sollte in Produktions-Builds nicht aktiviert bleiben.

Die Anweisungen in diesem Abschnitt gelten für Android 7.x und höher. Für Android 5.x und 6.x, ersetzen Sie /data/misc/audioserver durch /data/misc/media. Darüber hinaus müssen Sie ein Debugging- oder eng build. Wenn Sie einen UserDebug-Build verwenden, deaktivieren Sie Verity mit:

adb root && adb disable-verity && adb reboot

Einrichtung der Kompilierungszeit

  1. cd frameworks/av/services/audioflinger
  2. Configuration.h bearbeiten.
  3. Entfernen Sie den Kommentar von #define TEE_SINK.
  4. libaudioflinger.so neu erstellen.
  5. adb root
  6. adb remount
  7. Übertragen oder synchronisieren Sie die neue libaudioflinger.so an die /system/lib des Geräts.

Laufzeiteinrichtung

  1. adb shell getprop | grep ro.debuggable
    Prüfen Sie, ob die Ausgabe [ro.debuggable]: [1] ist.
  2. adb shell
  3. ls -ld /data/misc/audioserver

    Prüfen Sie, ob die Ausgabe so aussieht:

    drwx------ media media ... media
    

    Wenn das Verzeichnis nicht vorhanden ist, erstellen Sie es so:

    mkdir /data/misc/audioserver
    chown media:media /data/misc/audioserver
    
  4. echo af.tee=# > /data/local.prop
    Dabei ist der af.tee-Wert eine unten beschriebene Zahl.
  5. chmod 644 /data/local.prop
  6. reboot

Werte für die af.tee-Eigenschaft

Der Wert von af.tee ist eine Zahl zwischen 0 und 7, die für die Summe mehrerer Bits, eine pro Funktion. Du kannst den Code bei AudioFlinger::AudioFlinger() in AudioFlinger.cpp ansehen finden Sie eine Erläuterung zu den einzelnen Bits. Aber kurz:

  • 1 = Eingabe
  • 2 = FastMixer-Ausgabe
  • 4 = AudioRecord und Audiotrack pro Titel

Es gibt noch kein Bit für Deep buffer oder normalen Mixer, aber Sie erhalten ähnliche Ergebnisse mit „4“.

Daten testen und erfassen

  1. Führe den Audiotest durch.
  2. adb shell dumpsys media.audio_flinger
  3. Suchen Sie in der dumpsys-Ausgabe nach einer Zeile wie der folgenden:
    tee copied to /data/misc/audioserver/20131010101147_2.wav
    Das ist eine PCM-WAV-Datei.
  4. adb pull anschließend alle gewünschten /data/misc/audioserver/*.wav-Dateien. Beachten Sie, dass die trackspezifischen Dump-Dateinamen nicht in der Ausgabe von dumpsys, werden aber bei Sperrung der Strecke noch in /data/misc/audioserver gespeichert.
  5. Prüfen Sie die Dumpdateien auf Datenschutzbedenken, bevor Sie sie mit anderen teilen.

Vorschläge

Probieren Sie diese Ideen aus, um nützlichere Ergebnisse zu erhalten:

  • Deaktiviere Touch-Töne und Tastenklicks, um Unterbrechungen bei der Testausgabe zu vermeiden.
  • Maximieren Sie alle Volumen.
  • Apps deaktivieren, die Ton machen oder über das Mikrofon aufnehmen wenn sie für Ihren Test nicht von Interesse sind.
  • Titelspezifische Dumps werden nur gespeichert, wenn der Track geschlossen ist. müssen Sie das Schließen einer App möglicherweise erzwingen, um ihre titelspezifischen Daten zu übertragen.
  • Führen Sie dumpsys unmittelbar nach dem Test aus. ist der verfügbare Speicherplatz begrenzt.
  • Damit keine Dumpdateien verloren gehen, laden Sie sie regelmäßig auf Ihren Host hoch. Nur eine begrenzte Anzahl von Dumpdateien wird beibehalten. Ältere Dumps werden entfernt, sobald das Limit erreicht ist.

Wiederherstellen

Wie oben erwähnt, sollte die Tee-Senke nicht aktiviert bleiben. So stellst du deinen Build und dein Gerät wieder her:

  1. Setzen Sie die Änderungen am Quellcode auf Configuration.h zurück.
  2. libaudioflinger.so neu erstellen.
  3. Wiederhergestellte libaudioflinger.so per Push oder Synchronisierung übertragen auf den /system/lib des Geräts.
  4. adb shell
  5. rm /data/local.prop
  6. rm /data/misc/audioserver/*.wav
  7. reboot

media.log

ALOGx-Makros

Die standardmäßige Java Language Logging API im Android SDK ist android.util.Log.

Die entsprechende C Language API in Android NDK ist __android_log_print in <android/log.h> deklariert.

Innerhalb des nativen Teils des Android-Frameworks Makros mit den Namen ALOGE, ALOGW, ALOGI, ALOGV usw. Sie werden deklariert in <utils/Log.h> und für die Zwecke dieses Artikels werden zusammen als ALOGx bezeichnet.

All diese APIs sind einfach zu bedienen, gut verständlich und daher allgegenwärtig. auf der gesamten Android-Plattform. Insbesondere die mediaserver zu dem der AudioFlinger-Soundserver gehört, ALOGx ausgiebig.

Trotzdem gibt es einige Einschränkungen für ALOGx und Freunde:

  • Sie sind anfällig für „Spam protokollieren“, da der Protokollzwischenspeicher eine freigegebene Ressource ist sodass sie aufgrund von Logeinträgen ohne Bezug zum Überlauf einfach überlaufen können. übersehene Informationen. Die Variante ALOGV ist deaktiviert am standardmäßig die Compile-Zeit an. Aber natürlich kann auch dies zu Protokoll-Spam führen. sofern aktiviert.
  • Die zugrunde liegenden Kernel-Systemaufrufe könnten blockieren, was möglicherweise Prioritätsumkehr und folglich Messstörungen und Ungenauigkeiten. Dies ist von speziell für zeitkritische Threads wie FastMixer und FastCapture.
  • Wenn ein bestimmtes Protokoll zur Reduzierung von Log-Spam deaktiviert ist, dann gehen alle Informationen verloren, die von diesem Log erfasst worden wären. Es ist nicht möglich, ein bestimmtes Log rückwirkend zu aktivieren, nach deutlich wird, dass das Log interessant gewesen wäre.

NBLOG, media.log und MediaLogService

Die NBLOG APIs und die zugehörigen media.log Prozess und MediaLogService zusammen ein neueres Protokollierungssystem für Medien bilden. zur Behebung der oben genannten Probleme. Der Begriff „media.log“ sich auf alle drei beziehen, aber streng genommen ist NBLOG C++ Logging API, media.log ist ein Linux-Prozessname und MediaLogService ist ein Android-Binder-Dienst zum Untersuchen der Logs.

Eine media.log-Zeitachse ist eine Reihe von Logeinträgen, deren relative Reihenfolge beibehalten wird. Konventionsgemäß sollte jeder Thread eine eigene Zeitachse verwenden.

Vorteile

Die Vorteile des media.log-Systems sind:

  • Spamt das Hauptprotokoll nur, wenn es erforderlich ist.
  • Kann auch dann geprüft werden, wenn mediaserver abstürzt oder hängt.
  • Blockierung nach Zeitachse.
  • Stört die Leistung weniger stark. Natürlich ist keine Form des Loggings völlig unaufdringlich.

Architektur

Das folgende Diagramm zeigt die Beziehung des mediaserver-Prozesses und dem init-Prozess vor der Einführung von media.log:

Architektur vor media.log

Abbildung 1: Architektur vor media.log

Wichtige Punkte:

  • init gibt den Forks aus und führt den mediaserver aus.
  • init erkennt den Tod von mediaserver und verzweigt nach Bedarf noch einmal.
  • ALOGx-Logging wird nicht angezeigt.

Das folgende Diagramm zeigt die neue Beziehung der Komponenten, nachdem media.log zur Architektur hinzugefügt wurde:

Architektur nach media.log

Abbildung 2: Architektur nach media.log

Wichtige Änderungen:

  • Clients verwenden die NBLOG API, um Logeinträge zu erstellen und an folgende Adresse anzuhängen: ein kreisförmiger Puffer im gemeinsamen Speicher.
  • MediaLogService kann den Inhalt des kreisförmigen Zwischenspeichers jederzeit löschen.
  • Der kreisförmige Puffer ist so konstruiert, dass jegliche Beschädigung des eine geteilte Erinnerung führt zu einem Absturz von MediaLogService und kann trotzdem so viel von dem Zwischenspeicher frei, der von der Beschädigung nicht betroffen ist.
  • Der kreisförmige Zwischenspeicher ist sowohl für den Schreibvorgang als auch ohne Sperrung nicht gesperrt. und das Lesen vorhandener Einträge.
  • Es sind keine Kernel-Systemaufrufe erforderlich, um in den runden Zwischenspeicher zu schreiben oder daraus zu lesen (außer optionale Zeitstempel)

Verfügbarkeit

Ab Android 4.4 gibt es in AudioFlinger nur noch wenige Protokollpunkte. die das media.log-System verwenden. Obwohl die neuen APIs nicht so einfach zu verwenden als ALOGx, auch nicht sehr schwierig. Wir empfehlen Ihnen, sich mit dem neuen Protokollierungssystem wenn es unverzichtbar ist. Sie eignet sich insbesondere für AudioFlinger-Threads, die werden häufig, regelmäßig und ohne Blockierung FastMixer und FastCapture Threads.

Verwendung

Protokolle hinzufügen

Zuerst müssen Sie dem Code Logs hinzufügen.

Verwenden Sie in FastMixer- und FastCapture-Threads folgenden Code:

logWriter->log("string");
logWriter->logf("format", parameters);
logWriter->logTimestamp();

Da diese NBLog-Zeitachse nur von FastMixer und FastCapture Threads, ist ein gegenseitiger Ausschluss nicht erforderlich.

Verwenden Sie in anderen AudioFlinger-Threads mNBLogWriter:

mNBLogWriter->log("string");
mNBLogWriter->logf("format", parameters);
mNBLogWriter->logTimestamp();

Für andere Threads als FastMixer und FastCapture: Die NBLog-Zeitachse des Threads kann sowohl vom Thread selbst als auch durch Binder-Operationen. NBLog::Writer bietet keine impliziter gegenseitiger Ausschluss pro Zeitachse. Achten Sie daher darauf, dass alle Logs in einem Kontext, in dem der mutex-mLock des Threads gehalten wird.

Erstellen Sie AudioFlinger neu, nachdem Sie die Protokolle hinzugefügt haben.

Achtung: Pro Thread ist eine separate NBLog::Writer-Zeitachse erforderlich. um Threadsicherheit zu gewährleisten, da in Zeitplänen Mutexe weggelassen werden. Wenn Sie mehrere Threads dieselbe Zeitachse verwenden sollen, können Sie sie mit einem vorhandener Mutex (wie oben für mLock beschrieben). Oder Sie können Verwenden Sie den NBLog::LockedWriter-Wrapper anstelle von NBLog::Writer. Dies macht jedoch einen Hauptvorteil dieser API zunichte: ihre nicht blockierende verhalten.

Die vollständige NBLog API befindet sich unter frameworks/av/include/media/nbaio/NBLog.h.

media.log aktivieren

media.log ist standardmäßig deaktiviert. Es ist nur aktiv, wenn die Property ro.test_harness ist 1. So aktivieren Sie sie:

adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot

Die Verbindung wird während des Neustarts unterbrochen. Deshalb:

adb shell
Mit dem Befehl ps media werden jetzt zwei Prozesse angezeigt: <ph type="x-smartling-placeholder">
    </ph>
  • media.log
  • Mediaserver

Notieren Sie sich die Prozess-ID von mediaserver für später.

Zeitachsen einblenden

Sie können jederzeit manuell einen Log-Dump anfordern. Mit diesem Befehl werden Logs aus allen aktiven und letzten Zeitachsen angezeigt und anschließend gelöscht:

dumpsys media.log

Beachten Sie, dass Zeitpläne grundsätzlich unabhängig sind, und es ist nicht möglich, Zeitpläne zusammenzuführen.

Protokolle nach dem Ableben des Mediaservers wiederherstellen

Versuchen Sie jetzt, den mediaserver-Prozess zu beenden: kill -9 #, wobei # ist die Prozess-ID, die Sie zuvor notiert haben. Sie sollten einen Dump von media.log sehen in der Haupt-logcat, wobei alle Logs angezeigt werden, die zum Absturz geführt haben.

dumpsys media.log