Google berkomitmen untuk memajukan ekuitas ras untuk komunitas kulit hitam. Lihat bagaimana.
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Menggunakan Binder IPC

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

Perubahan ke pengikat pengikat

Dimulai di Android 8, kerangka kerja Android dan HAL sekarang saling berkomunikasi menggunakan binder. Karena komunikasi ini secara dramatis meningkatkan traffic binder, Android 8 menyertakan beberapa perbaikan yang dirancang untuk menjaga binder IPC dengan cepat. Vendor SoC dan OEM harus bergabung langsung dari cabang yang relevan dari android-4.4, android-4.9, dan lebih tinggi dari kernel / proyek umum .

Beberapa domain binder (konteks)

Common-4.4 dan lebih tinggi, termasuk hulu

Untuk memisahkan lalu lintas pengikat antara kerangka (perangkat-independen) dan vendor (khusus perangkat), Android 8 memperkenalkan konsep konteks pengikat . Setiap konteks pengikat memiliki simpul perangkat sendiri dan manajer konteks (layanan) sendiri. Anda dapat mengakses manajer konteks hanya melalui node perangkat tempat ia berada dan, ketika melewati binder node melalui konteks tertentu, itu dapat diakses dari konteks yang sama hanya dengan proses lain, sehingga sepenuhnya mengisolasi domain dari satu sama lain. Untuk detail tentang penggunaan, lihat vndbinder dan vndservicemanager .

Menyebarkan-mengumpulkan

Common-4.4 dan lebih tinggi, termasuk hulu

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

  • Sekali untuk cerita bersambung menjadi Parcel dalam proses panggilan
  • Setelah di driver kernel untuk menyalin Parcel ke proses target
  • Setelah unserialize Parcel dalam proses target

Android 8 menggunakan optimalisasi scatter-gathering untuk mengurangi jumlah salinan dari 3 menjadi 1. Alih-alih membuat serial data dalam Parcel terlebih dahulu, data tetap dalam struktur aslinya dan tata letak memori dan driver segera menyalinnya ke proses target. Setelah data dalam proses target, struktur dan tata letak memori adalah sama dan data dapat dibaca tanpa memerlukan salinan lain.

Penguncian berbutir halus

Common-4.4 dan lebih tinggi, termasuk hulu

Dalam rilis Android sebelumnya, pengikat pengikat menggunakan kunci global untuk melindungi terhadap akses bersamaan ke struktur data penting. Meskipun ada pertengkaran minimal untuk kunci, masalah utama adalah bahwa jika utas berprioritas rendah mendapatkan kunci dan kemudian didahului, itu bisa secara serius menunda utas berprioritas lebih tinggi yang perlu mendapatkan kunci yang sama. Ini menyebabkan jank di platform.

Upaya awal untuk menyelesaikan masalah ini termasuk menonaktifkan preemption sambil memegang kunci global. Namun, ini lebih merupakan peretasan daripada solusi sejati, dan akhirnya ditolak oleh hulu dan dibuang. Upaya selanjutnya difokuskan pada membuat penguncian lebih halus, versi yang telah berjalan pada perangkat Pixel sejak Januari 2017. Sementara sebagian besar perubahan itu dibuat untuk publik, peningkatan substansial dilakukan pada versi berikutnya.

Setelah mengidentifikasi masalah kecil dalam implementasi penguncian berbutir halus, kami menemukan solusi yang ditingkatkan dengan arsitektur penguncian yang berbeda dan mengajukan perubahan di semua cabang kernel umum. Kami terus menguji implementasi ini pada sejumlah besar perangkat yang berbeda; karena kami tidak mengetahui adanya masalah luar biasa, ini adalah implementasi yang disarankan untuk pengiriman perangkat dengan Android 8.

Warisan prioritas waktu nyata

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

Pengikat pengikat selalu mendukung warisan prioritas yang bagus. Karena semakin banyak proses di Android berjalan pada prioritas waktu-nyata, dalam beberapa kasus sekarang masuk akal bahwa jika utas waktu-nyata membuat panggilan pengikat, utas dalam proses yang menangani panggilan itu juga berjalan pada prioritas waktu-nyata . Untuk mendukung kasus penggunaan ini, Android 8 sekarang mengimplementasikan pewarisan prioritas waktu nyata dalam pengikat binder.

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

Perubahan ruang pengguna

Android 8 mencakup semua perubahan ruang pengguna yang diperlukan untuk bekerja dengan pengikat pengikat saat ini di kernel umum dengan satu pengecualian: Implementasi asli untuk menonaktifkan warisan prioritas real-time untuk /dev/binder menggunakan ioctl . Perkembangan selanjutnya mengalihkan kontrol pewarisan prioritas ke metode yang lebih halus yaitu mode per pengikat (dan bukan per konteks). Dengan demikian, ioctl tidak ada di cabang umum Android dan malah dikirimkan di kernel umum kami .

Efek dari perubahan ini adalah warisan prioritas waktu-nyata dinonaktifkan secara default untuk setiap node. Tim kinerja Android telah menemukan manfaat untuk mengaktifkan warisan prioritas waktu nyata untuk semua node di domain hwbinder . Untuk mencapai efek yang sama, pilih perubahan ini di userspace.

SHA untuk kernel biasa

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

  • Biasa-3,18
    cc8b90c121de ANDROID: binder: jangan periksa izin prio saat restore.
  • Common-4.4
    76b376eac7a2 ANDROID: binder: jangan periksa izin prio saat restore.
  • Biasa-4,9
    ecd972d4f9b5 ANDROID: binder: jangan periksa izin prio saat memulihkan.

Menggunakan binder IPC

Secara historis, proses vendor telah menggunakan binder interprocess communication (IPC) untuk berkomunikasi. Di Android 8, simpul perangkat /dev/binder menjadi eksklusif untuk proses kerangka kerja, artinya 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 antara proses vendor, Android mendukung binder IPC seperti yang dijelaskan di bawah ini.

vndbinder

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

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

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

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

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

vndservicemanager

Sebelumnya, layanan binder didaftarkan pada servicemanager , di mana mereka dapat diambil oleh proses lain. Di Android 8, servicemanager sekarang digunakan secara eksklusif oleh kerangka kerja dan proses aplikasi dan proses vendor tidak lagi dapat mengaksesnya.

Namun, layanan vendor sekarang dapat menggunakan vndservicemanager , instance baru 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 pergi ke vndservicemanager .

Biner vndservicemanager termasuk dalam vndservicemanager makefile perangkat bawaan Android.

Kebijakan SELinux

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

  1. Akses ke /dev/vndbinder .
  2. Binder {transfer, call} hooks ke vndservicemanager .
  3. binder_call(A, B) untuk domain vendor apa pun A yang ingin memanggil 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 membahas binder dapat tetap di tempatnya, dan tidak perlu mengganti nama.

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

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 dalam 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 ke vndservice_manager_type dan memindahkan aturan ke file vndservice.te . Contoh:

type atfwd_service,      vndservice_manager_type;

Aturan Servicemanager

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 di tempatnya dan menggunakan kelas yang sama. Contoh:

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