এই নিবন্ধটি Android অডিও ডিবাগ করার জন্য কিছু টিপস এবং কৌশল বর্ণনা করে।
টি সিঙ্ক
"টি সিঙ্ক" হল একটি AudioFlinger ডিবাগিং বৈশিষ্ট্য, যা শুধুমাত্র কাস্টম বিল্ডে উপলব্ধ, সাম্প্রতিক অডিওর একটি ছোট অংশ পরবর্তী বিশ্লেষণের জন্য ধরে রাখার জন্য। এটি বাস্তবে যা বাজানো বা রেকর্ড করা হয়েছে বনাম যা প্রত্যাশিত ছিল তার মধ্যে তুলনা করার অনুমতি দেয়।
গোপনীয়তার জন্য কম্পাইল-টাইম এবং রান-টাইম উভয় সময়েই টি সিঙ্ক ডিফল্টরূপে নিষ্ক্রিয় থাকে। টি সিঙ্ক ব্যবহার করার জন্য, আপনাকে এটি পুনরায় কম্পাইল করে এবং একটি সম্পত্তি সেট করে সক্ষম করতে হবে। আপনি ডিবাগিং সম্পন্ন করার পরে এই বৈশিষ্ট্যটি নিষ্ক্রিয় করতে ভুলবেন না; টি-সিঙ্ককে প্রোডাকশন বিল্ডে সক্রিয় রেখে দেওয়া উচিত নয়।
এই বিভাগে নির্দেশাবলী Android 7.x এবং উচ্চতর সংস্করণের জন্য। Android 5.x এবং 6.x-এর জন্য, /data/misc/audioserver
/data/misc/media
দিয়ে প্রতিস্থাপন করুন। অতিরিক্তভাবে, আপনাকে অবশ্যই একটি userdebug বা eng বিল্ড ব্যবহার করতে হবে। আপনি যদি একটি userdebug বিল্ড ব্যবহার করেন, তাহলে এর সাথে সত্যতা অক্ষম করুন:
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.cpp
এ AudioFlinger::AudioFlinger()
কোডটি দেখুন, কিন্তু সংক্ষেপে:
- 1 = ইনপুট
- 2 = ফাস্টমিক্সার আউটপুট
- 4 = প্রতি-ট্র্যাক AudioRecord এবং AudioTrack
ডিপ বাফার বা সাধারণ মিক্সারের জন্য এখনও কোনও বিট নেই, তবে আপনি "4" ব্যবহার করে একই ফলাফল পেতে পারেন।
পরীক্ষা এবং তথ্য অর্জন
- আপনার অডিও পরীক্ষা চালান.
-
adb shell dumpsys media.audio_flinger
-
dumpsys
আউটপুটে একটি লাইন সন্ধান করুন যেমন:
tee copied to /data/misc/audioserver/20131010101147_2.wav
এটি একটি PCM .wav ফাইল। - তারপর adb আগ্রহের যেকোনো
/data/misc/audioserver/*.wav
ফাইলadb pull
; মনে রাখবেন যে ট্র্যাক-নির্দিষ্ট ডাম্প ফাইলের নাম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
media.log
ALOGx ম্যাক্রো
অ্যান্ড্রয়েড এসডিকে-তে স্ট্যান্ডার্ড জাভা ল্যাঙ্গুয়েজ লগিং API হল android.util.Log ।
Android NDK-তে সংশ্লিষ্ট C ভাষা API হল __android_log_print
ঘোষিত <android/log.h>
।
অ্যান্ড্রয়েড ফ্রেমওয়ার্কের স্থানীয় অংশের মধ্যে, আমরা ALOGE
, ALOGW
, ALOGI
, ALOGV
, ইত্যাদি নামের ম্যাক্রো পছন্দ করি। সেগুলি <utils/Log.h>
এ ঘোষণা করা হয়েছে, এবং এই নিবন্ধটির উদ্দেশ্যে আমরা তাদের সম্মিলিতভাবে ALOGx
হিসাবে উল্লেখ করব .
এই সমস্ত APIগুলি ব্যবহার করা সহজ এবং ভালভাবে বোঝা যায়, তাই তারা অ্যান্ড্রয়েড প্ল্যাটফর্ম জুড়ে বিস্তৃত৷ বিশেষ করে mediaserver
প্রক্রিয়া, যার মধ্যে অডিওফ্লিংগার সাউন্ড সার্ভার রয়েছে, ব্যাপকভাবে ALOGx
ব্যবহার করে।
তবুও, ALOGx
এবং বন্ধুদের কিছু সীমাবদ্ধতা রয়েছে:
- তারা "লগ স্প্যাম"-এর জন্য সংবেদনশীল: লগ বাফার একটি শেয়ার্ড রিসোর্স তাই এটি অসংলগ্ন লগ এন্ট্রির কারণে সহজেই ওভারফ্লো হতে পারে, ফলে তথ্য মিস হয়ে যায়।
ALOGV
ভেরিয়েন্ট ডিফল্টরূপে কম্পাইল-টাইমে নিষ্ক্রিয় করা হয়। তবে অবশ্যই এটি সক্রিয় থাকলে লগ স্প্যাম হতে পারে। - অন্তর্নিহিত কার্নেল সিস্টেম কলগুলি ব্লক করতে পারে, সম্ভবত অগ্রাধিকার বিপরীতে পরিণত হতে পারে এবং ফলস্বরূপ পরিমাপের ব্যাঘাত এবং ভুল।
FastMixer
এবংFastCapture
মতো সময়-সমালোচনামূলক থ্রেডগুলির জন্য এটি বিশেষ উদ্বেগের বিষয়। - যদি লগ স্প্যাম কমাতে একটি নির্দিষ্ট লগ অক্ষম করা হয়, তাহলে সেই লগ দ্বারা ক্যাপচার করা যেকোন তথ্য হারিয়ে যাবে। লগটি আকর্ষণীয় হবে তা স্পষ্ট হয়ে যাওয়ার পরে পূর্ববর্তীভাবে একটি নির্দিষ্ট লগ সক্রিয় করা সম্ভব নয়।
NBLOG, media.log, এবং MediaLogService
NBLOG
APIs এবং সংশ্লিষ্ট media.log
প্রক্রিয়া এবং MediaLogService
পরিষেবা একসাথে মিডিয়ার জন্য একটি নতুন লগিং সিস্টেম গঠন করে, এবং বিশেষভাবে উপরের সমস্যাগুলি সমাধান করার জন্য ডিজাইন করা হয়েছে৷ আমরা তিনটির উল্লেখ করার জন্য "media.log" শব্দটি ঢিলেঢালাভাবে ব্যবহার করব, কিন্তু কঠোরভাবে বলতে গেলে NBLOG
হল C++ লগিং API, media.log
হল একটি Linux প্রক্রিয়ার নাম, এবং MediaLogService
হল লগগুলি পরীক্ষা করার জন্য একটি Android বাইন্ডার পরিষেবা৷
একটি media.log
"টাইমলাইন" হল লগ এন্ট্রিগুলির একটি সিরিজ যার আপেক্ষিক ক্রম সংরক্ষিত থাকে৷ নিয়ম অনুসারে, প্রতিটি থ্রেডের নিজস্ব টাইমলাইন ব্যবহার করা উচিত।
সুবিধা
media.log
সিস্টেমের সুবিধা হল এটি:
- মূল লগ স্প্যাম করে না যদি না এবং যতক্ষণ না এটি প্রয়োজন হয়।
-
mediaserver
ক্র্যাশ বা হ্যাং হয়ে গেলেও পরীক্ষা করা যেতে পারে। - টাইমলাইন প্রতি অ-ব্লক করা হয়.
- কর্মক্ষমতা কম ব্যাঘাত অফার. (অবশ্যই কোন প্রকার লগিং সম্পূর্ণরূপে অ-অনুপ্রবেশকারী নয়।)
স্থাপত্য
নিচের চিত্রটি media.log
চালু করার আগে mediaserver
প্রক্রিয়া এবং init
প্রক্রিয়ার সম্পর্ক দেখায়:
উল্লেখযোগ্য পয়েন্ট:
-
init
forks এবং execsmediaserver
। -
init
mediaserver
মৃত্যু শনাক্ত করে এবং প্রয়োজনে পুনরায় কাঁটাচামচ করে। -
ALOGx
লগিং দেখানো হয় না।
media.log
আর্কিটেকচারে যোগ করার পরে নীচের চিত্রটি উপাদানগুলির নতুন সম্পর্ক দেখায়:
গুরুত্বপূর্ণ পরিবর্তন:
- ক্লায়েন্টরা লগ এন্ট্রি তৈরি করতে
NBLOG
API ব্যবহার করে এবং শেয়ার করা মেমরিতে একটি বৃত্তাকার বাফারে যুক্ত করে। -
MediaLogService
যেকোনো সময় সার্কুলার বাফারের বিষয়বস্তু ডাম্প করতে পারে। - সার্কুলার বাফারটি এমনভাবে ডিজাইন করা হয়েছে যাতে শেয়ার করা মেমরির কোনো দুর্নীতি
MediaLogService
ক্র্যাশ করবে না এবং এটি এখনও দুর্নীতির দ্বারা প্রভাবিত না হওয়া বাফারের বেশি পরিমাণ ডাম্প করতে সক্ষম হবে। - নতুন এন্ট্রি লেখা এবং বিদ্যমান এন্ট্রি পড়ার জন্য সার্কুলার বাফারটি নন-ব্লকিং এবং লক-মুক্ত।
- সার্কুলার বাফার থেকে (ঐচ্ছিক টাইমস্ট্যাম্প ছাড়া) লিখতে বা পড়ার জন্য কোন কার্নেল সিস্টেম কলের প্রয়োজন নেই।
কোথায় ব্যবহার করতে হবে
অ্যান্ড্রয়েড 4.4 হিসাবে, AudioFlinger-এ শুধুমাত্র কয়েকটি লগ পয়েন্ট রয়েছে যা media.log
সিস্টেম ব্যবহার করে। যদিও নতুন API গুলি ALOGx
এর মতো ব্যবহার করা সহজ নয়, তবে সেগুলি খুব কঠিনও নয়৷ আমরা আপনাকে সেই অনুষ্ঠানগুলির জন্য নতুন লগিং সিস্টেম শিখতে উত্সাহিত করি যখন এটি অপরিহার্য। বিশেষ করে, এটি অডিওফ্লিঙ্গার থ্রেডগুলির জন্য সুপারিশ করা হয় যেগুলি অবশ্যই ঘন ঘন, পর্যায়ক্রমে এবং ব্লক না করে যেমন FastMixer
এবং FastCapture
থ্রেডগুলি চালাতে হবে৷
কিভাবে ব্যবহার করবেন
লগ যোগ করুন
প্রথমত, আপনাকে আপনার কোডে লগ যোগ করতে হবে।
FastMixer
এবং FastCapture
থ্রেডগুলিতে, কোড ব্যবহার করুন যেমন:
logWriter->log("string"); logWriter->logf("format", parameters); logWriter->logTimestamp();
যেহেতু এই NBLog
টাইমলাইনটি শুধুমাত্র FastMixer
এবং FastCapture
থ্রেড দ্বারা ব্যবহৃত হয়, তাই পারস্পরিক বর্জনের কোন প্রয়োজন নেই।
অন্যান্য AudioFlinger থ্রেডে, mNBLogWriter
ব্যবহার করুন:
mNBLogWriter->log("string"); mNBLogWriter->logf("format", parameters); mNBLogWriter->logTimestamp();
FastMixer
এবং FastCapture
ব্যতীত অন্য থ্রেডের জন্য, থ্রেডের NBLog
টাইমলাইন থ্রেড নিজেই এবং বাইন্ডার অপারেশন উভয় দ্বারা ব্যবহার করা যেতে পারে। NBLog::Writer
প্রতি টাইমলাইনে কোনো অন্তর্নিহিত পারস্পরিক বর্জন প্রদান করে না, তাই নিশ্চিত হন যে সমস্ত লগ এমন একটি প্রেক্ষাপটের মধ্যে ঘটে যেখানে থ্রেডের মিউটেক্স mLock
রাখা হয়।
আপনি লগ যোগ করার পরে, AudioFlinger পুনরায় তৈরি করুন.
সতর্কতা: একটি পৃথক NBLog::Writer
টাইমলাইন প্রয়োজন, যেহেতু টাইমলাইন ডিজাইন অনুসারে মিউটেক্স বাদ দেয়। আপনি যদি একই টাইমলাইনে একাধিক থ্রেড ব্যবহার করতে চান তবে আপনি একটি বিদ্যমান মিউটেক্সের সাথে রক্ষা করতে পারেন (যেমন mLock
এর জন্য উপরে বর্ণিত হয়েছে)। অথবা আপনি NBLog::Writer
এর পরিবর্তে NBLog::LockedWriter
র্যাপার ব্যবহার করতে পারেন। যাইহোক, এটি এই API এর একটি প্রধান সুবিধাকে অস্বীকার করে: এর অ-ব্লকিং আচরণ।
সম্পূর্ণ 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
এখন দুটি প্রক্রিয়া দেখাবে:- media.log
- মিডিয়া সার্ভার
পরবর্তীতে mediaserver
প্রসেস আইডি নোট করুন।
টাইমলাইন প্রদর্শন করুন
আপনি যেকোনো সময় ম্যানুয়ালি লগ ডাম্পের অনুরোধ করতে পারেন। এই কমান্ডটি সমস্ত সক্রিয় এবং সাম্প্রতিক টাইমলাইন থেকে লগ দেখায় এবং তারপরে সেগুলি সাফ করে:
dumpsys media.log
নোট করুন যে ডিজাইনের টাইমলাইনগুলি স্বাধীন, এবং টাইমলাইনগুলিকে একত্রিত করার কোনও সুবিধা নেই৷
মিডিয়া সার্ভারের মৃত্যুর পরে লগ পুনরুদ্ধার করুন
এখন mediaserver
প্রক্রিয়াকে হত্যা করার চেষ্টা করুন: kill -9 #
, যেখানে # আপনি আগে উল্লেখ করেছেন প্রসেস আইডি। আপনি প্রধান logcat
এ media.log
থেকে একটি ডাম্প দেখতে পাবেন, যা ক্র্যাশের দিকে অগ্রসর হওয়া সমস্ত লগ দেখাচ্ছে৷
dumpsys media.log