यह आलेख Android ऑडियो डीबग करने के लिए कुछ युक्तियों और युक्तियों का वर्णन करता है।
टी सिंक
"टी सिंक" एक ऑडियोफ्लिंगर डिबगिंग सुविधा है, जो केवल कस्टम बिल्ड में उपलब्ध है, बाद के विश्लेषण के लिए हाल के ऑडियो के एक छोटे टुकड़े को बनाए रखने के लिए। यह वास्तव में जो खेला या रिकॉर्ड किया गया था, उसके बीच तुलना की अनुमति देता है।
गोपनीयता के लिए टी सिंक डिफ़ॉल्ट रूप से, संकलन-समय और रन-टाइम दोनों पर अक्षम है। टी सिंक का उपयोग करने के लिए, आपको इसे फिर से संकलित करके और एक संपत्ति सेट करके इसे सक्षम करने की आवश्यकता होगी। डिबगिंग करने के बाद इस सुविधा को अक्षम करना सुनिश्चित करें; टी सिंक को प्रोडक्शन बिल्ड में सक्षम नहीं छोड़ा जाना चाहिए।
इस खंड में निर्देश Android 7.x और उच्चतर के लिए हैं। Android 5.x और 6.x के लिए, /data/misc/audioserver
को /data/misc/media
से बदलें। इसके अतिरिक्त, आपको एक userdebug या eng बिल्ड का उपयोग करना चाहिए। यदि आप उपयोगकर्ता डिबग बिल्ड का उपयोग करते हैं, तो इसके साथ सत्यता अक्षम करें:
adb root && adb disable-verity && adb reboot
संकलन-समय सेटअप
-
cd frameworks/av/services/audioflinger
-
Configuration.h
संपादित करें। एच। -
#define TEE_SINK
। -
libaudioflinger.so
को फिर से बनाएं। -
adb root
-
adb remount
- नए
libaudioflinger.so
को डिवाइस के/system/lib
में पुश या सिंक करें।
रन-टाइम सेटअप
-
adb shell getprop | grep ro.debuggable
पुष्टि करें कि आउटपुट है:[ro.debuggable]: [1]
-
adb shell
-
ls -ld /data/misc/audioserver
पुष्टि करें कि आउटपुट है:
drwx------ media media ... media
यदि निर्देशिका मौजूद नहीं है, तो इसे निम्नानुसार बनाएं:
mkdir /data/misc/audioserver
chown media:media /data/misc/audioserver
-
echo af.tee=# > /data/local.prop
जहांaf.tee
मान नीचे वर्णित एक संख्या है। -
chmod 644 /data/local.prop
-
reboot
af.tee
संपत्ति के लिए मूल्य
af.tee
का मान 0 और 7 के बीच की एक संख्या है, जो कई बिट्स के योग को व्यक्त करता है, एक प्रति फीचर। प्रत्येक बिट की व्याख्या के लिए AudioFlinger::AudioFlinger()
में AudioFlinger.cpp
पर कोड देखें, लेकिन संक्षेप में:
- 1 = इनपुट
- 2 = फास्टमिक्सर आउटपुट
- 4 = प्रति-ट्रैक ऑडियोरिकॉर्ड और ऑडियोट्रैक
गहरे बफर या सामान्य मिक्सर के लिए अभी तक कोई बिट नहीं है, लेकिन आप "4." का उपयोग करके समान परिणाम प्राप्त कर सकते हैं।
परीक्षण करें और डेटा प्राप्त करें
- अपना ऑडियो परीक्षण चलाएँ।
-
adb shell dumpsys media.audio_flinger
- इस तरह से
dumpsys
आउटपुट में एक लाइन की तलाश करें:
tee copied to /data/misc/audioserver/20131010101147_2.wav
यह एक पीसीएम .wav फ़ाइल है। - फिर
adb pull
किसी भी/data/misc/audioserver/*.wav
रुचि की फाइलों को खींचे; ध्यान दें कि ट्रैक-विशिष्ट डंप फ़ाइल नामdumpsys
आउटपुट में प्रकट नहीं होते हैं, लेकिन फिर भी ट्रैक बंद होने पर/data/misc/audioserver
में सहेजे जाते हैं। - दूसरों के साथ साझा करने से पहले गोपनीयता संबंधी चिंताओं के लिए डंप फ़ाइलों की समीक्षा करें।
सुझाव
अधिक उपयोगी परिणामों के लिए इन विचारों को आजमाएं:
- परीक्षण आउटपुट में रुकावटों को कम करने के लिए स्पर्श ध्वनियों और कुंजी क्लिकों को अक्षम करें।
- सभी वॉल्यूम को अधिकतम करें।
- उन ऐप्स को अक्षम करें जो माइक्रोफ़ोन से ध्वनि या रिकॉर्ड बनाते हैं, यदि वे आपके परीक्षण में रुचि नहीं रखते हैं।
- ट्रैक-विशिष्ट डंप केवल तभी सहेजे जाते हैं जब ट्रैक बंद हो; ट्रैक-विशिष्ट डेटा को डंप करने के लिए आपको किसी ऐप को बंद करने के लिए मजबूर करना पड़ सकता है
- परीक्षण के तुरंत बाद
dumpsys
करें; रिकॉर्डिंग स्थान की सीमित मात्रा उपलब्ध है। - यह सुनिश्चित करने के लिए कि आप अपनी डंप फ़ाइलें न खोएं, उन्हें समय-समय पर अपने होस्ट पर अपलोड करें। केवल सीमित संख्या में डंप फ़ाइलें संरक्षित हैं; उस सीमा तक पहुंचने के बाद पुराने डंप हटा दिए जाते हैं।
पुनर्स्थापित करना
जैसा कि ऊपर उल्लेख किया गया है, टी सिंक सुविधा को सक्षम नहीं छोड़ा जाना चाहिए। अपने निर्माण और डिवाइस को निम्नानुसार पुनर्स्थापित करें:
- स्रोत कोड परिवर्तन को
Configuration.h
पर वापस लाएं। -
libaudioflinger.so
को फिर से बनाएं। - पुनर्स्थापित किए गए
libaudioflinger.so
को डिवाइस के/system/lib
में पुश या सिंक करें। -
adb shell
-
rm /data/local.prop
-
rm /data/misc/audioserver/*.wav
-
reboot
मीडिया.लॉग
ALOGx मैक्रोज़
एंड्रॉइड एसडीके में मानक जावा भाषा लॉगिंग एपीआई android.util.Log है।
एंड्रॉइड एनडीके में संबंधित सी भाषा एपीआई __android_log_print
है जिसे <android/log.h>
में घोषित किया गया है।
Android ढांचे के मूल भाग के भीतर, हम ALOGE
, ALOGW
, ALOGI
, ALOGV
, आदि नाम के मैक्रोज़ पसंद करते हैं। उन्हें <utils/Log.h>
में घोषित किया गया है, और इस लेख के प्रयोजनों के लिए हम सामूहिक रूप से उन्हें ALOGx
के रूप में संदर्भित करेंगे। .
ये सभी एपीआई उपयोग में आसान और अच्छी तरह से समझे जाने वाले हैं, इसलिए ये पूरे एंड्रॉइड प्लेटफॉर्म पर व्यापक हैं। विशेष रूप से mediaserver
प्रक्रिया, जिसमें ऑडियोफ्लिंगर ध्वनि सर्वर शामिल है, ALOGx
का व्यापक रूप से उपयोग करता है।
फिर भी, ALOGx
और मित्रों की कुछ सीमाएँ हैं:
- वे "लॉग स्पैम" के लिए अतिसंवेदनशील होते हैं: लॉग बफर एक साझा संसाधन है, इसलिए यह असंबंधित लॉग प्रविष्टियों के कारण आसानी से ओवरफ्लो हो सकता है, जिसके परिणामस्वरूप छूटी हुई जानकारी हो सकती है।
ALOGV
संस्करण डिफ़ॉल्ट रूप से संकलन-समय पर अक्षम है। लेकिन निश्चित रूप से यह सक्षम होने पर भी लॉग स्पैम में परिणाम कर सकता है। - अंतर्निहित कर्नेल सिस्टम कॉल ब्लॉक कर सकता है, जिसके परिणामस्वरूप प्राथमिकता उलटा हो सकता है और परिणामस्वरूप माप गड़बड़ी और अशुद्धियां हो सकती हैं। यह
FastMixer
औरFastCapture
जैसे समय-महत्वपूर्ण धागों के लिए विशेष चिंता का विषय है। - यदि लॉग स्पैम को कम करने के लिए किसी विशेष लॉग को अक्षम किया जाता है, तो उस लॉग द्वारा कैप्चर की गई कोई भी जानकारी खो जाती है। एक विशिष्ट लॉग को पूर्वव्यापी रूप से सक्षम करना संभव नहीं है, यह स्पष्ट हो जाने के बाद कि लॉग दिलचस्प होता।
NBLOG, Media.log, और MediaLogService
NBLOG
API और संबद्ध media.log
प्रक्रिया और MediaLogService
सेवा मिलकर मीडिया के लिए एक नया लॉगिंग सिस्टम बनाते हैं, और विशेष रूप से उपरोक्त मुद्दों को हल करने के लिए डिज़ाइन किए गए हैं। हम तीनों को संदर्भित करने के लिए "मीडिया.लॉग" शब्द का शिथिल रूप से उपयोग करेंगे, लेकिन सख्ती से बोलना NBLOG
C++ लॉगिंग API है, media.log
एक Linux प्रक्रिया का नाम है, और MediaLogService
लॉग की जांच के लिए एक Android बाइंडर सेवा है।
media.log
"समयरेखा" लॉग प्रविष्टियों की एक श्रृंखला है जिसका सापेक्ष क्रम संरक्षित है। परंपरा के अनुसार, प्रत्येक थ्रेड को अपनी टाइमलाइन का उपयोग करना चाहिए।
फ़ायदे
media.log
प्रणाली के लाभ यह हैं कि यह:
- मुख्य लॉग को तब तक स्पैम नहीं करता जब तक और इसकी आवश्यकता न हो।
-
mediaserver
क्रैश या हैंग होने पर भी जांच की जा सकती है। - प्रति समयरेखा गैर-अवरुद्ध है।
- प्रदर्शन के लिए कम अशांति प्रदान करता है। (बेशक लॉगिंग का कोई भी रूप पूरी तरह से गैर-घुसपैठ नहीं है।)
आर्किटेक्चर
media.log
पेश करने से पहले, नीचे दिया गया चित्र mediaserver
प्रक्रिया और init
प्रक्रिया के संबंध को दर्शाता है:

चित्रा 1. Media.log . से पहले वास्तुकला
उल्लेखनीय बिंदु:
-
init
forks औरmediaserver
है। -
init
mediaserver
की मृत्यु का पता लगाता है, और आवश्यकतानुसार पुनः फोर्क करता है। -
ALOGx
लॉगिंग नहीं दिखाया गया है।
media.log
को आर्किटेक्चर में जोड़ने के बाद, नीचे दिया गया चित्र घटकों के नए संबंध को दर्शाता है:

चित्रा 2. Media.log . के बाद वास्तुकला
महत्वपूर्ण परिवर्तन:
- ग्राहक लॉग प्रविष्टियों के निर्माण के लिए
NBLOG
API का उपयोग करते हैं और उन्हें साझा मेमोरी में एक सर्कुलर बफर में जोड़ते हैं। -
MediaLogService
किसी भी समय सर्कुलर बफर की सामग्री को डंप कर सकता है। - सर्कुलर बफ़र इस तरह से डिज़ाइन किया गया है कि साझा मेमोरी का कोई भी भ्रष्टाचार
MediaLogService
को क्रैश नहीं करेगा, और यह अभी भी उतना ही बफ़र डंप करने में सक्षम होगा जो भ्रष्टाचार से प्रभावित नहीं है। - सर्कुलर बफर नई प्रविष्टियां लिखने और मौजूदा प्रविष्टियों को पढ़ने दोनों के लिए गैर-अवरुद्ध और लॉक-फ्री है।
- सर्कुलर बफर (वैकल्पिक टाइमस्टैम्प के अलावा) को लिखने या पढ़ने के लिए किसी कर्नेल सिस्टम कॉल की आवश्यकता नहीं है।
कहां उपयोग करें
Android 4.4 के रूप में, AudioFlinger में केवल कुछ लॉग पॉइंट हैं जो media.log
सिस्टम का उपयोग करते हैं। हालांकि नए API का उपयोग करना ALOGx
जितना आसान नहीं है, लेकिन वे बहुत कठिन भी नहीं हैं। हम आपको उन अवसरों के लिए नई लॉगिंग प्रणाली सीखने के लिए प्रोत्साहित करते हैं जब यह अपरिहार्य हो। विशेष रूप से, ऑडियोफ्लिंगर थ्रेड्स के लिए इसकी अनुशंसा की जाती है जो कि FastMixer
और FastCapture
थ्रेड्स जैसे बार-बार, समय-समय पर और ब्लॉक किए बिना चलना चाहिए।
कैसे इस्तेमाल करे
लॉग जोड़ें
सबसे पहले, आपको अपने कोड में लॉग जोड़ना होगा।
FastMixer
और FastCapture
थ्रेड्स में, इस तरह के कोड का उपयोग करें:
logWriter->log("string"); logWriter->logf("format", parameters); logWriter->logTimestamp();
चूंकि यह NBLog
टाइमलाइन केवल FastMixer
और FastCapture
थ्रेड्स द्वारा उपयोग की जाती है, इसलिए आपसी बहिष्करण की कोई आवश्यकता नहीं है।
अन्य ऑडियोफ्लिंगर थ्रेड्स में, mNBLogWriter
का उपयोग करें:
mNBLogWriter->log("string"); mNBLogWriter->logf("format", parameters); mNBLogWriter->logTimestamp();
FastMixer
और FastCapture
के अलावा अन्य थ्रेड्स के लिए, थ्रेड की NBLog
टाइमलाइन का उपयोग थ्रेड और बाइंडर ऑपरेशंस दोनों द्वारा किया जा सकता है। NBLog::Writer
प्रति टाइमलाइन में कोई अंतर्निहित पारस्परिक बहिष्करण प्रदान नहीं करता है, इसलिए सुनिश्चित करें कि सभी लॉग उस संदर्भ में होते हैं जहां थ्रेड का म्यूटेक्स mLock
होता है।
लॉग जोड़ने के बाद, AudioFlinger को फिर से बनाएं।
सावधानी: थ्रेड सुरक्षा सुनिश्चित करने के लिए प्रति थ्रेड एक अलग NBLog::Writer
टाइमलाइन आवश्यक है, क्योंकि टाइमलाइन डिज़ाइन द्वारा म्यूटेक्स को छोड़ देती है। यदि आप चाहते हैं कि एक से अधिक थ्रेड एक ही टाइमलाइन का उपयोग करें, तो आप मौजूदा म्यूटेक्स से सुरक्षा कर सकते हैं (जैसा कि ऊपर mLock
के लिए वर्णित है)। या आप NBLog::Writer
के बजाय NBLog::LockedWriter
आवरण का उपयोग कर सकते हैं। हालांकि, यह इस एपीआई के एक प्रमुख लाभ को नकारता है: इसका गैर-अवरुद्ध व्यवहार।
पूर्ण NBLog
API frameworks/av/include/media/nbaio/NBLog.h
।
Media.log सक्षम करें
media.log
डिफ़ॉल्ट रूप से अक्षम है। यह तभी सक्रिय होता है जब संपत्ति ro.test_harness
1
हो। आप इसे इसके द्वारा सक्षम कर सकते हैं:
adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot
रिबूट के दौरान कनेक्शन खो जाता है, इसलिए:
adb shellकमांड
ps media
अब दो प्रक्रियाओं को दिखाएगा:- मीडिया.लॉग
- मीडिया सर्वर
बाद के लिए mediaserver
की प्रक्रिया आईडी नोट करें।
समय सारिणी प्रदर्शित करना
आप किसी भी समय लॉग डंप का मैन्युअल रूप से अनुरोध कर सकते हैं। यह आदेश सभी सक्रिय और हाल की समय-सारिणी से लॉग दिखाता है, और फिर उन्हें साफ़ करता है:
dumpsys media.log
ध्यान दें कि डिज़ाइन द्वारा समय-सीमा स्वतंत्र है, और समय-सीमा को मर्ज करने की कोई सुविधा नहीं है।
मीडियासर्वर की मृत्यु के बाद लॉग पुनर्प्राप्त करना
अब mediaserver
प्रक्रिया को मारने का प्रयास करें: kill -9 #
, जहां # वह प्रक्रिया आईडी है जिसे आपने पहले नोट किया था। आपको media.log
से मुख्य logcat
में एक डंप देखना चाहिए, जो क्रैश तक ले जाने वाले सभी लॉग दिखाता है।
dumpsys media.log