APK'yı önbelleğe alma

Bu dokümanda, A/B bölümlerini destekleyen bir cihaza önceden yüklenmiş uygulamaların hızlı bir şekilde yüklenmesi için bir APK önbelleğe alma çözümünün tasarımı açıklanmaktadır.

OEM'ler, kullanıcılara yönelik veri alanını etkilemeden yeni A/B bölümlendirilmiş cihazlarda çoğunlukla boş olan B bölümünde depolanan APK önbelleğine önceden yüklenmiş uygulamaları ve popüler uygulamaları yerleştirebilir. Cihazlarda APK önbelleği bulunduğunda, yeni veya yakın zamanda fabrika ayarlarına sıfırlanan cihazlar, APK dosyalarını Google Play'den indirmeye gerek kalmadan neredeyse hemen kullanıma hazır olur.

Kullanım örnekleri

  • Daha hızlı kurulum için önceden yüklenmiş uygulamaları B bölümünde depolama
  • Daha hızlı geri yükleme için popüler uygulamaları B bölümünde depolama

Ön koşullar

Bu özelliği kullanmak için cihazın aşağıdakilere sahip olması gerekir:

  • Android 8.1 (O MR1) sürümü yüklü
  • A/B bölümü uygulandı

Önceden yüklenmiş içerikler yalnızca ilk açılış sırasında kopyalanabilir. Bunun nedeni, A/B sistem güncellemelerini destekleyen cihazlarda B bölümünün aslında sistem resim dosyalarını değil, perakende demo kaynakları, OAT dosyaları ve APK önbelleği gibi önceden yüklenmiş içerikleri depolamasıdır. Kaynaklar /data bölümüne kopyalandıktan sonra (bu işlem ilk açılışta gerçekleşir), B bölümü, sistem resminin güncel sürümlerini indirmek için kablosuz (OTA) güncellemeler tarafından kullanılır.

Bu nedenle, APK önbelleği OTA üzerinden güncellenemez; yalnızca fabrikada önceden yüklenebilir. Fabrika ayarlarına sıfırlama işlemi yalnızca /data bölümünü etkiler. OTA görüntüsü indirilene kadar sistem B bölümünde önceden yüklenmiş içerikler bulunur. Fabrika ayarlarına sıfırlamadan sonra sistem tekrar ilk önyüklemeyi gerçekleştirir. Bu, OTA görüntüsünün B bölümüne indirilip cihazın fabrika ayarlarına sıfırlanması durumunda APK önbelleğe alma özelliğinin kullanılamayacağı anlamına gelir.

Uygulama

1. yaklaşım. system_other bölümündeki içerik

Pro: Fabrika ayarlarına sıfırlamadan sonra önceden yüklenmiş içerikler kaybolmaz. Yeniden başlatıldıktan sonra B bölümünden kopyalanır.

Con: B bölümünde alan gerekir. Fabrika ayarlarına sıfırlamadan sonra önyüklenmesi gereken içeriklerin kopyalanması için ek süre gerekir.

Ön yüklemelerin ilk önyükleme sırasında kopyalanması için sistem /system/bin/preloads_copy.sh'te bir komut dosyası çağırır. Komut dosyası tek bir bağımsız değişkenle (system_b bölümü için salt okunur bağlama noktasının yolu) çağrılır:

Bu özelliği uygulamak için cihaza özgü aşağıdaki değişiklikleri yapın. Marlin'den bir örnek:

  1. Kopyalama işlemini yapan komut dosyasını device-common.mk dosyasına (bu örnekte device/google/marlin/device-common.mk) aşağıdaki gibi ekleyin:
    # Script that copies preloads directory from system_other to data partition
    PRODUCT_COPY_FILES += \
        device/google/marlin/preloads_copy.sh:system/bin/preloads_copy.sh
    
    Örnek komut dosyası kaynağını şu adreste bulabilirsiniz: device/google/marlin/preloads_copy.sh
  2. Gerekli /data/preloads dizini ve alt dizinleri oluşturması için init.common.rc dosyasını düzenleyin:
    mkdir /data/preloads 0775 system system
    mkdir /data/preloads/media 0775 system system
    mkdir /data/preloads/demo 0775 system system
    
    init dosya kaynağı örneğini şu adreste bulabilirsiniz: device/google/marlin/init.common.rc
  3. preloads_copy.te dosyasında yeni bir SELinux alanı tanımlayın:
    type preloads_copy, domain, coredomain;
    type preloads_copy_exec, exec_type, vendor_file_type, file_type;
    
    init_daemon_domain(preloads_copy)
    
    allow preloads_copy shell_exec:file rx_file_perms;
    allow preloads_copy toolbox_exec:file rx_file_perms;
    allow preloads_copy preloads_data_file:dir create_dir_perms;
    allow preloads_copy preloads_data_file:file create_file_perms;
    allow preloads_copy preloads_media_file:dir create_dir_perms;
    allow preloads_copy preloads_media_file:file create_file_perms;
    
    # Allow to copy from /postinstall
    allow preloads_copy system_file:dir r_dir_perms;
    
    Örnek bir SELinux alan dosyasını şu adreste bulabilirsiniz: /device/google/marlin/+/main/sepolicy/preloads_copy.te
  4. Alanı yeni bir /sepolicy/file_contexts dosyasına kaydedin:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    Örnek bir SELinux bağlamları dosyasını şu adreste bulabilirsiniz: device/google/marlin/sepolicy/preloads_copy.te
  5. Derleme sırasında, önceden yüklenmiş içeriğin bulunduğu dizin system_other bölümüne kopyalanmalıdır:
    # Copy contents of preloads directory to system_other partition
    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,vendor/google_devices/marlin/preloads,system_other/preloads)
    
    Bu, APK önbelleği kaynaklarının tedarikçinin Git deposundan (bizim durumumuzda vendor/google_devices/marlin/preloads) system_other bölümündeki konuma kopyalanmasına olanak tanıyan bir Makefile değişikliği örneğidir. Bu konumdaki kaynaklar, cihaz ilk kez açıldığında /data/preloads konumuna kopyalanır. Bu komut dosyası, system_other görüntüsünü hazırlamak için derleme sırasında çalışır. Ön yüklenmiş içeriğin vendor/google_devices/marlin/preloads adresinde bulunmasını bekler. OEM, gerçek depo adını/yolunu seçmekte özgürdür.
  6. APK önbelleği /data/preloads/file_cache konumundadır ve aşağıdaki düzene sahiptir:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    Bu, cihazlardaki nihai dizin yapısıdır. OEM'ler, nihai dosya yapısı yukarıda açıklanan yapıyı kopyaladığı sürece herhangi bir uygulama yaklaşımını seçmekte özgürdür.

