Lưu tệp APK vào bộ nhớ đệm

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

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

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

  • Lưu trữ các ứng dụng tải trước 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

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

Do đó, bạn không thể cập nhật bộ nhớ đệm của APK thông qua OTA; chỉ có thể tải trước ứng dụng này tại nhà máy. Việc đặt lại về trạng thái ban đầu chỉ ảnh hưởng đến phân vùng /data. Hệ thống B vẫn có nội dung được tải trước cho đến khi hình ảnh OTA được tải xuống. Sau khi đặt lại về trạng thái ban đầu, 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à APK tính năng lưu vào bộ nhớ đệm sẽ không hoạt động nếu hình ảnh OTA được tải xuống phân vùng B và thì thiết bị sẽ được đặt lại về trạng thái ban đầu.

Triển khai

Phương pháp 1. Nội dung đang bật phân vùng system_other

Ưu điểm: Nội dung đã tải trước sẽ không bị mất sau khi đặt lại về trạng thái ban đầu sẽ được sao chép từ phân vùng B sau khi khởi động lại.

Nhược điểm: Cần có không gian trên phân vùng B. Khởi động sau khi đặt lại về trạng thái ban đầu cần thêm thời gian để sao chép nội dung tải trước.

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

Để triển khai tính năng này, hãy thực hiện các thay đổi theo từng thiết bị sau. Dưới đây là một ví dụ từ Marlin:

  1. Thêm tập lệnh thực hiện việc sao chép vào device-common.mk (trong trường hợp này là device/google/marlin/device-common.mk), như sau:
    # 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 ví dụ về nguồn tập lệnh tại: device/google/marlin/Adds_copy.sh
  2. Chỉnh sửa tệp init.common.rc để tạo tệp thư mục /data/preloads cần thiết và các thư mục con:
    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 một tệp miền SELinux mẫu tại: /device/google/marlin/+/main/sepolicy/ngừas_copy.te
  4. Đăng ký miền trong một /sepolicy/file_contexts mới tệp:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    Tìm một tệp ngữ cảnh SELinux mẫu tại: device/google/marlin/sepolicy/khoás_copy.te
  5. Tại thời điểm tạo, thư mục có nội dung được tải trước 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à ví dụ về thay đổi trong tệp Makefile cho phép sao chép bộ nhớ đệm của tệp APK tài nguyên từ kho lưu trữ Git của nhà cung cấp (trong trường hợp của chúng tôi là provider/google_devices/marlin/previews) vào vị trí trên phân vùng system_other Sau đó, tệp này sẽ được sao chép vào /data/foregrounds khi thiết bị khởi động lần đầu tiên bất cứ lúc nào. Tập lệnh này chạy trong thời gian xây dựng để chuẩn bị hình ảnh system_other. Dự kiến nội dung được tải trước có sẵn trong provider/google_devices/marlin/submitteds. OEM (Nhà sản xuất thiết bị gốc) bạn có thể tuỳ ý chọn tên/đường dẫn thực tế của kho lưu trữ.
  6. Bộ nhớ đệm APK nằm trong /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 các thiết bị. OEM được thoải mái 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 một định dạng được mô tả ở trên.

Phương pháp 2. Nội dung trên dữ liệu người dùng hình ảnh được flash tại trạng thái ban đầu

Phương pháp thay thế này giả định rằng nội dung tải trước đã được đưa vào trong thư mục /data/preloads trên phân vùng /data.

Ưu điểm: Hoạt động ngay từ đầu – không cần phải sản xuất 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 đặt lại về trạng thái ban đầu. Trong khi điều này có thể chấp nhận được đối với một số nhà sản xuất nhưng có thể không phải lúc nào cũng phù hợp với các OEM nhà máy đặt lại thiết bị sau khi kiểm tra quản lý chất lượng.

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

Đã thêm một phương thức mới là IPackageManager.deletePreloadsFileCache cho phép xoá thư mục tải trước để lấy lại tất cả dung lượng. Phương thức này có thể chỉ đượ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ỉ những ứng dụng đặc quyền mới có thể truy cập vào thư mục bộ nhớ đệm đã tải trước. Để làm được việc đó quyền truy cập, các ứng dụng phải được cài đặt trong thư mục /system/priv-app.

Xác nhận kết quả

  • 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ị xoá nếu thiết bị sắp hết bộ nhớ.

Sử dụng ví dụ ApkCacheTest để kiểm tra bộ nhớ đệm APK.

  1. Tạo ứng dụng bằng cách chạy lệnh sau từ thư mục gốc:
    make ApkCacheTest
    
  2. Cài đặt ứng dụng dưới dạng ứ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 vào bộ nhớ đệm của APK.) Điều này đòi hỏi một thiết bị bị can thiệp hệ thống:
    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ộ nhớ đệm của tệp và nội dung trong thư mục đó nếu cần (cũng yêu cầu đặc quyền gốc):
    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 file_cache kiểm thử, hãy mở ứng dụng ApkCacheTest. Phải hiển thị một tệp test.txt và nội dung của tệp đó. Xem ảnh chụp màn hình này để xem cách những kết quả này xuất hiện trong giao diện người dùng.

    Hình 1. Kết quả ApkCacheTest.