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

Android 11, product bölümünü ayırarak system ve vendor bölümlerinden bağımsız hale getirir. Bu değişiklikler kapsamında, product bölümünün yerel ve Java arayüzlerine erişimini kontrol edebilirsiniz (bu, arayüz zorlamasının vendor bölümlerinde çalışma şekline benzer).

Yerel arayüzleri zorunlu kılma

Yerel arayüz zorunluluğunu etkinleştirmek için PRODUCT_PRODUCT_VNDK_VERSION değerini current olarak ayarlayın. (Hedefin kargo API düzeyi 29'dan yüksek olduğunda sürüm otomatik olarak current olarak ayarlanır.) Yaptırım, aşağıdakilere olanak tanır:

  • Bağlantı oluşturulacak product bölümündeki yerel modüller:
    • Statik, paylaşılan veya başlık kitaplıklarını 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 bağlanır.
  • product bölümündeki paketlenmemiş APK'larda bulunan JNI kitaplıkları, /product/lib veya /product/lib64 bölümündeki kitaplıklara bağlanır (bu, NDK kitaplıklarına ek olarak yapılır).

Yaptırım, product bölümü dışındaki bölümlere başka bağlantıların eklenmesine izin vermez.

Derleme zamanı zorunlu kılma (Android.bp)

Android 11'de sistem modülleri, temel ve satıcı görüntü varyantlarına ek olarak bir ürün görüntüsü varyantı oluşturabilir. Yerel arayüz zorunluluğu 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ında yer alır.

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

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

  • VNDK kitaplıkları, product_available: true dosyalarında Android.bp içermelidir. Böylece product ikilileri VNDK kitaplıklarına bağlanabilir.

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

Android.bp dosyasındaki özellikler Oluşturulan varyantlar
Yaptırım uygulanmadan önce Yaptırım uygulandıktan sonra
varsayılan (yok) core
(/system, /system_ext ve /product dahil)
core
(/system ve /system_ext'yi içerir ancak /product'ü içermez)
system_ext_specific: true core bölgesi core bölgesi
product_specific: true core bölgesi ürün
vendor: true otomatik satış makinesi otomatik satış makinesi
vendor_available: true core, vendor core, vendor
product_available: true Yok core, product
vendor_available: true VE product_available: true Yok çekirdek, ürün, tedarikçi
system_ext_specific: true VE vendor_available: true core, vendor core, vendor
product_specific: true VE vendor_available: true core, vendor ürün, satıcı

Derleme zamanı zorunluluğu (Android.mk)

Yerel arayüz zorunluluğu etkinleştirildiğinde, product bölümüne yüklenen yerel modüllerin yalnızca diğer native:product veya native:vndk modüllerine bağlanabilen bir native:product bağlantı türü olur. Bunların 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ı zorunlu kılma

Yerel arayüz zorunluluğu etkinleştirildiğinde, bionic bağlayıcı için bağlayıcı yapılandırması, sistem işlemlerinin product kitaplıklarını kullanmasına izin vermez. Bu nedenle, product bölümü dışındaki 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 etme girişimleri, 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ü zorunluluğunu etkinleştirmek için PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE değerini true olarak ayarlayın. (Hedefin kargo API düzeyi 29'dan yüksek olduğunda değer otomatik olarak true olarak ayarlanır.) Etkinleştirildiğinde zorlama, aşağıdaki erişime izin verir veya erişimi engeller:

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ğlanmaya izin verilmez. Bu kısıtlama, derleme zamanında bağlamayı ve çalışma zamanında yansıtmayı içerir.

Derleme zamanında yaptırım

Derleme sırasında Make ve Soong, 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 kısmı current, system_current veya API'nin sayısal sürümüyle doldurulmalı ve platform_apis alanı boş olmalıdır.

Çalışma zamanı zorunlu kılma

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

Ürün arayüzü zorunluluğunu etkinleştirme

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

Adım Task Zorunlu
1 system bölümündeki paketleri belirten kendi sistem makefile'ınızı tanımlayın, ardından device.mk bölümünde yapay nesne yolu gereksinimi kontrolünü ayarlayın (sistem dışı modüllerin system bölümüne yüklenmesini önlemek için). N
2 İzin verilenler listesini temizleyin. N
3 Yerel arayüzleri zorunlu kılın ve çalışma zamanı bağlantı hatalarını belirleyin (Java zorunlu kılma ile paralel olarak çalıştırılabilir). Y
4 Java arayüzlerini zorunlu kılın ve çalışma zamanı davranışını doğrulayın (yerel zorunlu kılma ile paralel olarak çalıştırılabilir). Y
5 Çalışma zamanı davranışlarını kontrol edin. Y
6 Ürün arayüzü zorunluluğu ile device.mk güncellemesi. Y

1. adım: makefile oluşturun ve yapay nesne yolu kontrolünü etkinleştirin

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

  1. system bölümündeki paketleri 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'ı devralın ve yapıt yolu şartları kontrolünü etkinleştirin. Örneğin:

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

Yapay nesne yolu koşulları hakkında

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

Yukarıdaki örnekte, PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS strict olarak ayarlandığında oem_system.mk dışındaki makefile'lar, root veya system bölümüne yüklenen modülleri içeremez. Bu modülleri eklemek için bunları oem_system.mk dosyasında veya dahil edilen bir makefile'da tanımlamanız gerekir. Modüllerin izin verilmeyen yollara yüklenmeye çalışılması derleme hatalarına neden olur. Satır sonu sorunlarını düzeltmek için aşağıdakilerden birini yapın:

  • 1. seçenek: Sistem modülünü, oem_system.mk içinde bulunan makefile'lara ekleyin. Bu sayede, yapay ürün yolu şartı karşılanır (modüller artık dahil edilen bir makefile'da bulunduğundan) ve böylece `require-artifacts-in-path` içindeki yollar kümesine yükleme yapılmasına izin verilir.

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

  • 3. seçenek: Modülleri PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST bölümüne ekleyin. Bu listede, yüklenebilecek izin verilen modüller yer alır.

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

Bu adımda, PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST paylaşan tüm cihazların tek bir system resmi de paylaşabilmesi için oem_system.mk boş bırakılır. İ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. Ortak bir system resim tanımlamak, ürün arayüzü zorunluluğunu etkinleştirmek için gerekli olmadığından bu adım isteğe bağlıdır. Ancak izin verilenler listesini boşaltmak, system ile system_ext arasındaki sınırı 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 ayarlarsınız, ardından derleme ve çalışma zamanı hatalarını arayıp bunları çözersiniz. Cihazın başlatılmasını ve günlüklerini kontrol etmek, çalışma zamanı bağlantı hatalarını bulup düzeltmek için:

  1. PRODUCT_PRODUCT_VNDK_VERSION := current olarak ayarlayın.

  2. Cihazı oluşturun ve derleme hatalarını arayın. Eksik ürün varyantları veya temel varyantlar nedeniyle birkaç derleme hatası görmeniz olasıdır. Yaygın aralar şunlardır:

    • product_specific: true içeren hidl_interface modülleri, sistem modüllerinde kullanılamaz. Düzeltmek için product_specific: true yerine system_ext_specific: true yazın.
    • Modüllerde, ürün modülleri için gerekli olan ürün varyantı eksik olabilir. Bu sorunu düzeltmek için product bölümünde product_available: true ayarını yaparak modülü kullanılabilir hâle getirin veya modülü product bölümüne taşıyın ve product_specific: true ayarını yapı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 başlatma ile günlüklerde çalışma zamanı hatalarını arayın.

    • Bir test durumu günlüğündeki linker etiketi CANNOT LINK EXECUTABLE mesajını gösteriyorsa 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ıda verilen yönergeleri 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 ayarlarsınız. Ardından, ortaya çıkan derleme hatalarını bulup düzeltirsiniz. İki tür hataya dikkat edin:

  • Bağlantı türü hataları Bu hata, bir uygulamanın daha geniş bir sdk_version olan Java modüllerine bağlandığını gösterir. Bu sorunu düzeltmek için uygulamanın sdk_version kapsamını genişletebilir veya kitaplığın sdk_version kapsamını 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, bir sembolün gizli bir API'de olduğu için 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ğrulayacaksınız. Hata ayıklanabilir uygulamalarda, StrictMode.detectNonSdkApiUsage kullanarak gizli API kullanımını günlük kaydıyla izleyebilirsiniz (bu, uygulama gizli bir API kullandığında günlük oluşturur). Alternatif olarak, kullanım türünü (bağlantı veya yansıtma), kısıtlama düzeyini ve çağrı yığınını almak için veridex statik analiz aracını 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 bölümünde aşağıdakileri ayarlayın:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true