Menerapkan antarmuka partisi produk

Android 11 memisahkan partisi product, sehingga tidak bergantung pada partisi system dan vendor. Sebagai bagian dari perubahan ini, Anda kini dapat mengontrol akses partisi product ke antarmuka native dan Java (yang mirip dengan cara kerja penerapan antarmuka untuk partisi vendor).

Menerapkan antarmuka native

Untuk mengaktifkan penerapan antarmuka native, tetapkan PRODUCT_PRODUCT_VNDK_VERSION ke current. (Versi ini otomatis ditetapkan ke current jika level API pengiriman untuk target lebih besar dari 29.) Penerapan memungkinkan:

  • Modul native di partisi product untuk ditautkan:
    • Secara statis atau dinamis ke modul lain di partisi product yang menyertakan library statis, bersama, atau header.
    • Secara dinamis ke library VNDK di partisi system.
  • Library JNI di APK yang tidak digabungkan di partisi product untuk ditautkan ke library di /product/lib atau /product/lib64 (selain library NDK).

Penerapan tidak mengizinkan link lain ke partisi selain partisi product.

Penerapan waktu build (Android.bp)

Di Android 11, modul sistem dapat membuat varian image produk selain varian image inti dan vendor. Jika penerapan antarmuka native diaktifkan (PRODUCT_PRODUCT_VNDK_VERSION ditetapkan ke current):

  • Modul native di partisi product berada dalam varian produk, bukan varian inti.

  • Modul dengan product_available: true dalam file Android.bp tersedia untuk varian produk.

  • Library atau biner yang menentukan product_specific: true dapat ditautkan ke library lain yang menentukan product_specific: true atau product_available: true dalam file Android.bp.

  • Library VNDK harus memiliki product_available: true dalam file Android.bp sehingga biner product dapat ditautkan ke library VNDK.

Tabel berikut merangkum properti Android.bp yang digunakan untuk membuat varian image.

Properti di Android.bp Varian yang dibuat
Sebelum penerapan Setelah penerapan
default (none) core
(includes /system, /system_ext and /product)
core
(includes /system and /system_ext but not /product)
system_ext_specific: true core core
product_specific: true core product
vendor: true vendor vendor
vendor_available: true core, vendor core, vendor
product_available: true T/A core, product
vendor_available: true AND product_available: true T/A core, product, vendor
system_ext_specific: true AND vendor_available: true core, vendor core, vendor
product_specific: true AND vendor_available: true core, vendor product, vendor

Penerapan waktu build (Android.mk)

Jika penerapan antarmuka native diaktifkan, modul native yang diinstal ke partisi product memiliki jenis link native:product yang hanya dapat ditautkan ke modul native:product atau native:vndk lainnya. Mencoba menautkan ke modul selain modul ini akan menyebabkan sistem build menghasilkan error pemeriksaan jenis link.

Penerapan runtime

Jika penerapan antarmuka native diaktifkan, konfigurasi linker untuk linker bionik tidak mengizinkan proses sistem menggunakan library product, sehingga membuat bagian product untuk proses product yang tidak dapat ditautkan ke library di luar partisi product (namun, proses tersebut dapat ditautkan ke library VNDK). Upaya untuk melanggar konfigurasi link runtime akan menyebabkan proses gagal dan menghasilkan pesan error CANNOT LINK EXECUTABLE.

Menerapkan antarmuka Java

Untuk mengaktifkan penerapan antarmuka Java, tetapkan PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE ke true. (Nilai ini otomatis ditetapkan ke true jika level API pengiriman untuk target lebih besar dari 29.) Jika diaktifkan, penerapan akan mengizinkan atau tidak mengizinkan akses berikut:

API /system /system_ext /product /vendor /data
API Publik
@SystemApi
@hide API

Seperti di partisi vendor, aplikasi atau library Java di partisi product hanya diizinkan menggunakan API publik dan sistem; penautan ke library yang menggunakan API tersembunyi tidak diizinkan. Pembatasan ini mencakup penautan pada waktu build dan refleksi dalam runtime.

Penerapan waktu build

Pada waktu build, Make dan Soong memverifikasi bahwa modul Java di partisi product tidak menggunakan API tersembunyi dengan memeriksa kolom platform_apis dan sdk_version. sdk_version aplikasi di partisi product harus diisi dengan current, system_current, atau versi numerik API, dan kolom platform_apis harus kosong.

