RIL Refactoring

Android 7.0 لایه رابط رادیویی (RIL) را با استفاده از مجموعه‌ای از ویژگی‌ها برای بهبود عملکرد RIL بازسازی کرد. تغییرات کد شریک برای پیاده سازی این ویژگی ها لازم است، که اختیاری هستند اما تشویق می شوند. تغییرات Refactoring سازگار با عقب هستند، بنابراین پیاده سازی های قبلی ویژگی های refactored به کار خود ادامه می دهند.

بازسازی RIL شامل بهبودهای زیر است:

  • کدهای خطای RIL کدهای خطای خاصی را علاوه بر کد GENERIC_FAILURE موجود فعال می کند. این به عیب یابی خطا با ارائه اطلاعات دقیق تر در مورد علت خطاها کمک می کند.
  • نسخه RIL. اطلاعات نسخه دقیق تر و آسان تر را برای پیکربندی ارائه می دهد.
  • ارتباط RIL با استفاده از wakelocks. عملکرد باتری دستگاه را بهبود می بخشد.

شما می توانید هر یک یا همه بهبودهای فوق را اجرا کنید. برای جزئیات بیشتر، به نظرات کد در مورد نسخه‌سازی RIL در https://android.googlesource.com/platform/hardware/ril/+/main/include/telephony/ril.h مراجعه کنید.

پیاده سازی کدهای خطای RIL پیشرفته

تقریباً همه تماس‌های درخواست RIL می‌توانند کد خطای GENERIC_FAILURE را در پاسخ به یک خطا برگردانند. این یک مشکل با همه پاسخ‌های درخواستی است که توسط OEMها برگردانده می‌شود، که می‌تواند اشکال‌زدایی یک مشکل را از گزارش اشکال دشوار کند اگر همان کد خطا GENERIC_FAILURE توسط تماس‌های RIL به دلایل مختلف برگردانده شود. حتی تشخیص اینکه چه بخشی از کد می‌تواند کد GENERIC_FAILURE را برگرداند، ممکن است زمان قابل‌توجهی طول بکشد.

در Android 7.x و بالاتر، OEM ها می توانند مقدار کد خطای متمایز مرتبط با هر خطای متفاوتی را که در حال حاضر به عنوان GENERIC_FAILURE طبقه بندی می شود، برگردانند. OEM هایی که نمی خواهند کدهای خطای سفارشی خود را به صورت عمومی فاش کنند، می توانند خطاها را به صورت مجموعه ای متمایز از اعداد صحیح (مانند 1 تا x) نگاشت شده به عنوان OEM_ERROR_1 به OEM_ERROR_X برگردانند. فروشندگان باید اطمینان حاصل کنند که هر کد خطای پنهان شده، نقشه ها را به دلیل خطای منحصر به فردی در کد بازگردانده است. استفاده از کدهای خطای خاص می تواند اشکال زدایی RIL را هر زمان که خطاهای عمومی توسط OEM برگردانده می شود سرعت بخشد، زیرا شناسایی علت دقیق کد خطای GENERIC_FAILURE اغلب زمان زیادی می برد (و گاهی اوقات تشخیص آن غیرممکن است).

علاوه بر این، ril.h کدهای خطای بیشتری را برای enums RIL_LastCallFailCause و RIL_DataCallFailCause اضافه می کند تا کد فروشنده بتواند از بازگرداندن خطاهای عمومی مانند CALL_FAIL_ERROR_UNSPECIFIED و PDP_FAIL_ERROR_UNSPECIFIED جلوگیری کند.

اعتبار سنجی کدهای خطای RIL پیشرفته

پس از افزودن کدهای خطای جدید برای جایگزینی کد GENERIC_FAILURE ، بررسی کنید که کدهای خطای جدید با تماس RIL به جای GENERIC_FAILURE برگردانده شوند.

پیاده سازی نسخه سازی پیشرفته RIL

نسخه RIL در نسخه‌های قدیمی‌تر اندروید مشکل‌ساز بود: خود نسخه نادقیق بود، مکانیسم گزارش یک نسخه RIL نامشخص بود (که باعث می‌شد برخی از فروشندگان نسخه نادرست را گزارش کنند)، و راه‌حل برای تخمین نسخه مستعد عدم دقت بود.

