Pemfaktoran ulang RIL

Android 7.0 memfaktorkan ulang Lapisan Antarmuka Radio (RIL) menggunakan serangkaian fitur untuk meningkatkan fungsi RIL. Perubahan kode partner diperlukan untuk menerapkan fitur ini, yang bersifat opsional tetapi dianjurkan. Perubahan pemfaktoran ulang kompatibel dengan versi sebelumnya, sehingga implementasi sebelumnya dari fitur yang difaktorkan ulang tetap berfungsi.

Pemfaktoran ulang RIL mencakup peningkatan berikut:

  • Kode error RIL. Mengaktifkan kode error tertentu selain kode GENERIC_FAILURE yang ada. Hal ini membantu pemecahan masalah error dengan memberikan informasi yang lebih spesifik tentang penyebab error.
  • Pembuatan versi RIL. Memberikan informasi versi yang lebih akurat dan lebih mudah dikonfigurasi.
  • Komunikasi RIL menggunakan wakelock. Meningkatkan performa baterai perangkat.

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

Mengimplementasikan kode error RIL yang ditingkatkan

Hampir semua panggilan permintaan RIL dapat menampilkan kode error GENERIC_FAILURE sebagai respons terhadap error. Ini adalah masalah dengan semua respons yang diminta yang ditampilkan oleh OEM, yang dapat menyulitkan proses debug masalah dari laporan bug jika kode error GENERIC_FAILURE yang sama ditampilkan oleh panggilan RIL karena alasan yang berbeda. Vendor mungkin perlu waktu cukup lama untuk mengidentifikasi bagian kode yang mungkin menampilkan kode GENERIC_FAILURE.

Di Android 7.x dan yang lebih tinggi, OEM dapat menampilkan nilai kode error yang berbeda yang terkait dengan setiap error berbeda yang saat ini dikategorikan sebagai GENERIC_FAILURE. OEM yang tidak ingin mengungkapkan kode error kustomnya secara publik dapat menampilkan error sebagai kumpulan bilangan bulat yang berbeda (seperti 1 hingga x) yang dipetakan sebagai OEM_ERROR_1 ke OEM_ERROR_X. Vendor harus memastikan setiap kode error yang disamarkan tersebut ditampilkan ke alasan error unik dalam kode. Menggunakan kode error tertentu dapat mempercepat proses debug RIL setiap kali error umum ditampilkan oleh OEM, karena sering kali memerlukan terlalu banyak waktu untuk mengidentifikasi penyebab pasti kode error GENERIC_FAILURE (dan terkadang tidak mungkin diketahui).

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

Memvalidasi kode error RIL yang ditingkatkan

Setelah menambahkan kode error baru untuk mengganti kode GENERIC_FAILURE, pastikan kode error baru ditampilkan oleh panggilan RIL, bukan GENERIC_FAILURE.

Menerapkan pembuatan versi RIL yang ditingkatkan

Pembuatan versi RIL dalam rilis Android lama bermasalah: versi itu sendiri tidak akurat, 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 mengupdate versi mereka dalam kode dan menampilkan versi tersebut dalam RIL_REGISTER.

Memvalidasi pembuatan versi RIL yang ditingkatkan

Pastikan versi RIL yang sesuai dengan kode RIL Anda ditampilkan selama RIL_REGISTER (bukan RIL_VERSION yang ditentukan dalam ril.h).

Mengimplementasikan komunikasi RIL menggunakan wakelock

Wakelock berjangka waktu digunakan dalam komunikasi RIL dengan cara yang tidak akurat, yang berdampak negatif pada performa baterai. Di Android 7.x dan yang lebih tinggi, Anda dapat meningkatkan performa dengan mengklasifikasikan permintaan RIL dan mengupdate kode untuk menangani wakelock secara berbeda untuk berbagai jenis permintaan.

Mengklasifikasikan permintaan RIL

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

  • sinkron. Permintaan yang tidak memerlukan waktu yang lama untuk merespons. Misalnya, RIL_REQUEST_GET_SIM_STATUS.
  • asinkron. Permintaan yang memerlukan waktu yang cukup lama untuk memberikan respons. Misalnya, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS.