2. Yaklaşım. Fabrikada gösterilen kullanıcı verileri resmindeki içerik

Bu alternatif yaklaşımda, önceden yüklenmiş içeriğin /data bölümündeki /data/preloads dizinine zaten dahil olduğu varsayılır.

Pro: Hazır olarak çalışır. İlk açılışta dosyaları kopyalamak için cihaz özelleştirmesi yapmanız gerekmez. İçerik zaten /data bölümünde.

Eksi: Fabrika ayarlarına sıfırlama işleminden sonra önceden yüklenmiş içerikler kaybolur. Bu durum bazı kullanıcılar için kabul edilebilir olsa da kalite kontrolü denetimlerini yaptıktan sonra cihazları fabrika ayarlarına sıfırlayan OEM'ler için her zaman işe yaramayabilir.

android.content.Context alanına yeni bir @SystemApi yöntemi (getPreloadsFileCache()) eklendi. Önceden yüklenmiş önbellekte uygulamaya özel bir dizinin mutlak yolunu döndürür.

Tüm alanı geri almak için ön yüklemeler dizininin silinmesine olanak tanıyan yeni bir yöntem (IPackageManager.deletePreloadsFileCache) eklendi. Yöntem yalnızca SYSTEM_UID'ye sahip uygulamalar (ör. sistem sunucusu veya Ayarlar) tarafından çağrılabilir.

Uygulama hazırlama

Yalnızca ayrıcalıklı uygulamalar ön yükleme önbelleği dizinine erişebilir. Bu erişim için uygulamaların /system/priv-app dizinine yüklenmesi gerekir.

Doğrulama

  • İlk başlatma işleminden sonra cihazın /data/preloads/file_cache dizininde içerik olmalıdır.
  • Cihazın depolama alanı dolduğunda file_cache/ dizinindeki içerik silinmelidir.

APK önbelleğini test etmek için örnek ApkCacheTest uygulamasını kullanın.

  1. Kök dizinden şu komutu çalıştırarak uygulamayı derleyin:
    make ApkCacheTest
    
  2. Uygulamayı ayrıcalıklı uygulama olarak yükleyin. (Yalnızca ayrıcalıklı uygulamaların APK önbelleği erişebileceğini unutmayın.) Bunun için root erişimli bir cihaz gerekir:
    adb root && adb remount
    adb shell mkdir /system/priv-app/ApkCacheTest
    adb push $ANDROID_PRODUCT_OUT/data/app/ApkCacheTest/ApkCacheTest.apk /system/priv-app/ApkCacheTest/
    adb shell stop && adb shell start
    
  3. Gerekirse dosya önbelleği dizinini ve içeriğini simüle edin (root ayrıcalıkları da gerekir):
    adb shell mkdir -p /data/preloads/file_cache/com.android.apkcachetest
    adb shell restorecon -r /data/preloads
    adb shell "echo "Test File" > /data/preloads/file_cache/com.android.apkcachetest/test.txt"
    
  4. Uygulamayı test edin. Uygulamayı yükleyip test file_cache dizini oluşturduktan sonra ApkCacheTest uygulamasını açın. Bir test.txt dosyası ve içeriği gösterilir. Bu sonuçların kullanıcı arayüzünde nasıl göründüğünü görmek için bu ekran görüntüsüne bakın.

    Şekil 1. ApkCacheTest sonuçları.