در Android 7.x و بالاتر، ril.h تمام مقادیر نسخه RIL را مستند می کند، نسخه RIL مربوطه را توصیف می کند و همه تغییرات آن نسخه را فهرست می کند. هنگام ایجاد تغییراتی که مربوط به یک نسخه RIL است، فروشندگان باید نسخه خود را به صورت کد به روز کنند و آن نسخه را در RIL_REGISTER برگردانند.

اعتبار سنجی نسخه RIL پیشرفته

بررسی کنید که نسخه RIL مربوط به کد RIL شما در طول RIL_REGISTER (به جای RIL_VERSION تعریف شده در ril.h ) برگردانده شود.

پیاده سازی ارتباط RIL با استفاده از wakelocks

wakelockهای زماندار در ارتباطات RIL به روشی غیر دقیق استفاده می شوند که بر عملکرد باتری تأثیر منفی می گذارد. در Android 7.x و بالاتر، می‌توانید با طبقه‌بندی درخواست‌های RIL و به‌روزرسانی کد برای مدیریت متفاوت wakelockها برای انواع مختلف درخواست، عملکرد را بهبود بخشید.

طبقه بندی درخواست های RIL

درخواست های RIL می تواند درخواستی یا ناخواسته باشد. فروشندگان باید بیشتر درخواست های درخواست شده را به عنوان یکی از موارد زیر طبقه بندی کنند:

  • همزمان . درخواست هایی که پاسخگویی به آنها زمان زیادی نمی برد. برای مثال، RIL_REQUEST_GET_SIM_STATUS .
  • نامتقارن . درخواست هایی که پاسخ دادن به آنها زمان زیادی می برد. برای مثال، RIL_REQUEST_QUERY_AVAILABLE_NETWORKS .

درخواست های RIL درخواستی ناهمزمان می تواند زمان قابل توجهی را ببرد. پس از دریافت تایید از کد فروشنده، RIL جاوا wakelock را آزاد می کند، که ممکن است باعث شود پردازنده برنامه از حالت بیکار به حالت تعلیق برود. هنگامی که پاسخ از کد فروشنده در دسترس است، RIL Java (پردازنده برنامه) دوباره wakelock را دریافت می کند، پاسخ را پردازش می کند و سپس به حالت بیکار باز می گردد. چنین حرکتی از حالت بیکار به حالت تعلیق به حالت بیکار می تواند انرژی زیادی را مصرف کند.

اگر زمان پاسخ به اندازه کافی طولانی نباشد، نگه داشتن wakelock و بیکار ماندن برای تمام مدت زمانی که برای پاسخ دادن نیاز است، می تواند نسبت به حالت تعلیق با رها کردن wakelock و بیدار شدن در هنگام رسیدن پاسخ، کارآمدتر باشد. فروشندگان باید از اندازه‌گیری‌های توان مخصوص پلت فرم برای تعیین مقدار آستانه زمان T استفاده کنند، زمانی که توان مصرف شده با بی‌حرکت ماندن در تمام مدت T بیشتر از توان مصرف شده با حرکت از حالت بی‌کار به حالت تعلیق و بی‌حرکتی در همان زمان T است. وقتی زمان T مشخص باشد، دستورات RIL که بیش از زمان T طول می کشد را می توان به عنوان ناهمزمان و بقیه دستورات را به عنوان همزمان طبقه بندی کرد.

سناریوهای ارتباطی RIL

نمودارهای زیر سناریوهای رایج ارتباط RIL را نشان می‌دهند و راه‌حل‌هایی برای اصلاح کد برای رسیدگی به درخواست‌های درخواستی و ناخواسته RIL ارائه می‌دهند.

توجه: برای جزئیات پیاده سازی در مورد توابع استفاده شده در نمودارهای زیر، به متدهای acquireWakeLock() ، decrementWakeLock() و clearWakeLock( ) در ril.cpp مراجعه کنید.

سناریو: درخواست RIL و پاسخ ناهمزمان درخواست شده

