এই নিবন্ধে Android অডিও ডিবাগ করার জন্য কিছু পরামর্শ ও কৌশল বর্ণনা করা হয়েছে।
টি সিঙ্ক
"টি সিঙ্ক" হল একটি AudioFlinger ডিবাগিং ফিচার, যা শুধুমাত্র কাস্টম বিল্ডে উপলভ্য, পরবর্তীকালে বিশ্লেষণের জন্য সাম্প্রতিক অডিওর একটি ছোট অংশ ধরে রাখার জন্য। এর ফলে, যা আসলে চালানো বা রেকর্ড করা হয়েছে তার সাথে যা প্রত্যাশিত ছিল তার তুলনা করা যায়।
গোপনীয়তা রক্ষার জন্য, কম্পাইল-টাইম ও রান-টাইম, উভয় ক্ষেত্রেই ডিফল্ট হিসেবে টি সিঙ্ক বন্ধ করা থাকে। টি সিঙ্ক ব্যবহার করতে, আপনাকে আবার কম্পাইল করে এটি চালু করতে হবে, এবং একটি প্রপার্টি সেট করতে হবে। ডিবাগিং করা হয়ে গেলে এই ফিচার বন্ধ করতে ভুলবেন না; প্রোডাকশন বিল্ডে টি সিঙ্ক চালু রাখবেন না।
এই বিভাগে দেওয়া নির্দেশাবলী Android 7.x ও তার পরবর্তী যেকোনও ভার্সনের জন্য। Android
5.x ও 6.x ভার্সনের জন্য, /data/misc/audioserver-এর জায়গায়
/data/misc/media ব্যবহার করুন। এছাড়াও, আপনাকে অবশ্যই userdebug বা
eng বিল্ড ব্যবহার করতে হবে। আপনি যদি userdebug বিল্ড ব্যবহার করেন, তাহলে এটি দিয়ে verity বন্ধ করুন:
adb root && adb disable-verity && adb reboot
কম্পাইল-টাইম সেট-আপ
cd frameworks/av/services/audioflingerConfiguration.hএডিট করুন।- কমেন্ট সরিয়ে দিন
#define TEE_SINK। libaudioflinger.soআবার তৈরি করো।adb rootadb remount- ডিভাইসের
/system/lib-এ নতুনlibaudioflinger.soপুশ বা সিঙ্ক করুন।
রান-টাইম সেট-আপ
adb shell getprop | grep ro.debuggable
আউটপুটটি যে:[ro.debuggable]: [1]তা কনফার্ম করুনadb shellls -ld /data/misc/audioserver
কনফার্ম করুন যে আউটপুট হল:
drwx------ media media ... media
ডিরেক্টরি না থাকলে, এইভাবে তৈরি করুন:
mkdir /data/misc/audioserverchown media:media /data/misc/audioserverecho af.tee=# > /data/local.prop
যেখানেaf.teeভ্যালু হল নিচে বর্ণিত একটি সংখ্যা।chmod 644 /data/local.propreboot
af.tee প্রপার্টির জন্য ভ্যালু
af.tee-এর ভ্যালু হল ০ থেকে ৭-এর মধ্যে একটি সংখ্যা, যা
বিভিন্ন বিটের যোগফলকে প্রকাশ করে, ফিচার পিছু একটি করে বিট।
AudioFlinger.cpp-এ AudioFlinger::AudioFlinger()-এ কোডটি দেখুন
প্রতিটি বিটের ব্যাখ্যা দেওয়া আছে, তবে সংক্ষেপে:
- ১ = ইনপুট
- ২ = FastMixer আউটপুট
- ৪ = পার-ট্র্যাক AudioRecord ও AudioTrack
ডিপ বাফার বা সাধারণ মিক্সারের জন্য এখনও কোনও বিট নেই, তবে আপনি "4" ব্যবহার করে একই ধরনের ফলাফল পেতে পারেন।
ডেটা পরীক্ষা ও সংগ্রহ করা
- আপনার অডিও টেস্ট চালান।
adb shell dumpsys media.audio_flingerdumpsysআউটপুটে এই ধরনের লাইন খুঁজুন:
tee copied to /data/misc/audioserver/20131010101147_2.wav
এটি একটি PCM .wav ফাইল।- তারপরে আগ্রহের
adb pullযেকোনও/data/misc/audioserver/*.wavফাইল; মনে রাখবেন, ট্র্যাক-নির্দিষ্ট ডাম্প ফাইলের নামdumpsysআউটপুটে দেখা যায় না, তবে ট্র্যাক বন্ধ করার পরে সেগুলি/data/misc/audioserver-এ সেভ করা হয়। - অন্যদের সাথে শেয়ার করার আগে গোপনীয়তা সংক্রান্ত উদ্বেগের জন্য ডাম্প ফাইল পর্যালোচনা করুন।
সাজেশন
আরও উপযোগী ফলাফল পেতে এইসব আইডিয়া ব্যবহার করে দেখুন:
- টেস্ট আউটপুটে বাধা কমানোর জন্য টাচ সাউন্ড ও কী ক্লিক বন্ধ করুন।
- সব ভলিউম সর্বাধিক করুন।
- যেসব অ্যাপ মাইক্রোফোন থেকে সাউন্ড তৈরি করে বা রেকর্ড করে, সেগুলি বন্ধ করুন, যদি সেগুলি আপনার পরীক্ষার জন্য প্রাসঙ্গিক না হয়।
- ট্র্যাক বন্ধ করা হলেই শুধু ট্র্যাক-নির্দিষ্ট ডাম্প সেভ করা হয়; ট্র্যাক-নির্দিষ্ট ডেটা ডাম্প করার জন্য আপনাকে অ্যাপ জোর করে বন্ধ করতে হতে পারে
- পরীক্ষার সাথে সাথেই
dumpsysকরুন; রেকর্ডিং স্পেস সীমিত থাকে। - ডাম্প ফাইল যাতে হারিয়ে না যায় তা নিশ্চিত করতে, সেগুলি আপনার হোস্টে পিরিয়ডিক ভিত্তিতে আপলোড করুন। শুধুমাত্র সীমিত সংখ্যক ডাম্প ফাইল সংরক্ষণ করা হয়; সেই সীমায় পৌঁছে গেলে পুরনো ডাম্প ফাইল সরিয়ে দেওয়া হয়।
ফিরিয়ে আনুন
উপরে উল্লেখ করা হয়েছে যে, টি সিঙ্ক ফিচার চালু রাখা উচিত নয়। নিম্নলিখিত পদ্ধতিতে আপনার বিল্ড ও ডিভাইস রিস্টোর করুন:
- সোর্স কোডে করা পরিবর্তন আগের অবস্থায় ফিরিয়ে এনে
Configuration.hকরুন। libaudioflinger.soআবার তৈরি করো।- রিস্টোর করা
libaudioflinger.soডেটা ডিভাইসের/system/lib-এ পুশ বা সিঙ্ক করুন। adb shellrm /data/local.proprm /data/misc/audioserver/*.wavreboot
media.log
ALOGx ম্যাক্রো
Android SDK-তে স্ট্যান্ডার্ড Java ল্যাঙ্গুয়েজ লগিং API হল android.util.Log.
Android NDK-তে সংশ্লিষ্ট C ল্যাঙ্গুয়েজ API হল
__android_log_print
যা <android/log.h>-এ ঘোষণা করা হয়েছে।
Android ফ্রেমওয়ার্কের নেটিভ অংশের মধ্যে, আমরা
ALOGE, ALOGW,
ALOGI, ALOGV ইত্যাদি নামের ম্যাক্রো পছন্দ করি। সেগুলি
<utils/Log.h>-এ ঘোষণা করা হয় এবং এই নিবন্ধের উদ্দেশ্যে
আমরা সেগুলিকে সম্মিলিতভাবে ALOGx হিসেবে উল্লেখ করব।
এইসব API সহজে ব্যবহার করা যায় এবং ভালভাবে বোঝা যায়, তাই Android প্ল্যাটফর্ম জুড়ে
এগুলি ব্যাপকভাবে ব্যবহার করা হয়। বিশেষ করে, mediaserver
প্রসেস, যার মধ্যে AudioFlinger সাউন্ড সার্ভার অন্তর্ভুক্ত, সেটি
ALOGx ব্যাপকভাবে ব্যবহার করে।
তবে, ALOGx ও বন্ধুদের ক্ষেত্রে কিছু সীমাবদ্ধতা আছে:
-
এগুলি "লগ স্প্যাম" দ্বারা প্রভাবিত হতে পারে: লগ বাফার হল একটি শেয়ার করা রিসোর্স
তাই এটি সহজেই অপ্রাসঙ্গিক লগ এন্ট্রির কারণে ওভারফ্লো হতে পারে, যার ফলে
তথ্য মিস হয়ে যেতে পারে।
ALOGVভেরিয়েন্ট ডিফল্ট হিসেবে কম্পাইল-টাইমে বন্ধ করা থাকে। তবে এটি চালু করা থাকলে, এর ফলে লগ স্প্যাম হতে পারে। -
আন্ডারলায়িং কার্নেল সিস্টেম কল ব্লক করতে পারে, এর ফলে সম্ভবত
অগ্রাধিকারের ইনভার্সন এবং ফলস্বরূপ পরিমাপ সংক্রান্ত সমস্যা ও
অনিশ্চয়তা হতে পারে। এটি
FastMixerএবংFastCapture-এর মতো সময়-সংবেদনশীল থ্রেডের ক্ষেত্রে বিশেষভাবে গুরুত্বপূর্ণ। - লগ স্প্যাম কমানোর জন্য কোনও নির্দিষ্ট লগ বন্ধ করা হলে, সেই লগ যে তথ্য ক্যাপচার করত তা আর পাওয়া যায় না। কোনও নির্দিষ্ট লগ, সেটি যে ইন্টারেস্টিং হতে পারত তা স্পষ্ট হয়ে যাওয়ার পরে রেট্রোঅ্যাক্টিভভাবে চালু করা সম্ভব নয়।
NBLOG, media.log ও MediaLogService
NBLOG API এবং সংশ্লিষ্ট media.log
প্রসেস ও MediaLogService
পরিষেবা একসাথে মিডিয়ার জন্য একটি নতুন লগিং সিস্টেম তৈরি করে এবং উপরে উল্লেখ করা সমস্যাগুলি সমাধান করার জন্য বিশেষভাবে
ডিজাইন করা হয়েছে। আমরা এই তিনটিকেই বোঝাতে "media.log" শব্দটি আলগাভাবে ব্যবহার করব, তবে কঠোরভাবে বলতে গেলে NBLOG হল
C++ লগিং API, media.log হল একটি Linux প্রসেস নাম এবং MediaLogService
লগ পরীক্ষা করার জন্য একটি Android বাইন্ডার পরিষেবা।
media.log "টাইমলাইন" হল লগ এন্ট্রির একটি সিরিজ
যেখানে আপেক্ষিক ক্রম বজায় রাখা হয়।
কনভেনশন অনুযায়ী, প্রতিটি থ্রেডের নিজস্ব টাইমলাইন ব্যবহার করা উচিত।
সুবিধা
media.log সিস্টেমের সুবিধা হল যে এটি:
- প্রয়োজন না হলে মূল লগ স্প্যাম করে না।
mediaserverক্র্যাশ বা হ্যাং করলেও পরীক্ষা করা যায়।- প্রতিটি টাইমলাইনের জন্য নন-ব্লকিং।
- পারফর্ম্যান্সের ক্ষেত্রে কম সমস্যা হয়। (অবশ্যই, কোনও ধরনের লগিংই সম্পূর্ণভাবে নন-ইনট্রুসিভ নয়।)
স্থাপত্যশিল্প
media.log চালু করার আগে, নিচের ডায়াগ্রামে mediaserver প্রসেস
ও init প্রসেসের মধ্যে সম্পর্ক দেখানো হয়েছে:
ছবি ১. media.log-এর আগের আর্কিটেকচার
উল্লেখযোগ্য পয়েন্ট:
initforks and execsmediaserver.initmediaserver-এর মৃত্যু শনাক্ত করে এবং প্রয়োজন অনুযায়ী আবার ফর্ক করে।ALOGxলগিং দেখানো হয় না।
নিচের ডায়াগ্রামে কম্পোনেন্টের নতুন সম্পর্ক দেখানো হয়েছে,
media.log আর্কিটেকচারে যোগ করার পরে:
ছবি ২. media.log-এর পরে আর্কিটেকচার।
গুরুত্বপূর্ণ পরিবর্তন:
-
ক্লায়েন্টরা লগ এন্ট্রি তৈরি করতে
NBLOGAPI ব্যবহার করে এবং সেগুলিকে শেয়ার করা মেমরিতে একটি সার্কুলার বাফারে যোগ করে। -
MediaLogServiceযেকোনও সময় সার্কুলার বাফারের কন্টেন্ট ডাম্প করতে পারে। -
সার্কুলার বাফার এমনভাবে ডিজাইন করা হয়েছে যে শেয়ার করা মেমরির
কোনও দুর্নীতি
MediaLogServiceক্র্যাশ করবে না এবং এটি এখনও দুর্নীতি দ্বারা প্রভাবিত হয়নি এমন বাফারের যতটা সম্ভব ডাম্প করতে পারবে। - নতুন এন্ট্রি লেখার এবং আগে থেকে থাকা এন্ট্রি পড়ার, দু'টি ক্ষেত্রেই সার্কুলার বাফার নন-ব্লকিং এবং লক-ফ্রি।
- বৃত্তাকার বাফার (ঐচ্ছিক টাইমস্ট্যাম্প ছাড়া) থেকে লেখা বা পড়ার জন্য কোনও কার্নেল সিস্টেম কল প্রয়োজন হয় না।
কোথায় ব্যবহার করা যাবে
Android 4.4 ভার্সন অনুযায়ী, AudioFlinger-এ
শুধুমাত্র কয়েকটি লগ পয়েন্ট আছে যেগুলি media.log সিস্টেম ব্যবহার করে। নতুন API গুলি ALOGx-এর মতো
সহজে ব্যবহার করা না গেলেও, সেগুলি খুব কঠিনও নয়।
যেসব ক্ষেত্রে লগিং অপরিহার্য, সেইসব ক্ষেত্রে নতুন লগিং সিস্টেম সম্পর্কে
জানতে আমরা আপনাকে উৎসাহিত করি।
বিশেষ করে, এটি AudioFlinger থ্রেডের জন্য সাজেস্ট করা হয় যেগুলিকে অবশ্যই
ঘন ঘন, নির্দিষ্ট সময় অন্তর এবং ব্লক করা ছাড়াই রান করতে হবে, যেমন
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 rootadb shellecho ro.test_harness=1 > /data/local.propchmod 644 /data/local.propreboot
রিবুট করার সময় কানেকশন বিচ্ছিন্ন হয়ে গেছে, তাই:
adb shell
ps media কমান্ডটি এখন দুটি প্রসেস দেখাবে:
- media.log
- mediaserver
পরে দেখার জন্য mediaserver-এর প্রসেস আইডি নোট করে রাখুন।
টাইমলাইন দেখান
আপনি যেকোনও সময় ম্যানুয়ালি লগ ডাম্পের অনুরোধ করতে পারবেন। এই কমান্ডটি সব অ্যাক্টিভ ও সাম্প্রতিক টাইমলাইন থেকে লগ দেখায় এবং তারপরে সেগুলি মুছে দেয়:
dumpsys media.log
মনে রাখবেন, ডিজাইন অনুযায়ী টাইমলাইনগুলি স্বাধীন, এবং টাইমলাইন মার্জ করার কোনও সুবিধা নেই।
mediaserver বন্ধ হয়ে যাওয়ার পরে লগ ফিরিয়ে আনা
এখন mediaserver প্রসেস বন্ধ করার চেষ্টা করুন: kill -9 #, যেখানে # হল
প্রসেস আইডি যা আপনি আগে লিখে রেখেছিলেন। ক্র্যাশ হওয়ার আগে পর্যন্ত সব লগ সহ media.log
থেকে logcat-এ একটি ডাম্প দেখতে পাবেন।
dumpsys media.log