التخزين المؤقت لحِزم APK

يصف هذا المستند تصميم حل تخزين ملفات APK مؤقتًا للتثبيت السريع. من التطبيقات المُحمَّلة مسبقًا على جهاز يتيح استخدام أقسام A/B

يمكن للمصنّعين الأصليين للأجهزة وضع عمليات التحميل المسبقة والتطبيقات الشائعة في ذاكرة التخزين المؤقت لحِزمة APK المخزّنة في ذاكرة التخزين المؤقت تقسيم B فارغ على أجهزة جديدة مقسمة باستخدام A/B بدون التأثير أي مساحة بيانات مواجهة للمستخدم. من خلال إتاحة ذاكرة تخزين مؤقت لملف APK على الجهاز، سواء كان الأجهزة التي تمت إعادة ضبطها على الإعدادات الأصلية مؤخرًا جاهزة للاستخدام على الفور تقريبًا، بدون الحاجة إلى تنزيل ملفات APK من Google Play.

حالات الاستخدام

  • تخزين التطبيقات المُحمَّلة مسبقًا في القسم B للإعداد بشكلٍ أسرع
  • تخزين التطبيقات الرائجة في القسم B لاستعادة الأداء بشكل أسرع

المتطلّبات الأساسية

لاستخدام هذه الميزة، يحتاج الجهاز إلى ما يلي:

  • تم تثبيت إصدار Android 8.1 (O MR1)
  • تم تنفيذ قسم A/B

لا يمكن نسخ المحتوى المُحمَّل مُسبَقًا إلا أثناء التشغيل الأول فقط. هذا لأنه في التي تتيح تحديثات نظام A/B (أ/ب)، فلا يخزن القسم B في الواقع وملفات صور النظام، ولكن بدلاً من ذلك المحتوى المحمّل مسبقًا مثل موارد العرض التوضيحي للبيع بالتجزئة، ملفات OAT وذاكرة التخزين المؤقت لحِزم APK. بعد نسخ الموارد إلى /data (يحدث هذا عند التشغيل لأول مرة)، فسيتم استخدام القسم B عبر شبكة عبر شبكة غير سلكيّة (OTA) تحديثات لتنزيل نُسخ مُعدَّلة من صورة النظام.

ولذلك، لا يمكن تحديث ذاكرة التخزين المؤقت لحزمة APK من خلال التحديث عبر الهواء، يمكن تحميله مسبقًا فقط في مصنع. تؤثر إعادة الضبط على الإعدادات الأصلية في قسم /data فقط. النظام B الاحتفاظ بالمحتوى الذي تم تحميله مسبقًا إلى أن يتم تنزيل صورة عبر الهواء. بعد إعادة الضبط على الإعدادات الأصلية، سيبدأ النظام عملية التشغيل الأولى مرّة أخرى. يعني ذلك أنّ حزمة APK لا يكون التخزين المؤقت متاحًا إذا تم تنزيل صورة OTA على القسم B، فسيتم إعادة ضبط الجهاز على الإعدادات الأصلية.

التنفيذ

الطريقة 1. المحتوى مفعَّل قسم System_other

احترافي: المحتوى الذي تم تحميله مسبقًا لا يتم فقدانه بعد إعادة ضبطه على الإعدادات الأصلية، بل سيتم نسخها من القسم B بعد إعادة التشغيل.

السلبيات: تتطلب مساحة في القسم B. التشغيل بعد إعادة الضبط على الإعدادات الأصلية يتطلب وقتًا إضافيًا لنسخ المحتوى المحمَّل مسبقًا.

لنسخ عمليات التحميل المُسبقة أثناء التشغيل الأول، يستدعي النظام نصًا برمجيًا. في /system/bin/preloads_copy.sh. يتم استدعاء النص باستخدام علامة الوسيطة (المسار إلى نقطة التثبيت للقراءة فقط في system_b ):