در این سناریو، اگر انتظار می‌رود که پاسخ درخواستی RIL به زمان قابل توجهی نیاز داشته باشد (یعنی پاسخ به RIL_REQUEST_GET_AVAILABLE_NETWORKS )، wakelock برای مدت طولانی در سمت پردازنده برنامه نگه داشته می‌شود. مشکلات مودم همچنین می تواند منجر به انتظار طولانی شود.

شکل 1. RIL درخواست پاسخ ناهمزمان.

راه حل 1: مودم wakelock را برای درخواست RIL و پاسخ ناهمزمان نگه می دارد.

شکل 2. Wakelock توسط مودم نگه داشته شده است.
  1. درخواست RIL ارسال می شود و مودم wakelock را برای پردازش آن درخواست دریافت می کند.
  2. مودم تصدیق ارسال می کند که باعث می شود سمت جاوا شمارنده wakelock را کاهش دهد و زمانی که مقدار شمارنده 0 باشد آن را آزاد می کند.

    توجه: مدت زمان وقفه wakelock برای دنباله درخواست-ack کمتر از مدت زمان استفاده کنونی است زیرا ack باید نسبتاً سریع دریافت شود.

  3. پس از پردازش درخواست، مودم یک وقفه به کد فروشنده می‌فرستد که wakelock را دریافت می‌کند و پاسخی را به ril.cpp می‌فرستد، که به نوبه خود wakelock را دریافت می‌کند و پاسخی را به سمت جاوا می‌فرستد.
  4. هنگامی که پاسخ به سمت جاوا می رسد، wakelock بدست می آید و یک پاسخ به تماس گیرنده برگردانده می شود.
  5. پس از پردازش پاسخ توسط همه ماژول ها، تایید (از طریق سوکت) به ril.cpp ارسال می شود، که سپس wakelock بدست آمده در مرحله 3 را آزاد می کند.

راه حل 2: مودم wakelock را نگه نمی دارد و پاسخ سریع است (درخواست و پاسخ RIL همزمان). رفتار همزمان در مقابل ناهمزمان برای یک دستور RIL خاص کدگذاری شده است و بر روی یک فراخوانی به صورت فراخوانی تصمیم گیری می شود.

شکل 3. Wakelock توسط مودم نگهداری نمی شود.
  1. درخواست RIL با فراخوانی acquireWakeLock() در سمت جاوا ارسال می شود.
  2. کد فروشنده نیازی به دریافت wakelock ندارد و می تواند درخواست را پردازش کرده و به سرعت پاسخ دهد.
  3. هنگامی که پاسخ توسط سمت جاوا دریافت می شود، decrementWakeLock() فراخوانی می شود که شمارنده wakelock را کاهش می دهد و اگر مقدار شمارنده 0 باشد wakelock را آزاد می کند.

سناریو: پاسخ ناخواسته RIL

در این سناریو، پاسخ‌های ناخواسته RIL دارای یک پرچم نوع wakelock هستند که نشان می‌دهد آیا باید یک wakelock برای پاسخ فروشنده خریداری شود یا خیر. اگر پرچم تنظیم شده باشد، یک wakelock زمان‌بندی شده تنظیم می‌شود و پاسخ از طریق یک سوکت به سمت جاوا ارسال می‌شود. هنگامی که تایمر منقضی می شود، wakelock آزاد می شود. wakelock زمان‌بندی‌شده می‌تواند برای پاسخ‌های ناخواسته RIL بسیار طولانی یا خیلی کوتاه باشد.

شکل 4. پاسخ ناخواسته RIL.

راه حل: به جای نگه داشتن یک wakelock زمان بندی شده در سمت بومی و در حین ارسال یک پاسخ ناخواسته، یک تأیید از کد جاوا به سمت اصلی ( ril.cpp ) ارسال می شود.

شکل 5. استفاده از ack به جای wakelock زماندار.

اعتبار سنجی wakelockهای بازطراحی شده

بررسی کنید که تماس های RIL به عنوان همزمان یا ناهمزمان شناسایی شوند. از آنجایی که مصرف انرژی باتری می‌تواند وابسته به سخت‌افزار/پلتفرم باشد، فروشندگان باید آزمایش‌های داخلی انجام دهند تا دریابند که آیا استفاده از معنای wakelock جدید برای تماس‌های ناهمزمان منجر به صرفه‌جویی در مصرف باتری می‌شود یا خیر.