Bộ nhớ đệm APK

Tài liệu này mô tả thiết kế của giải pháp bộ nhớ đệm APK để cài đặt nhanh các ứng dụng tải sẵn trên thiết bị hỗ trợ phân vùng A/B.

OEM có thể đặt các bản tải trước và các ứng dụng phổ biến vào bộ đệm APK được lưu trữ trong phân vùng B gần như trống trên các thiết bị được phân vùng A/B mới mà không ảnh hưởng đến bất kỳ không gian dữ liệu nào của người dùng. Bằng cách có sẵn bộ đệm APK trên thiết bị, các thiết bị mới hoặc được khôi phục cài đặt gốc gần đây sẽ sẵn sàng để sử dụng gần như ngay lập tức mà không cần tải xuống tệp APK từ Google Play.

Trường hợp sử dụng

  • Lưu trữ các ứng dụng tải sẵn trong phân vùng B để thiết lập nhanh hơn
  • Lưu trữ các ứng dụng phổ biến trong phân vùng B để khôi phục nhanh hơn

Điều kiện tiên quyết

Để sử dụng tính năng này, thiết bị cần:

  • Đã cài đặt bản phát hành Android 8.1 (O MR1)
  • Đã triển khai phân vùng A/B

Nội dung tải trước chỉ có thể được sao chép trong lần khởi động đầu tiên. Điều này là do trên các thiết bị hỗ trợ cập nhật hệ thống A/B, phân vùng B không thực sự lưu trữ tệp hình ảnh hệ thống mà thay vào đó tải sẵn nội dung như tài nguyên demo bán lẻ, tệp OAT và bộ đệm APK. Sau khi tài nguyên đã được sao chép vào phân vùng /data (điều này xảy ra trong lần khởi động đầu tiên), phân vùng B sẽ được sử dụng bởi các bản cập nhật qua mạng (OTA) để tải xuống các phiên bản cập nhật của hình ảnh hệ thống.

Do đó, bộ đệm APK không thể được cập nhật qua OTA; nó chỉ có thể được tải sẵn tại nhà máy. Khôi phục cài đặt gốc chỉ ảnh hưởng đến phân vùng /data. Phân vùng hệ thống B vẫn có nội dung được tải sẵn cho đến khi hình ảnh OTA được tải xuống. Sau khi khôi phục cài đặt gốc, hệ thống sẽ thực hiện lại lần khởi động đầu tiên. Điều này có nghĩa là bộ nhớ đệm APK không khả dụng nếu hình ảnh OTA được tải xuống phân vùng B và sau đó thiết bị được khôi phục cài đặt gốc.

Thực hiện

Cách tiếp cận 1. Nội dung trên phân vùng system_other

Ưu điểm : Nội dung tải sẵn không bị mất sau khi khôi phục cài đặt gốc - nó sẽ được sao chép từ phân vùng B sau khi khởi động lại.

Nhược điểm : Yêu cầu dung lượng trên phân vùng B. Khởi động sau khi khôi phục cài đặt gốc cần thêm thời gian để sao chép nội dung được tải sẵn.

Để sao chép các bản tải trước trong lần khởi động đầu tiên, hệ thống gọi một tập lệnh trong /system/bin/preloads_copy.sh . Tập lệnh được gọi với một đối số duy nhất (đường dẫn đến điểm gắn kết chỉ đọc cho phân vùng system_b ):

