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

Android 11, product bölümünü gruplandırarak system ve vendor bölümlerinden bağımsız hale getirir. 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ü zorunlu kılmayı etkinleştirmek için PRODUCT_PRODUCT_VNDK_VERSION öğesini 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:
    • product bölümünde statik, paylaşılan veya başlık kitaplıkları içeren diğer modüllere statik ya da dinamik olarak gönderilir.
    • system bölümündeki VNDK kitaplıklarına dinamik olarak.
  • product veya /product/lib64 bölümündeki kitaplıklara bağlanmak için product bölümündeki paketlenmemiş APK'lardaki JNI kitaplıkları (NDK kitaplıklarına ek olarak)./product/lib

Zorunlu kılma, product bölümü dışındaki bölüm bağlantılarına 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, ana 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 dahildir ancak /product hariç)
system_ext_specific: true core core
product_specific: true core ürün
vendor: true otomatik satış makinesi otomatik satış makinesi
vendor_available: true çekirdek, satıcı core, vendor
product_available: true Yok çekirdek, ürün
vendor_available: true VE product_available: true Yok core, product, vendor
system_ext_specific: true VE vendor_available: true core, vendor çekirdek, satıcı
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ünden hariç kitaplıklara bağlantı oluşturamayan product işlemleri için bir product bölümü oluşturulur (ancak bu tür işlemler VNDK kitaplıklarına bağlantı oluşturabilir). Ç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.) Etkinleştirildiğinde, zorunlu kılma işlemi aşağıdaki erişime izin verir veya erişimi engeller:

API /system /system_ext /product /vendor /data
Public API
@SystemApi
@gizle 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ıtmayı 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 alanı current, system_current veya API'nin sayısal sürümüyle doldurulmalı 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üzlerle ilgili kısıtlamalar bölümüne bakın.

Ürün arayüzü zorunlu kılmayı etkinleştir

Ü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ü için paketleri belirten kendi sistem oluşturma dosyanızı tanımlayın ve ardından device.mk içinde yapı yolu gereksinimi denetimini 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ılın ve çalışma zamanı bağlantı hatalarını belirleyin (Java yaptırımıyla 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'ı tanımlarsınız.

  1. system bölümünün paketlerini tanımlayan bir makefile oluşturun. Örneğin, aşağıdaki gibi 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 oem_system.mk dosyasında veya dahil edilen bir makefile dosyasında tanımlamanız gerekir. İzin verilmeyen yollara modül yükleme denemeleri, derleme araları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çinde yer alan makefiles'e ekleyin. Bu, yapı yolu gereksiniminin karşılanmasını sağlar (modüller artık dahil olan bir oluşturma dosyasında mevcut olduğundan) ve böylece, "gerekli-yapıdaki yollardaki yollar" kümesine yükleme işlemi yapılmasını sağlar.

  • 2. Seçenek: Modülleri system_ext veya product bölümüne yükleyin (ve system bölümüne modül 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 değerini 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 veya system dosya oluşturma bölümüne 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 listesinin boşaltılması, system_ext ile system sınırını 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 başlatma ve günlüklerini kontrol etmek ve çalışma zamanı bağlantısı 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 ayarlarını yaparsınız. Ardından, sonuçta 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ş bir sdk_version öğesine sahip Java modüllerine bağlantı verdiğini 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ü (bağlantı veya yansıma), kısıtlama seviyesi ve çağrı yığınını öğrenmek 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 bölümüne bakın.

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 içinde şunları ayarlayın:

  • PRODUCT_PRODUCT_VNDK_VERSION := current
  • PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true