Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Menggunakan Binder IPC

Halaman ini menjelaskan perubahan pada driver binder di Android 8, memberikan detail tentang penggunaan IPC binder, dan mencantumkan kebijakan SELinux yang diperlukan.

Perubahan pada driver pengikat

Mulai Android 8, kerangka kerja Android dan HAL sekarang saling berkomunikasi menggunakan pengikat. Karena komunikasi ini secara dramatis meningkatkan lalu lintas pengikat, Android 8 menyertakan beberapa peningkatan yang dirancang untuk menjaga IPC pengikat tetap cepat. Vendor SoC dan OEM harus bergabung langsung dari cabang yang relevan dari android-4.4, android-4.9, dan yang lebih tinggi dari kernel / project umum .

Beberapa domain pengikat (konteks)

Common-4.4 dan lebih tinggi, termasuk upstream

Untuk membagi traffic pengikat dengan rapi antara kode framework (tidak bergantung perangkat) dan vendor (khusus perangkat), Android 8 memperkenalkan konsep konteks pengikat . Setiap konteks pengikat memiliki node perangkatnya sendiri dan manajer konteks (layanan) sendiri. Anda dapat mengakses manajer konteks hanya melalui node perangkat tempatnya berada dan, ketika meneruskan node pengikat melalui konteks tertentu, itu dapat diakses dari konteks yang sama hanya dengan proses lain, sehingga sepenuhnya mengisolasi domain satu sama lain. Untuk mengetahui detail tentang penggunaan, lihat vndbinder dan vndservicemanager .

Berkumpul

Common-4.4 dan lebih tinggi, termasuk upstream

Dalam rilis Android sebelumnya, setiap bagian data dalam panggilan binder disalin tiga kali:

  • Sekali untuk membuat serial menjadi Parcel dalam proses panggilan
  • Setelah di driver kernel untuk menyalin Parcel ke proses target
  • Sekali untuk membatalkan seri Parcel dalam proses target

Android 8 menggunakan pengoptimalan pengumpulan-sebar untuk mengurangi jumlah salinan dari 3 menjadi 1. Daripada membuat serialisasi data dalam Parcel terlebih dahulu, data tetap dalam struktur aslinya dan tata letak memori dan driver segera menyalinnya ke proses target. Setelah data berada dalam proses target, struktur dan tata letak memori sama dan data dapat dibaca tanpa memerlukan salinan lagi.

Penguncian mendetail

Common-4.4 dan lebih tinggi, termasuk upstream

Dalam rilis Android sebelumnya, driver binder menggunakan kunci global untuk melindungi dari akses bersamaan ke struktur data penting. Meskipun ada pertikaian minimal untuk kunci tersebut, masalah utamanya adalah bahwa jika utas dengan prioritas rendah memperoleh kunci dan kemudian mendapat preemption, hal itu dapat sangat menunda utas dengan prioritas lebih tinggi yang perlu mendapatkan kunci yang sama. Ini menyebabkan jank di peron.

Upaya awal untuk menyelesaikan masalah ini melibatkan penonaktifan preemption sambil menahan kunci global. Namun, ini lebih merupakan peretasan daripada solusi sebenarnya, dan akhirnya ditolak oleh upstream dan dibuang. Upaya selanjutnya difokuskan untuk membuat penguncian lebih halus, sebuah versi yang telah berjalan di perangkat Pixel sejak Januari 2017. Meskipun sebagian besar perubahan tersebut dipublikasikan, peningkatan substansial dilakukan di versi berikutnya.

Setelah mengidentifikasi masalah kecil dalam implementasi penguncian yang mendetail, kami merancang solusi yang lebih baik dengan arsitektur penguncian yang berbeda dan mengirimkan perubahan di semua cabang kernel umum. Kami terus menguji penerapan ini pada sejumlah besar perangkat yang berbeda; karena kami tidak mengetahui adanya masalah yang belum terselesaikan, ini adalah penerapan yang disarankan untuk perangkat yang dikirimkan dengan Android 8.