Permintaan RIL yang diminta secara asinkron dapat memerlukan waktu yang cukup lama. Setelah menerima ack dari kode vendor, RIL Java akan merilis wakelock, yang mungkin menyebabkan prosesor aplikasi beralih dari status tidak ada aktivitas ke ditangguhkan. Saat respons tersedia dari kode vendor, RIL Java (pemroses aplikasi) akan memperoleh kembali wakelock, memproses respons, lalu kembali ke mode tidak ada aktivitas. Berpindah dari tidak ada aktivitas ke ditangguhkan ke tidak ada aktivitas dapat menghabiskan banyak daya.

Jika waktu respons tidak cukup lama, menahan wakelock dan tetap dalam mode tidak ada aktivitas selama waktu yang diperlukan untuk merespons dapat lebih hemat daya daripada beralih ke status penangguhan dengan melepaskan wakelock dan mengaktifkan saat respons datang. Vendor harus menggunakan pengukuran daya khusus platform untuk menentukan nilai minimum waktu T saat daya yang digunakan dengan tetap tidak ada aktivitas selama seluruh waktu T lebih besar dari daya yang digunakan dengan beralih dari tidak ada aktivitas ke ditangguhkan dan tidak ada aktivitas dalam waktu yang sama T. Jika waktu T diketahui, perintah RIL yang memerlukan waktu lebih dari T dapat diklasifikasikan sebagai asinkron dan perintah lainnya diklasifikasikan sebagai sinkron.

Skenario komunikasi RIL

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

Catatan: Untuk mengetahui detail penerapan 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 memerlukan waktu yang cukup lama (yaitu respons terhadap RIL_REQUEST_GET_AVAILABLE_NETWORKS), wakelock akan ditahan selama waktu yang lama di sisi pemroses aplikasi. Masalah modem juga dapat menyebabkan 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 ditahan oleh modem.
  1. Permintaan RIL dikirim dan modem memperoleh wakelock untuk memproses permintaan tersebut.
  2. Modem mengirimkan konfirmasi yang menyebabkan sisi Java mengurangi penghitung wakelock dan melepaskannya saat nilai penghitung adalah 0.

    Catatan: Durasi waktu tunggu wakelock untuk urutan permintaan-respons akan lebih kecil dari durasi waktu tunggu yang saat ini digunakan karena respons 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. Saat respons mencapai sisi Java, wakelock akan diperoleh dan respons akan ditampilkan kepada pemanggil.
  5. Setelah respons diproses oleh semua modul, konfirmasi akan 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 ditahan 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. Saat respons diterima oleh sisi Java, decrementWakeLock() dipanggil, yang mengurangi penghitung wakelock dan melepaskan wakelock jika nilai penghitungnya adalah 0.

Skenario: Respons yang tidak diminta RIL

Dalam skenario ini, respons tidak diminta RIL memiliki tanda jenis wakelock dalam yang menunjukkan apakah wakelock perlu diperoleh untuk respons vendor. Jika tanda ini ditetapkan, wakelock berjangka waktu akan ditetapkan dan respons akan dikirim melalui socket ke sisi Java. Saat timer berakhir, wakelock akan dilepaskan. Wakelock berjangka waktu mungkin terlalu lama atau terlalu singkat untuk respons tidak diminta RIL yang berbeda.

Gambar 4. Respons tidak diminta RIL.

Solusi: Pengesahan dikirim dari kode Java ke sisi native (ril.cpp), bukan menahan wakelock berjangka waktu di sisi native saat mengirim respons yang tidak diminta.

Gambar 5. Menggunakan ack, bukan wakelock berjangka waktu.

Memvalidasi wakelock yang didesain ulang

Pastikan panggilan RIL diidentifikasi sebagai sinkron atau asinkron. Karena konsumsi daya baterai dapat bergantung pada hardware/platform, vendor harus melakukan beberapa pengujian internal untuk mengetahui apakah penggunaan semantik wakelock baru untuk panggilan asinkron akan menghemat daya baterai.