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 من خلال OTA؛ ولا يمكن تحميله مسبقًا إلا في المصنع. تؤثر إعادة ضبط المصنع على القسم / البيانات فقط. لا يزال قسم النظام B يحتوي على المحتوى الذي تم تحميله مسبقًا حتى يتم تنزيل صورة OTA. بعد إعادة ضبط المصنع، سيخضع النظام للتمهيد الأول مرة أخرى. وهذا يعني أن التخزين المؤقت لـ APK غير متاح إذا تم تنزيل صورة OTA إلى القسم B، ثم تمت إعادة ضبط الجهاز على إعدادات المصنع.

تطبيق

النهج 1. المحتوى على قسم system_other

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

Con : يتطلب مساحة على القسم 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 الخاص بالبائع (في حالتنا كان البائع/google_devices/ marlin/preloads) إلى الموقع على قسم system_other الذي سيتم نسخه لاحقًا إلى /data/preloads عند تشغيل الجهاز لأول مرة. يعمل هذا البرنامج النصي في وقت الإنشاء لإعداد صورة system_other. ويتوقع أن يكون المحتوى الذي تم تحميله مسبقًا متاحًا في المورد/google_devices/marlin/preloads. OEM حر في اختيار اسم/مسار المستودع الفعلي.
  6. توجد ذاكرة التخزين المؤقت لـ APK في /data/preloads/file_cache ولها التخطيط التالي:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    هذه هي بنية الدليل النهائية على الأجهزة. يتمتع مصنعو المعدات الأصلية بحرية اختيار أي أسلوب تنفيذ طالما أن بنية الملف النهائية تكرر تلك الموضحة أعلاه.

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

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

Pro : يعمل خارج الصندوق - لا حاجة لإجراء تخصيصات الجهاز لنسخ الملفات عند التشغيل الأول. المحتوى موجود بالفعل في القسم /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. نتائج اختبار ApkCache