Penerapan runtime

Runtime Android memverifikasi bahwa aplikasi di partisi product tidak menggunakan API tersembunyi, termasuk refleksi. Untuk mengetahui detailnya, lihat Pembatasan antarmuka non-SDK.

Mengaktifkan penerapan antarmuka produk

Gunakan langkah-langkah di bagian ini untuk mengaktifkan penerapan antarmuka produk.

Langkah Tugas Wajib
1 Tentukan makefile sistem Anda sendiri yang menentukan paket untuk partisi system, lalu tetapkan pemeriksaan persyaratan jalur artefak di device.mk (untuk mencegah modul non-sistem diinstal ke partisi system). T
2 Bersihkan daftar yang diizinkan. T
3 Terapkan antarmuka native dan identifikasi kegagalan link runtime (dapat berjalan secara paralel dengan penerapan Java). Y
4 Terapkan antarmuka Java dan verifikasi perilaku runtime (dapat berjalan secara paralel dengan penerapan native). Y
5 Periksa perilaku runtime. Y
6 Perbarui device.mk dengan penerapan antarmuka produk. Y

Langkah 1: Buat makefile dan aktifkan pemeriksaan jalur artefak

Pada langkah ini, Anda menentukan makefile system.

  1. Buat makefile yang menentukan paket untuk partisi system. Misalnya, buat file oem_system.mk dengan kode berikut:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk)
    $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk)
    
    # Applications
    PRODUCT_PACKAGES += \
        CommonSystemApp1 \
        CommonSystemApp2 \
        CommonSystemApp3 \
    
    # Binaries
    PRODUCT_PACKAGES += \
        CommonSystemBin1 \
        CommonSystemBin2 \
        CommonSystemBin3 \
    
    # Libraries
    PRODUCT_PACKAGES += \
        CommonSystemLib1 \
        CommonSystemLib2 \
        CommonSystemLib3 \
    
    PRODUCT_SYSTEM_NAME := oem_system
    PRODUCT_SYSTEM_BRAND := Android
    PRODUCT_SYSTEM_MANUFACTURER := Android
    PRODUCT_SYSTEM_MODEL := oem_system
    PRODUCT_SYSTEM_DEVICE := generic
    
    # For system-as-root devices, system.img should be mounted at /, so we
    # include ROOT here.
    _my_paths := \
     $(TARGET_COPY_OUT_ROOT)/ \
     $(TARGET_COPY_OUT_SYSTEM)/ \
    
    $(call require-artifacts-in-path, $(_my_paths),)
    
  2. Dalam file device.mk, warisi makefile umum untuk partisi system dan aktifkan pemeriksaan persyaratan jalur artefak. Contoh:

    $(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk)
    
    # Enable artifact path requirements checking
    PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
    

Tentang persyaratan jalur artefak

Jika PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS ditetapkan ke true atau strict, sistem build akan mencegah paket yang ditentukan dalam makefile lain diinstal ke jalur yang ditentukan di require-artifacts-in-path dan mencegah paket yang ditentukan dalam makefile saat ini menginstal artefak di luar jalur yang ditentukan di require-artifacts-in-path.

