Ürün bölümü arayüzlerini zorunlu kılma

Android 11, product bölümünü system ve vendor bölümlerinden bağımsız hale getirerek paketten çıkarır. Bu değişiklikler kapsamında artık product bölümünün yerel ve Java arayüzlerine erişimini kontrol edebilirsiniz (bu, vendor bölümleri için arayüz yaptırımının işleyiş şekline benzer).

Yerel arayüzleri zorunlu kılma

Yerel arayüz yaptırımını etkinleştirmek için PRODUCT_PRODUCT_VNDK_VERSION değerini current olarak ayarlayın. (Hedefin gönderim API seviyesi 29'dan yüksek olduğunda sürüm otomatik olarak current olarak ayarlanır.) Yaptırım sayesinde:

  • Bağlanacak product bölümündeki yerel modüller:
    • Statik, paylaşılan veya başlık kitaplıkları içeren product bölümündeki diğer modüllere statik veya dinamik olarak.
    • system bölümündeki VNDK kitaplıklarına dinamik olarak.
  • product veya /product/lib64 bölümündeki kitaplıklara bağlantı oluşturmak için product bölümündeki paketlenmemiş APK'lardaki JNI kitaplıkları (NDK kitaplıklarına ek olarak)./product/lib

Yaptırım, product bölümünün dışındaki bölümlere diğer bağlantılara izin vermez.

Derleme zamanı yaptırımı (Android.bp)

Android 11'de sistem modülleri, temel ve tedarikçi firma resim varyantlarına ek olarak ürün resmi varyantı oluşturabilir. Yerel arayüz yaptırımı etkinleştirildiğinde (PRODUCT_PRODUCT_VNDK_VERSION, current olarak ayarlanır):

  • product bölümündeki yerel modüller, temel varyant yerine ürün varyantındadır.

  • Android.bp dosyalarında product_available: true bulunan modüller ürün varyantında kullanılabilir.

  • product_specific: true belirten kitaplıklar veya ikili dosyalar, Android.bp dosyalarında product_specific: true veya product_available: true belirten diğer kitaplıklara bağlantı verebilir.

  • product ikili dosyalarının VNDK kitaplıklarına bağlanabilmesi için VNDK kitaplıklarının Android.bp dosyalarında product_available: true olmalıdır.

Aşağıdaki tabloda, resim varyantları oluşturmak için kullanılan Android.bp özellikleri özetlenmiştir.

Android.bp dosyasında mülkler Oluşturulan varyant sayısı
Yaptırımdan önce Yaptırımdan sonra
varsayılan (yok) temel
(/system, /system_ext ve /product dahil)
temel
(/system ve /system_ext'yi içerir ancak /product'ı içermez)
system_ext_specific: true core core
product_specific: true core ürün
vendor: true otomatik satış makinesi otomatik satış makinesi
vendor_available: true core, vendor core, vendor
product_available: true Yok core, ürün
vendor_available: true VE product_available: true Yok core, product, vendor
system_ext_specific: true VE vendor_available: true core, vendor core, vendor
product_specific: true VE vendor_available: true core, vendor ürün, tedarikçi firma

Derleme zamanı yaptırımı (Android.mk)

Yerleşik arayüz yaptırımı etkinleştirildiğinde, product bölümüne yüklenen yerel modüller yalnızca diğer native:product veya native:vndk modüllerine bağlantı oluşturabilen bir native:product bağlantı türüne sahiptir. Bunlar dışındaki modüllere bağlantı oluşturmaya çalışmak, derleme sisteminin bağlantı türü kontrol hatası oluşturmasına neden olur.

Çalışma zamanında yaptırım

Yerel arayüz yaptırımı etkinleştirildiğinde, Bionic linker'ın bağlayıcı yapılandırması, sistem işlemlerinin product kitaplıklarını kullanmasına izin vermez. Bu durumda, product bölümündeki kitaplıklara bağlanamayan product işlemleri için bir product bölümü oluşturulur (ancak bu tür işlemler VNDK kitaplıklarına bağlanabilir). Çalışma zamanı bağlantı yapılandırmasını ihlal etmeye yönelik girişimler, işlemin başarısız olmasına ve CANNOT LINK EXECUTABLE hata mesajının oluşturulmasına neden olur.

Java arayüzlerini zorunlu kılma

Java arayüzünü zorunlu kılma özelliğini etkinleştirmek için PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE değerini true olarak ayarlayın. (Hedefin kargo API düzeyi 29'dan büyük olduğunda değer otomatik olarak true olarak ayarlanır.) Zorunlu kılma etkinleştirildiğinde aşağıdaki erişimlere izin verilir veya verilmez:

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

vendor bölümünde olduğu gibi, product bölümündeki bir uygulamanın veya Java kitaplığının yalnızca herkese açık ve sistem API'lerini kullanmasına izin verilir. Gizli API'leri kullanan bir kitaplığa bağlantı verilmesine izin verilmez. Bu kısıtlama, derleme sırasında bağlantı oluşturmayı ve çalışma zamanında yansımayı içerir.

Derleme zamanı yaptırımı

Make ve Soong, derleme sırasında product bölümündeki Java modüllerinin platform_apis ve sdk_version alanlarını kontrol ederek gizli API'ler kullanmadığını doğrular. product bölümündeki uygulamaların sdk_version değeri, API'nin current, system_current veya sayısal sürümüyle doldurulmalıdır ve platform_apis alanı boş olmalıdır.

Çalışma zamanında yaptırım

Android çalışma zamanı, product bölümündeki uygulamaların yansıma dahil gizli API'ler kullanmadığını doğrular. Ayrıntılar için SDK dışı arayüzlerdeki kısıtlamalar başlıklı makaleyi inceleyin.

Ürün arayüzü yaptırımını etkinleştirme

Ürün arayüzü yaptırımını etkinleştirmek için bu bölümdeki adımları uygulayın.

Adım Görev Zorunlu
1 system bölümünün paketlerini belirten kendi sistem makefile dosyanızı tanımlayın, ardından device.mk içinde yapı yolu koşulu kontrolünü ayarlayın (sistem dışı modüllerin system bölümüne yüklenmesini önlemek için). H
2 İzin verilenler listesini temizleyin. H
3 Yerel arayüzleri zorunlu kılma ve çalışma zamanındaki bağlantı hatalarını belirleme (Java zorunluluğuna paralel olarak çalışabilir). Y
4 Java arayüzlerini zorunlu kılın ve çalışma zamanı davranışını doğrulayın (yerel zorunlu kılımla paralel olarak çalışabilir). Y
5 Çalışma zamanı davranışlarını kontrol edin. Y
6 device.mk'ü ürün arayüzü yaptırımıyla güncelleyin. Y

1. adım: Makefile oluşturun ve yapı yolu kontrolünü etkinleştirin

Bu adımda system makefile'ini tanımlarsınız.

  1. system bölümünün paketlerini tanımlayan bir makefile oluşturun. Örneğin, aşağıdakileri içeren bir oem_system.mk dosyası oluşturun:

    $(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. device.mk dosyasında, system bölümü için ortak makefile'i devralın ve yapı yolu şartlarını kontrol etmeyi etkinleştirin. Örnek:

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

Öğe yolu koşulları hakkında

PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS, true veya strict olarak ayarlandığında derleme sistemi, diğer makefile'lerde tanımlanan paketlerin require-artifacts-in-path'da tanımlanan yollara yüklenmesini ve geçerli makefile'de tanımlanan paketlerin require-artifacts-in-path'da tanımlanan yolların dışında yapı yüklemesini engeller.

Yukarıdaki örnekte, PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS strict olarak ayarlandığında oem_system.mk dışındaki makefile'ler root veya system bölümüne yüklenen modülleri içeremez. Bu modülleri dahil etmek için bunları oem_system.mk dosyasında veya dahil edilen bir makefile dosyasında tanımlamanız gerekir. İzin verilmeyen yollara modül yükleme girişimleri derleme işleminin kesintiye uğramasına neden olur. Araları düzeltmek için aşağıdakilerden birini yapın:

  • 1. Seçenek: Sistem modülünü oem_system.mk içindeki makefile'lere dahil edin. Bu sayede, yapı yolu koşulu karşılanır (modüller artık dahil edilmiş bir makefile'de bulunduğundan) ve böylece "require-artifacts-in-path" içindeki yol grubuna yükleme yapılır.

  • 2. Seçenek: Modülleri system_ext veya product bölümüne yükleyin (system bölümüne yüklemeyin).

  • 3. Seçenek: PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST'ye modül ekleyin. Bu listede, yüklenmesi izin verilen modüller yer alır.

2. adım: İzin verilenler listesini boşaltın

Bu adımda, oem_system.mk paylaşan tüm cihazların tek bir system resmi de paylaşabilmesi için PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST değerini boş bırakırsınız. İzin verilenler listesini boşaltmak için listedeki modülleri system_ext veya product bölümüne taşıyın ya da system make dosyalarına ekleyin. Ürün arayüzü yaptırımını etkinleştirmek için ortak bir system resmi tanımlamak gerekmediğinden bu adım isteğe bağlıdır. Ancak izin verilenler listesini boşaltmak, system sınırını system_ext ile tanımlamak için yararlıdır.

3. Adım: Yerel arayüzleri zorunlu kılın

Bu adımda, PRODUCT_PRODUCT_VNDK_VERSION := current değerini ayarlar, ardından derleme ve çalışma zamanı hatalarını arar ve çözersiniz. Cihazın önyüklemesini ve günlüklerini kontrol etmek, çalışma zamanındaki bağlantı hatalarını bulup düzeltmek için:

  1. PRODUCT_PRODUCT_VNDK_VERSION := current değerini ayarlayın.

  2. Cihazı derleyin ve derleme hatalarını arayın. Eksik ürün varyantları veya temel varyantlar için birkaç derleme kesintisi görebilirsiniz. Yaygın aralar şunlardır:

    • product_specific: true içeren hidl_interface modülleri sistem modülleri için kullanılamaz. Düzeltmek için product_specific: true yerine system_ext_specific: true yazın.
    • Modüllerde, ürün modülleri için gereken ürün varyantı eksik olabilir. Bu sorunu düzeltmek için product_available: true ayarını yaparak modülü product bölümüne kullanılabilir hale getirin veya product_specific: true ayarını yaparak modülü product bölümüne taşıyın.
  3. Derleme hatalarını giderin ve cihazın başarıyla derlendiğinden emin olun.

  4. Görüntüyü flaşlayın ve cihazın önyükleme işleminde ve günlüklerinde çalışma zamanı hatalarını arayın.

    • Bir test kaydı günlüğündeki linker etiketinde CANNOT LINK EXECUTABLE mesajı gösteriliyorsa make dosyasında bir bağımlılık eksiktir (ve derleme sırasında yakalanmamıştır).
    • Derleme sisteminden kontrol etmek için gerekli kitaplığı shared_libs: veya required: alanına ekleyin.
  5. Yukarıdaki talimatları kullanarak eksik bağımlılıkları giderin.

4. Adım: Java arayüzlerini zorunlu kılın

Bu adımda PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true değerini ayarlar, ardından ortaya çıkan derleme hatalarını bulup düzeltirsiniz. İki tür hatayı arayın:

  • Bağlantı türü hataları Bu hata, bir uygulamanın daha geniş sdk_version alanına sahip Java modüllerine bağlantı oluşturduğunu gösterir. Bu sorunu düzeltmek için uygulamanın sdk_version'sini genişletebilir veya kitaplığın sdk_version'sini kısıtlayabilirsiniz. Örnek hata:

    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.
    
  • Sembol hataları. Bu hata, gizli bir API'de olduğu için bir sembolün bulunamadığını gösterir. Bu sorunu düzeltmek için görünür (gizli olmayan) bir API kullanın veya alternatif bir API bulun. Örnek hata:

    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
    

5. Adım: Çalışma zamanı davranışlarını kontrol edin

Bu adımda, çalışma zamanı davranışlarının beklendiği gibi olduğunu doğrularsınız. Hata ayıklama yapılabilir uygulamalarda, gizli API kullanımını StrictMode.detectNonSdkApiUsage (uygulama gizli bir API kullandığında günlük oluşturur) kullanarak günlük kaydıyla izleyebilirsiniz. Alternatif olarak, kullanım türünü (bağlantı oluşturma veya yansıtma), kısıtlama düzeyini ve çağrı yığınını öğrenmek için veridex statik analiz aracını da kullanabilirsiniz.

  • Veridex söz dizimi:

    ./art/tools/veridex/appcompat.sh --dex-file={apk file}
  • Örnek Veridex sonucu:

    #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;
    

Veridex kullanımıyla ilgili ayrıntılar için Veridex aracını kullanarak test etme başlıklı makaleyi inceleyin.

6. Adım: device.mk dosyasını güncelleyin

Tüm derleme ve çalışma zamanı hatalarını düzelttikten ve çalışma zamanı davranışlarının beklendiği gibi olduğunu doğruladıktan sonra device.mk'te aşağıdakileri ayarlayın:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true