Pewarisan prioritas waktu nyata

Common-4.4 dan common-4.9 (upstream segera hadir)

Driver pengikat selalu mendukung pewarisan prioritas yang bagus. Seiring meningkatnya jumlah proses di Android yang berjalan pada prioritas real-time, dalam beberapa kasus sekarang masuk akal jika thread real-time membuat panggilan pengikat, thread dalam proses yang menangani panggilan tersebut juga berjalan pada prioritas real-time. . Untuk mendukung kasus penggunaan ini, Android 8 sekarang menerapkan pewarisan prioritas real-time di driver binder.

Selain pewarisan prioritas tingkat transaksi, pewarisan prioritas node memungkinkan node (objek layanan pengikat) menentukan prioritas minimum di mana panggilan ke node ini harus dijalankan. Versi Android sebelumnya sudah mendukung pewarisan prioritas node dengan nilai bagus, tetapi Android 8 menambahkan dukungan untuk pewarisan node kebijakan penjadwalan waktu nyata.

Perubahan ruang pengguna

Android 8 menyertakan semua perubahan ruang pengguna yang diperlukan untuk bekerja dengan driver pengikat saat ini di kernel umum dengan satu pengecualian: Implementasi asli untuk menonaktifkan pewarisan prioritas waktu nyata untuk /dev/binder menggunakan ioctl . Pengembangan selanjutnya mengalihkan kontrol pewarisan prioritas ke metode yang lebih halus yaitu per mode pengikat (dan bukan per konteks). Jadi, ioctl tidak ada di cabang umum Android dan malah dikirimkan di kernel umum kami .

Efek dari perubahan ini adalah bahwa pewarisan prioritas waktu nyata dinonaktifkan secara default untuk setiap node. Tim kinerja Android hwbinder manfaatnya untuk mengaktifkan pewarisan prioritas waktu nyata untuk semua node di domain hwbinder . Untuk mencapai efek yang sama, pilihlah perubahan ini di userspace.

SHA untuk kernel umum

Untuk mendapatkan perubahan yang diperlukan untuk pengandar pengikat, sinkronkan ke SHA yang sesuai:

  • Umum-3.18
    cc8b90c121de ANDROID: binder: jangan periksa izin prio saat memulihkan.
  • Umum-4.4
    76b376eac7a2 ANDROID: binder: jangan periksa izin prio saat memulihkan.
  • Umum-4.9
    ecd972d4f9b5 ANDROID: binder: jangan periksa izin prio saat memulihkan.

Menggunakan binder IPC

Secara historis, proses vendor telah menggunakan komunikasi antarproses pengikat (IPC) untuk berkomunikasi. Di Android 8, node perangkat /dev/binder menjadi eksklusif untuk proses kerangka kerja, yang berarti proses vendor tidak lagi memiliki akses ke sana. Proses vendor dapat mengakses /dev/hwbinder , tetapi harus mengonversi antarmuka AIDL mereka untuk menggunakan HIDL. Untuk vendor yang ingin terus menggunakan antarmuka AIDL antar proses vendor, Android mendukung IPC binder seperti yang dijelaskan di bawah ini.

vndbinder

Android 8 mendukung domain pengikat baru untuk digunakan oleh layanan vendor, diakses menggunakan /dev/vndbinder alih-alih /dev/binder . Dengan tambahan /dev/vndbinder , Android sekarang memiliki tiga domain IPC berikut:

Domain IPC Deskripsi
/dev/binder IPC antara proses framework / aplikasi dengan antarmuka AIDL
/dev/hwbinder IPC antara proses kerangka / vendor dengan antarmuka HIDL
IPC antara proses vendor dengan antarmuka HIDL
/dev/vndbinder IPC antara proses vendor / vendor dengan Antarmuka AIDL