Dalam contoh di atas, dengan PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS ditetapkan ke strict, makefile di luar oem_system.mk tidak dapat menyertakan modul yang diinstal ke partisi root atau system. Untuk menyertakan modul ini, Anda harus menentukannya di file oem_system.mk itu sendiri atau di makefile yang disertakan. Upaya untuk menginstal modul ke jalur yang tidak diizinkan akan menyebabkan build gagal. Untuk memperbaiki kegagalan, lakukan salah satu hal berikut:

  • Opsi 1: Sertakan modul sistem dalam makefile yang disertakan di oem_system.mk. Hal ini akan memastikan persyaratan jalur artefak terpenuhi (karena modul kini ada di makefile yang disertakan) dan dengan demikian memungkinkan penginstalan ke kumpulan jalur di `require-artifacts-in-path.

  • Opsi 2: Instal modul ke partisi system_ext atau product (dan jangan instal modul ke partisi system).

  • Opsi 3: Tambahkan modul ke PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST. Hal ini akan mencantumkan modul yang diizinkan untuk diinstal.

Langkah 2: Kosongkan daftar yang diizinkan

Pada langkah ini, Anda mengosongkan PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST sehingga semua perangkat yang berbagi oem_system.mk juga dapat berbagi satu system image. Untuk mengosongkan daftar yang diizinkan, pindahkan modul apa pun dalam daftar ke system_ext atau product partisi atau tambahkan ke system file make. Langkah ini bersifat opsional karena menentukan image system umum tidak diperlukan untuk mengaktifkan penerapan antarmuka produk. Namun, mengosongkan daftar yang diizinkan akan berguna untuk menentukan batas system dengan system_ext.

Langkah 3: Terapkan antarmuka native

Pada langkah ini, Anda menetapkan PRODUCT_PRODUCT_VNDK_VERSION := current, lalu mencari dan menyelesaikan error build dan runtime. Untuk memeriksa boot dan log perangkat serta menemukan dan memperbaiki kegagalan link runtime:

  1. Tetapkan PRODUCT_PRODUCT_VNDK_VERSION := current.

  2. Build perangkat dan cari error build. Anda mungkin akan melihat beberapa kegagalan build untuk varian produk atau varian inti yang tidak ada. Kegagalan umum mencakup:

    • Modul hidl_interface yang memiliki product_specific: true tidak akan tersedia untuk modul sistem. Untuk memperbaikinya, ganti product_specific: true dengan system_ext_specific: true.
    • Modul mungkin tidak memiliki varian produk yang diperlukan untuk modul produk. Untuk memperbaikinya, buat modul tersebut tersedia untuk partisi product dengan menetapkan product_available: true atau pindahkan modul ke partisi product dengan menetapkan product_specific: true.
  3. Selesaikan error build dan pastikan perangkat berhasil di-build.

  4. Flash image dan cari error runtime di boot dan log perangkat.

    • Jika tag linker dari log kasus pengujian menampilkan pesan CANNOT LINK EXECUTABLE, file make tidak memiliki dependensi (dan tidak diambil pada waktu build).
    • Untuk memeriksanya dari sistem build, tambahkan library yang diperlukan ke kolom shared_libs: atau required:.
  5. Selesaikan dependensi yang tidak ada menggunakan panduan yang diberikan di atas.

Langkah 4: Terapkan antarmuka Java

Pada langkah ini, Anda menetapkan PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true, lalu menemukan dan memperbaiki error build yang dihasilkan. Cari dua jenis error tertentu:

  • Error jenis link. Error ini menunjukkan bahwa aplikasi ditautkan ke modul Java yang memiliki sdk_version yang lebih luas. Untuk memperbaikinya, Anda dapat memperluas sdk_version aplikasi atau membatasi sdk_version library. Contoh error:

    error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.
    
  • Error simbol. Error ini menunjukkan bahwa simbol tidak dapat ditemukan karena berada di API tersembunyi. Untuk memperbaikinya, gunakan API yang terlihat (tidak tersembunyi) atau temukan alternatif. Contoh error:

    frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol
                ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader(
                                               ^
      symbol:   class ProxyAuthenticate
      location: class SipSessionGroup.SipSessionImpl
    

Langkah 5: Periksa perilaku runtime

Pada langkah ini, Anda memverifikasi bahwa perilaku runtime sesuai dengan yang diharapkan. Untuk aplikasi yang dapat di-debug, Anda dapat memantau penggunaan API tersembunyi berdasarkan log menggunakan StrictMode.detectNonSdkApiUsage (yang menghasilkan log saat aplikasi menggunakan API tersembunyi). Atau, Anda dapat menggunakan alat analisis statis veridex untuk mendapatkan jenis penggunaan (penautan atau refleksi), tingkat pembatasan, dan stack panggilan.

  • Sintaksis Veridex:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
  • Contoh hasil veridex:

    #1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s):
           Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V
    
    #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s):
           Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
    

Untuk mengetahui detail penggunaan veridex, lihat Menguji menggunakan alat veridex tool.

Langkah 6: Perbarui device.mk

Setelah memperbaiki semua kegagalan build dan runtime, serta memverifikasi bahwa perilaku runtime sesuai dengan yang diharapkan, tetapkan hal berikut di device.mk:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true