Để triển khai tính năng này, hãy thực hiện những thay đổi dành riêng cho thiết bị này. Đây là một ví dụ từ Marlin:

  1. Thêm tập lệnh thực hiện sao chép vào tệp device-common.mk (trong trường hợp này là device/google/marlin/device-common.mk ), như vậy:
    # 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
    
    Tìm nguồn tập lệnh mẫu tại: device/google/marlin /preloads_copy.sh
  2. Chỉnh sửa tệp init.common.rc để nó tạo thư mục /data/preloads và các thư mục con cần thiết:
    mkdir /data/preloads 0775 system system
    mkdir /data/preloads/media 0775 system system
    mkdir /data/preloads/demo 0775 system system
    
    Tìm ví dụ về nguồn tệp init tại: device/google/marlin/init.common.rc
  3. Xác định miền SELinux mới trong tệp 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;
    
    Tìm tệp miền SELinux mẫu tại: /device/google/marlin/+/main/sepolicy/preloads_copy.te
  4. Đăng ký tên miền mới /sepolicy/file_contexts file:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    Tìm một ví dụ về tệp bối cảnh SELinux tại: device/google/marlin/sepolicy/preloads_copy.te
  5. Tại thời điểm xây dựng, thư mục có nội dung được tải sẵn phải được sao chép vào phân vùng 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)
    
    Đây là một ví dụ về thay đổi trong Makefile cho phép sao chép tài nguyên bộ đệm APK từ kho lưu trữ Git của nhà cung cấp (trong trường hợp của chúng tôi là nhà cung cấp/google_devices/ marlin/preloads) vào vị trí trên phân vùng system_other mà sau này sẽ được sao chép vào /data/preloads khi thiết bị khởi động lần đầu tiên. Tập lệnh này chạy vào thời điểm xây dựng để chuẩn bị hình ảnh system_other. Nó hy vọng nội dung được tải sẵn sẽ có sẵn trong nhà cung cấp/google_devices/marlin/preloads. OEM có thể tự do chọn tên/đường dẫn kho lưu trữ thực tế.
  6. Bộ đệm APK nằm ở /data/preloads/file_cache và có bố cục sau:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    Đây là cấu trúc thư mục cuối cùng trên thiết bị. OEM có thể tự do lựa chọn bất kỳ phương pháp triển khai nào miễn là cấu trúc tệp cuối cùng sao chép cấu trúc được mô tả ở trên.

Cách tiếp cận 2. Nội dung trên hình ảnh dữ liệu người dùng được flash tại nhà máy

Cách tiếp cận thay thế này giả định rằng nội dung được tải trước đã được bao gồm trong thư mục /data/preloads trên phân vùng /data .

Ưu điểm : Hoạt động tốt - không cần thực hiện tùy chỉnh thiết bị để sao chép tệp trong lần khởi động đầu tiên. Nội dung đã có trên phân vùng /data .

Nhược điểm : Nội dung tải trước sẽ bị mất sau khi khôi phục cài đặt gốc. Mặc dù điều này có thể được chấp nhận đối với một số người, nhưng nó có thể không phải lúc nào cũng hiệu quả đối với các OEM khôi phục cài đặt gốc cho thiết bị sau khi thực hiện kiểm tra kiểm soát chất lượng.

Một phương thức @SystemApi mới, getPreloadsFileCache() , đã được thêm vào android.content.Context . Nó trả về một đường dẫn tuyệt đối đến một thư mục dành riêng cho ứng dụng trong bộ đệm được tải sẵn.

Một phương thức mới, IPackageManager.deletePreloadsFileCache , đã được thêm vào cho phép xóa thư mục tải trước để lấy lại toàn bộ dung lượng. Phương thức này chỉ có thể được gọi bởi các ứng dụng có SYSTEM_UID, tức là máy chủ hệ thống hoặc Cài đặt.

Chuẩn bị ứng dụng

Chỉ các ứng dụng đặc quyền mới có thể truy cập vào thư mục bộ đệm tải trước. Để có quyền truy cập đó, các ứng dụng phải được cài đặt trong thư mục /system/priv-app .

Thẩm định

  • Sau lần khởi động đầu tiên, thiết bị sẽ có nội dung trong thư mục /data/preloads/file_cache .
  • Nội dung trong thư mục file_cache/ phải bị xóa nếu thiết bị sắp hết dung lượng.

Sử dụng ứng dụng ApkCacheTest mẫu để kiểm tra bộ đệm APK.

  1. Xây dựng ứng dụng bằng cách chạy lệnh này từ thư mục gốc:
    make ApkCacheTest
    
  2. Cài đặt ứng dụng như một ứng dụng đặc quyền. (Hãy nhớ rằng chỉ những ứng dụng có đặc quyền mới có thể truy cập bộ đệm APK.) Điều này yêu cầu thiết bị đã root:
    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. Mô phỏng thư mục bộ đệm của tệp và nội dung của nó nếu cần (cũng yêu cầu quyền root):
    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. Kiểm tra ứng dụng. Sau khi cài đặt ứng dụng và tạo thư mục test file_cache , hãy mở ứng dụng ApkCacheTest. Nó sẽ hiển thị một tệp test.txt và nội dung của nó. Xem ảnh chụp màn hình này để biết các kết quả này xuất hiện như thế nào trong giao diện người dùng.

    Hình 1. Kết quả ApkCacheTest