Pemfaktoran Ulang RIL

Android 7.0 memfaktorkan ulang Lapisan Antarmuka Radio (RIL) menggunakan serangkaian fitur untuk meningkatkan fungsionalitas RIL. Perubahan kode mitra diperlukan untuk menerapkan fitur ini, yang bersifat opsional namun dianjurkan. Perubahan pemfaktoran ulang bersifat kompatibel, sehingga implementasi sebelumnya dari fitur yang difaktorkan ulang akan tetap berfungsi.

Refactoring RIL mencakup perbaikan berikut:

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

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

Menerapkan kode kesalahan RIL yang ditingkatkan

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

Di Android 7.x dan 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 berbeda (misalnya 1 hingga x) yang dipetakan sebagai OEM_ERROR_1 hingga OEM_ERROR_X . Vendor harus memastikan setiap kode kesalahan terselubung 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 memerlukan terlalu banyak waktu 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 munculnya 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 bahwa kode kesalahan baru dikembalikan oleh panggilan RIL, bukan GENERIC_FAILURE .

Menerapkan versi RIL yang ditingkatkan

Pembuatan versi RIL pada rilis Android lama bermasalah: versinya sendiri tidak tepat, mekanisme pelaporan versi RIL tidak jelas (menyebabkan beberapa vendor melaporkan versi yang salah), dan solusi untuk memperkirakan versi tersebut rentan terhadap ketidakakuratan.

Di Android 7.x dan 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 kode mereka 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 aktif digunakan dalam komunikasi RIL dengan cara yang tidak tepat, sehingga berdampak negatif terhadap kinerja baterai. Di Android 7.x dan lebih tinggi, Anda dapat meningkatkan performa dengan mengklasifikasikan permintaan RIL dan memperbarui kode untuk menangani wakelock secara berbeda untuk jenis permintaan berbeda.

Mengklasifikasikan permintaan RIL

Permintaan RIL bisa diminta atau tidak diminta. Vendor selanjutnya harus mengklasifikasikan permintaan yang diminta sebagai salah satu dari berikut ini:

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

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

Jika waktu respons tidak cukup lama, menahan penguncian layar saat aktif dan tetap diam selama waktu yang diperlukan untuk merespons dapat lebih menghemat daya daripada masuk ke status penangguhan dengan melepaskan penguncian layar dan membangunkan saat respons tiba. Vendor harus menggunakan pengukuran daya spesifik platform untuk menentukan nilai ambang batas waktu T ketika daya yang dikonsumsi dengan tetap berada dalam kondisi idle sepanjang waktu T lebih besar daripada daya yang dikonsumsi dengan berpindah dari idle ke suspend 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 lainnya diklasifikasikan sebagai sinkron.

Skenario komunikasi RIL

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

Catatan: Untuk detail implementasi 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 lama (yaitu respons terhadap RIL_REQUEST_GET_AVAILABLE_NETWORKS ), wakelock akan ditahan dalam waktu lama di sisi pemroses aplikasi. Masalah modem juga bisa mengakibatkan waktu tunggu yang lama.

Gambar 1. RIL meminta respons asinkron.

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

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

    Catatan: Durasi waktu tunggu wakelock untuk urutan permintaan-ack akan lebih kecil daripada durasi waktu habis 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 kemudian memperoleh wakelock dan mengirimkan respons ke sisi Java.
  4. Saat respons mencapai sisi Java, wakelock diperoleh dan respons dikembalikan ke pemanggil.
  5. Setelah respons diproses oleh semua modul, pengakuan dikirim (melalui soket) 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 di-hardcode untuk perintah RIL tertentu dan diputuskan berdasarkan panggilan demi panggilan.

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

Skenario: RIL tanggapan yang tidak diminta

Dalam skenario ini, respons RIL yang tidak diminta memiliki tanda tipe wakelock yang menunjukkan apakah wakelock perlu diperoleh untuk respons vendor. Jika flag disetel, wakelock berwaktu akan disetel dan respons dikirim melalui soket ke sisi Java. Ketika penghitung waktu berakhir, wakelock dilepaskan. Penguncian waktu yang diatur waktunya mungkin 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 mengirimkan respons yang tidak diminta.

Gambar 5. Menggunakan ack sebagai pengganti timed wakelock.

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 penggunaan semantik wakelock baru untuk panggilan asinkron dapat menghemat daya baterai.