لتطبيق هذه الميزة، عليك إجراء هذه التغييرات الخاصة بالجهاز. إليك مثال من مارلين:

  1. أضِف النص البرمجي الذي ينفّذ النسخ إلى device-common.mk. (في هذه الحالة، device/google/marlin/device-common.mk)، مثل:
    # 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
    
    يمكنك العثور على مثال لمصدر النص البرمجي على: device/google/marlin/preloads_copy.sh.
  2. عدِّل ملف init.common.rc لإنشاء الملف الدليل والأدلة الفرعية /data/preloads الضرورية:
    mkdir /data/preloads 0775 system system
    mkdir /data/preloads/media 0775 system system
    mkdir /data/preloads/demo 0775 system system
    
    يمكنك العثور على مثال لمصدر ملف init على: device/google/marlin/init.common.rc
  3. حدد نطاق SELinux جديد في الملف preloads_copy.te:
    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;
    
    ابحث عن نموذج لملف نطاق SELinux على: /device/google/marlin/+/main/sepolicy/preloads_copy.te
  4. تسجيل النطاق في /sepolicy/file_contexts جديد الملف:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    ابحث عن نموذج لملف سياقات SELinux على: device/google/marlin/sepolicy/preloads_copy.te
  5. في وقت الإصدار، يجب نسخ الدليل الذي يتضمن محتوى تم تحميله مسبقًا إلى قسم system_other:
    # 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)
    
    هذا مثال على تغيير في ملف Makefile يسمح بنسخ ذاكرة التخزين المؤقت لحِزم APK. الموارد من مستودع Git للمورد (في حالتنا كانت Seller/google_devices/marlin/preloads) على الموقع الجغرافي في القسم system_other. الذي سيتم نسخه لاحقًا إلى /data/preloads عند تشغيل الجهاز لأول مرة الوقت. يتم تشغيل هذا النص البرمجي في وقت الإصدار لإعداد صورة system_other. من المتوقع المحتوى المُحمَّل مسبقًا ليكون متوفرًا في sellers/google_devices/marlin/preloads. المصنّع الأصلي للجهاز يمكن اختيار اسم/مسار المستودع الفعلي.
  6. تتوفّر ذاكرة التخزين المؤقت لملف APK في /data/preloads/file_cache وبه التخطيط التالي:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    هذه هي بنية الدليل النهائية على الأجهزة. للمصنّعين الأصليين للأجهزة حرية الاختيار أي نهج تنفيذ طالما أن هيكل الملف النهائي يكرر واحد كما هو موضح أعلاه.

الطريقة 2. المحتوى في بيانات المستخدمين ومضت الصورة في المصنع

تفترض هذه الطريقة البديلة أن المحتوى المُحمَّل مُسبَقًا سبق أن تم تضمينه في دليل /data/preloads على القسم /data.

المحترفون: يعمل بطريقة غير تقليدية بدون الحاجة إلى صنع جهاز. التخصيصات لنسخ الملفات عند التشغيل لأول مرة. المحتوى موجود على قسم واحد (/data).

السلبيات: يتم فقدان المحتوى المُحمَّل مسبقًا بعد إعادة الضبط على الإعدادات الأصلية. بينما قد يكون هذا مقبولاً للبعض، وقد لا يصلح دائمًا للمصنّعين الأصليين للأجهزة الذين إعادة ضبط الأجهزة بعد إجراء فحوصات مراقبة الجودة.

تمت إضافة طريقة @SystemApi جديدة، وهي getPreloadsFileCache()، إلى android.content.Context فهي تُرجع مسارًا مطلقًا إلى الدليل الخاص بالتطبيق في ذاكرة التخزين المؤقت المُحمَّلة مسبقًا.

تمت إضافة طريقة جديدة، IPackageManager.deletePreloadsFileCache يسمح بحذف دليل التحميل المسبق باستعادة كل المساحة. يمكن للطريقة إلا بواسطة التطبيقات التي تتضمن SYSTEM_UID، أي خادم النظام أو الإعدادات.

إعداد التطبيقات

يمكن للتطبيقات الحاصلة على الأذونات فقط الوصول إلى دليل ذاكرة التخزين المؤقت للتحميل المُسبق. لذلك الوصول، يجب تثبيت التطبيقات في الدليل /system/priv-app.

التحقُّق

  • بعد التشغيل الأول، يجب أن يتضمن الجهاز محتوى في دليل /data/preloads/file_cache.
  • يجب حذف المحتوى في دليل file_cache/ إذا كانت انخفاض مساحة التخزين في الجهاز.

استخدِم المثال ApkcacheTest اختبار ذاكرة التخزين المؤقت لحِزم APK.

  1. أنشِئ التطبيق من خلال تنفيذ الأمر التالي من الدليل الجذري:
    make ApkCacheTest
    
  2. ثبِّت التطبيق كتطبيق امتياز. (تذكر أنه لا يمكن الوصول إلى ذاكرة التخزين المؤقت لحِزم APK إلا للتطبيقات المميزة). يتطلب هذا استخدام جهاز جذر:
    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. محاكاة دليل ذاكرة التخزين المؤقت للملف ومحتواه إذا لزم الأمر (يتطلب أيضًا امتيازات الجذر):
    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. اختبِر التطبيق. بعد تثبيت التطبيق وإنشاء دليل file_cache للاختبار، افتح تطبيق ApkcacheTest. من المفترض أن يعرض ملف test.txt واحد ومحتواه. يمكنك الاطّلاع على لقطة الشاشة هذه لمعرفة كيفية ظهور هذه النتائج في واجهة المستخدم.

    الشكل 1. نتائج ApkcacheTest