Agar /dev/vndbinder muncul, pastikan item konfigurasi kernel CONFIG_ANDROID_BINDER_DEVICES disetel ke "binder,hwbinder,vndbinder" (ini adalah default di pohon kernel umum Android).

Biasanya, proses vendor tidak membuka pengandar pengikat secara langsung dan sebagai gantinya menautkan ke perpustakaan ruang pengguna libbinder , yang membuka pengandar pengikat. Menambahkan metode untuk ::android::ProcessState() memilih driver pengikat untuk libbinder . Proses vendor harus memanggil metode ini sebelum memanggil ke ProcessState, IPCThreadState , atau sebelum melakukan panggilan binder secara umum. Untuk menggunakan, lakukan panggilan berikut setelah main() dari proses vendor (klien dan server):

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

Sebelumnya, layanan pengikat yang terdaftar dengan servicemanager , di mana mereka dapat diambil oleh proses lainnya. Di Android 8, servicemanager sekarang digunakan secara eksklusif oleh kerangka kerja dan proses aplikasi dan proses vendor tidak dapat lagi mengaksesnya.

Namun, layanan vendor sekarang dapat menggunakan vndservicemanager , sebuah instance baru dari servicemanager yang menggunakan /dev/vndbinder alih-alih /dev/binder dan yang dibangun dari sumber yang sama dengan framework servicemanager . Proses vendor tidak perlu melakukan perubahan untuk berbicara dengan vndservicemanager ; ketika proses vendor membuka / dev/vndbinder , pencarian layanan secara otomatis masuk ke vndservicemanager .

Biner vndservicemanager disertakan dalam makefile perangkat default Android.

Kebijakan SELinux

Proses vendor yang ingin menggunakan fungsionalitas pengikat untuk berkomunikasi satu sama lain memerlukan hal-hal berikut:

  1. Akses ke /dev/vndbinder .
  2. Binder {transfer, call} terhubung ke vndservicemanager .
  3. binder_call(A, B) untuk setiap vendor domain A yang ingin memanggil ke domain vendor B melalui antarmuka pengikat vendor.
  4. Izin untuk {add, find} layanan di vndservicemanager .

Untuk memenuhi persyaratan 1 dan 2, gunakan makro vndbinder_use() :

vndbinder_use(some_vendor_process_domain);

Untuk memenuhi persyaratan 3, binder_call(A, B) untuk proses vendor A dan B yang perlu membicarakan pengikat dapat tetap di tempatnya, dan tidak perlu diganti nama.

Untuk memenuhi persyaratan 4, Anda harus membuat perubahan pada cara penanganan nama layanan, label layanan, dan aturan.

Untuk detail tentang SELinux, lihat Linux yang Ditingkatkan Keamanan di Android . Untuk detail tentang SELinux di Android 8.0, lihat SELinux untuk Android 8.0 .

Nama layanan

Sebelumnya, vendor memproses nama layanan terdaftar dalam file service_contexts dan menambahkan aturan terkait untuk mengakses file itu. Contoh file service_contexts dari device/google/marlin/sepolicy :

AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0

Di Android 8, vndservicemanager memuat file vndservice_contexts sebagai gantinya. Layanan vendor yang bermigrasi ke vndservicemanager (dan yang sudah ada di file service_contexts lama) harus ditambahkan ke file vndservice_contexts baru.

Label layanan

Sebelumnya, label layanan seperti u:object_r:atfwd_service:s0 didefinisikan dalam file service.te . Contoh:

type atfwd_service,      service_manager_type;

Di Android 8, Anda harus mengubah tipe menjadi vndservice_manager_type dan memindahkan aturan ke file vndservice.te . Contoh:

type atfwd_service,      vndservice_manager_type;

Aturan manajer servis

Sebelumnya, aturan memberi domain akses untuk menambah atau menemukan layanan dari servicemanager layanan. Contoh:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

Di Android 8, aturan seperti itu bisa tetap berlaku dan menggunakan kelas yang sama. Contoh:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;