Pemfaktoran Ulang RIL

Android 7.0 memfaktorkan ulang Radio Interface Layer (RIL) menggunakan serangkaian fitur untuk meningkatkan fungsionalitas RIL. Perubahan kode mitra diperlukan untuk menerapkan fitur ini, yang bersifat opsional tetapi dianjurkan. Perubahan pemfaktoran ulang kompatibel ke belakang, jadi implementasi sebelumnya dari fitur pemfaktoran ulang terus berfungsi.

Refactoring RIL mencakup peningkatan berikut:

  • Kode kesalahan RIL. Mengaktifkan kode kesalahan tertentu selain kode GENERIC_FAILURE yang ada. Ini membantu dalam pemecahan masalah kesalahan dengan memberikan informasi yang lebih spesifik tentang penyebab kesalahan.
  • versi RIL. Memberikan informasi versi yang lebih akurat dan lebih mudah untuk dikonfigurasi.
  • Komunikasi RIL menggunakan wakelocks. Meningkatkan kinerja baterai perangkat.

Anda dapat menerapkan salah satu atau semua peningkatan di atas. Untuk detail lebih lanjut, lihat komentar kode pada versi RIL di https://android.googlesource.com/platform/hardware/ril/+/master/include/telephony/ril.h .

Menerapkan kode kesalahan RIL yang ditingkatkan

Hampir semua panggilan permintaan RIL dapat mengembalikan kode kesalahan GENERIC_FAILURE sebagai tanggapan atas kesalahan. Ini adalah masalah dengan semua tanggapan yang diminta yang dikembalikan oleh OEM, yang dapat menyulitkan untuk men-debug masalah dari laporan bug jika kode kesalahan GENERIC_FAILURE yang sama dikembalikan oleh panggilan RIL karena alasan yang berbeda. Vendor membutuhkan waktu yang cukup lama bahkan untuk mengidentifikasi bagian kode mana yang dapat mengembalikan kode GENERIC_FAILURE .

Di Android 7.x dan yang lebih tinggi, OEM dapat mengembalikan nilai kode kesalahan berbeda yang terkait dengan setiap kesalahan berbeda yang saat ini dikategorikan sebagai GENERIC_FAILURE . OEM yang tidak ingin mengungkapkan kode kesalahan khusus mereka secara publik dapat mengembalikan kesalahan sebagai kumpulan bilangan bulat yang berbeda (seperti 1 hingga x) yang dipetakan sebagai OEM_ERROR_1 hingga OEM_ERROR_X . Vendor harus memastikan setiap kode kesalahan terselubung tersebut mengembalikan peta ke alasan kesalahan unik dalam kode. Menggunakan kode kesalahan tertentu dapat mempercepat proses debug RIL setiap kali kesalahan umum dikembalikan oleh OEM, karena seringkali memakan waktu terlalu lama untuk mengidentifikasi penyebab pasti dari kode kesalahan GENERIC_FAILURE (dan terkadang tidak mungkin untuk mengetahuinya).

Selain itu, ril.h menambahkan lebih banyak kode kesalahan untuk enum RIL_LastCallFailCause dan RIL_DataCallFailCause sehingga kode vendor dapat menghindari pengembalian kesalahan umum seperti CALL_FAIL_ERROR_UNSPECIFIED dan PDP_FAIL_ERROR_UNSPECIFIED .

Memvalidasi kode kesalahan RIL yang ditingkatkan

Setelah menambahkan kode kesalahan baru untuk menggantikan kode GENERIC_FAILURE , verifikasi kode kesalahan baru dikembalikan oleh panggilan RIL alih-alih GENERIC_FAILURE .

Menerapkan versi RIL yang ditingkatkan

Versi RIL di rilis Android yang lebih lama bermasalah: versi itu sendiri tidak tepat, mekanisme untuk melaporkan versi RIL tidak jelas (menyebabkan beberapa vendor melaporkan versi yang salah), dan solusi untuk memperkirakan versi rentan terhadap ketidakakuratan.

Di Android 7.x dan yang lebih tinggi, ril.h mendokumentasikan semua nilai versi RIL, menjelaskan versi RIL yang sesuai, dan mencantumkan semua perubahan untuk versi tersebut. Saat membuat perubahan yang sesuai dengan versi RIL, vendor harus memperbarui versi mereka dalam kode dan mengembalikan versi tersebut dalam RIL_REGISTER .

Memvalidasi versi RIL yang ditingkatkan

Verifikasi bahwa versi RIL yang sesuai dengan kode RIL Anda dikembalikan selama RIL_REGISTER (bukan RIL_VERSION yang ditentukan dalam ril.h ).

Menerapkan komunikasi RIL menggunakan wakelocks

Penguncian waktu bangun digunakan dalam komunikasi RIL dengan cara yang tidak tepat, yang berdampak negatif pada kinerja baterai. Di Android 7.x dan yang lebih tinggi, Anda dapat meningkatkan kinerja dengan mengklasifikasikan permintaan RIL dan memperbarui kode untuk menangani wakelock secara berbeda untuk jenis permintaan yang berbeda.

Mengklasifikasikan permintaan RIL

Permintaan RIL dapat berupa diminta atau tidak diminta. Vendor harus mengklasifikasikan permintaan yang diminta lebih lanjut sebagai salah satu dari berikut ini:

  • sinkron . Permintaan yang tidak membutuhkan waktu lama untuk ditanggapi kembali. Misalnya, RIL_REQUEST_GET_SIM_STATUS .
  • asinkron . Permintaan yang membutuhkan waktu cukup lama untuk ditanggapi kembali. Misalnya, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS .

Permintaan RIL yang diminta secara asinkron dapat memakan waktu yang cukup lama. Setelah menerima ack dari kode vendor, RIL Java melepaskan wakelock, yang mungkin menyebabkan prosesor aplikasi beralih dari status idle ke status menangguhkan. Ketika respons tersedia dari kode vendor, RIL Java (prosesor aplikasi) memperoleh kembali wakelock, memproses respons, lalu kembali ke idle. Perpindahan dari idle ke suspend ke idle seperti itu dapat menghabiskan banyak daya.

Jika waktu respons tidak cukup lama, menahan wakelock dan tetap diam selama waktu yang diperlukan untuk merespons dapat lebih hemat daya daripada masuk ke status tunda dengan melepaskan wakelock dan bangun saat respons tiba. Vendor harus menggunakan pengukuran daya khusus platform untuk menentukan nilai ambang batas waktu T ketika daya yang dikonsumsi dengan tetap diam selama T lebih besar daripada daya yang dikonsumsi dengan berpindah dari diam ke tunda dan ke idle dalam waktu yang sama T . Ketika waktu T diketahui, perintah RIL yang memakan waktu lebih dari waktu T dapat diklasifikasikan sebagai asinkron dan perintah yang tersisa diklasifikasikan sebagai sinkron.

Skenario komunikasi RIL

Diagram berikut mengilustrasikan skenario komunikasi RIL umum dan memberikan solusi untuk memodifikasi kode untuk menangani permintaan RIL yang diminta dan tidak diminta.

Catatan: Untuk detail implementasi tentang fungsi yang digunakan dalam diagram berikut, lihat metode acquireWakeLock() , decrementWakeLock() , dan clearWakeLock( ) di ril.cpp .

Skenario: Permintaan RIL dan respons asinkron yang diminta

Dalam skenario ini, jika respons yang diminta RIL diperkirakan akan memakan waktu yang cukup lama (yaitu respons terhadap RIL_REQUEST_GET_AVAILABLE_NETWORKS ), penguncian layar ditahan untuk waktu yang lama di sisi prosesor aplikasi. Masalah modem juga dapat mengakibatkan menunggu lama.

Gambar 1. RIL meminta respons asinkron.

Solusi 1: Modem menahan wakelock untuk permintaan RIL dan respons asinkron.

Gambar 2. Wakelock dipegang oleh modem.
  1. Permintaan RIL dikirim dan modem memperoleh wakelock untuk memproses permintaan itu.
  2. Modem mengirimkan pengakuan yang menyebabkan sisi Java mengurangi penghitung wakelock dan melepaskannya ketika nilai penghitung adalah 0.

    Catatan: Durasi wakelock timeout untuk urutan request-ack akan lebih kecil daripada durasi timeout yang digunakan saat ini karena ack harus diterima dengan cukup cepat.

  3. Setelah memproses permintaan, modem mengirimkan interupsi ke kode vendor yang memperoleh wakelock dan mengirimkan respons ke ril.cpp, yang pada gilirannya memperoleh wakelock dan mengirimkan respons ke sisi Java.
  4. Ketika respons mencapai sisi Java, wakelock diperoleh dan respons dikembalikan ke pemanggil.
  5. Setelah respons diproses oleh semua modul, pengakuan dikirim (melalui socket) kembali ke ril.cpp , yang kemudian melepaskan wakelock yang diperoleh pada langkah 3.

Solusi 2: Modem tidak menahan wakelock dan responsnya cepat (permintaan dan respons RIL sinkron). Perilaku sinkron vs. asinkron dikodekan untuk perintah RIL tertentu dan diputuskan berdasarkan panggilan-per-panggilan.

Gambar 3. Wakelock tidak dipegang oleh modem.
  1. Permintaan RIL dikirim dengan memanggil acquireWakeLock() di sisi Java.
  2. Kode vendor tidak perlu mendapatkan wakelock dan dapat memproses permintaan dan merespons dengan cepat.
  3. Ketika respons diterima oleh sisi Java, decrementWakeLock() dipanggil, yang menurunkan penghitung wakelock dan melepaskan wakelock jika nilai penghitung adalah 0.

Skenario: RIL tanggapan yang tidak diminta

Dalam skenario ini, respons yang tidak diminta RIL memiliki tanda jenis wakelock yang menunjukkan apakah wakelock perlu diperoleh untuk respons vendor. Jika flag disetel, wakelock berwaktu diatur dan respons dikirim melalui soket ke sisi Java. Ketika timer berakhir, wakelock dilepaskan. Waktu wakelock bisa terlalu panjang atau terlalu pendek untuk berbagai respons RIL yang tidak diminta.

Gambar 4. Respon RIL yang tidak diminta.

Solusi: Pengakuan dikirim dari kode Java ke sisi asli ( ril.cpp ) alih-alih menahan wakelock berwaktu di sisi asli saat mengirim respons yang tidak diminta.

Gambar 5. Menggunakan ack alih-alih wakelock berwaktu.

Memvalidasi wakelock yang didesain ulang

Verifikasi bahwa panggilan RIL diidentifikasi sebagai sinkron atau asinkron. Karena konsumsi daya baterai dapat bergantung pada perangkat keras/platform, vendor harus melakukan beberapa pengujian internal untuk mengetahui apakah menggunakan semantik wakelock baru untuk panggilan asinkron dapat menghemat daya baterai.