APK ক্যাশিং

এই ডকুমেন্টে এ/বি পার্টিশন সমর্থনকারী ডিভাইসে আগে থেকে লোড করা অ্যাপ দ্রুত ইনস্টল করার জন্য একটি এপিকে ক্যাশিং সলিউশনের ডিজাইন বর্ণনা করা হয়েছে।

OEM-রা নতুন A/B পার্টিশনযুক্ত ডিভাইসগুলির প্রায় খালি B পার্টিশনে সংরক্ষিত APK ক্যাশে প্রি-লোড এবং জনপ্রিয় অ্যাপগুলি রাখতে পারে, যা ব্যবহারকারীর ডেটা স্পেসকে প্রভাবিত করে না। ডিভাইসে APK ক্যাশে উপলব্ধ থাকার ফলে, নতুন বা সম্প্রতি ফ্যাক্টরি রিসেট করা ডিভাইসগুলি গুগল প্লে থেকে APK ফাইল ডাউনলোড করার প্রয়োজন ছাড়াই প্রায় সঙ্গে সঙ্গেই ব্যবহারের জন্য প্রস্তুত হয়ে যায়।

ব্যবহারের ক্ষেত্র

  • দ্রুত সেটআপের জন্য আগে থেকে লোড করা অ্যাপগুলো B পার্টিশনে সংরক্ষণ করুন।
  • দ্রুত পুনরুদ্ধারের জন্য জনপ্রিয় অ্যাপগুলি B পার্টিশনে সংরক্ষণ করুন।

পূর্বশর্ত

এই বৈশিষ্ট্যটি ব্যবহার করার জন্য ডিভাইসটিতে প্রয়োজন:

  • অ্যান্ড্রয়েড ৮.১ (ও এমআর১) রিলিজ ইনস্টল করা হয়েছে
  • এ/বি বিভাজন বাস্তবায়িত হয়েছে

প্রি-লোডেড কন্টেন্ট শুধুমাত্র প্রথম বুটের সময় কপি করা যায়। এর কারণ হলো, A/B সিস্টেম আপডেট সমর্থনকারী ডিভাইসগুলিতে B পার্টিশনে আসলে সিস্টেম ইমেজ ফাইল জমা থাকে না, বরং সেখানে রিটেইল ডেমো রিসোর্স, OAT ফাইল এবং APK ক্যাশের মতো প্রি-লোডেড কন্টেন্ট থাকে। রিসোর্সগুলি /data পার্টিশনে কপি হয়ে যাওয়ার পর (যা প্রথম বুটের সময় ঘটে), B পার্টিশনটি ওভার-দ্য-এয়ার (OTA) আপডেটের মাধ্যমে সিস্টেম ইমেজের আপডেটেড সংস্করণ ডাউনলোড করার জন্য ব্যবহৃত হয়।

সুতরাং, OTA-এর মাধ্যমে APK ক্যাশে আপডেট করা যায় না; এটি শুধুমাত্র ফ্যাক্টরিতেই প্রি-লোড করা যায়। ফ্যাক্টরি রিসেট শুধুমাত্র /data পার্টিশনকে প্রভাবিত করে। OTA ইমেজ ডাউনলোড না হওয়া পর্যন্ত সিস্টেমের B পার্টিশনে প্রি-লোড করা কন্টেন্ট থেকে যায়। ফ্যাক্টরি রিসেটের পর, সিস্টেমটি আবার প্রথম বুট প্রক্রিয়ার মধ্যে দিয়ে যাবে। এর মানে হলো, যদি B পার্টিশনে OTA ইমেজ ডাউনলোড করার পর ডিভাইসটি ফ্যাক্টরি রিসেট করা হয়, তাহলে APK ক্যাশিং আর পাওয়া যাবে না।

বাস্তবায়ন

পদ্ধতি ১. 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. প্রয়োজনীয় /data/preloads ডিরেক্টরি এবং সাবডিরেক্টরিগুলো তৈরি করার জন্য init.common.rc ফাইলটি সম্পাদনা করুন:
    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. preloads_copy.te ফাইলে একটি নতুন SELinux ডোমেইন সংজ্ঞায়িত করুন:
    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/+/android17-release/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-এর পরিবর্তনের উদাহরণ, যা ভেন্ডরের গিট রিপোজিটরি (আমাদের ক্ষেত্রে এটি ছিল vendor/google_devices/marlin/preloads) থেকে APK ক্যাশ রিসোর্স system_other পার্টিশনের এমন একটি লোকেশনে কপি করার সুযোগ দেয়, যা ডিভাইসটি প্রথমবার বুট করার সময় /data/preloads-এ কপি করা হবে। এই স্ক্রিপ্টটি system_other ইমেজ প্রস্তুত করার জন্য বিল্ড টাইমে চলে। এটি আশা করে যে প্রি-লোডেড কন্টেন্ট vendor/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/
    
    এটিই ডিভাইসগুলোর চূড়ান্ত ডিরেক্টরি কাঠামো। OEM-রা যেকোনো বাস্তবায়ন পদ্ধতি বেছে নিতে পারেন, যতক্ষণ পর্যন্ত চূড়ান্ত ফাইল কাঠামোটি উপরে বর্ণিত কাঠামোর অনুরূপ হয়।

পদ্ধতি ২। ব্যবহারকারীর ডেটা ইমেজে থাকা বিষয়বস্তু যা কারখানায় ফ্ল্যাশ করা হয়েছিল।

এই বিকল্প পদ্ধতিটি ধরে নেয় যে প্রি-লোডেড কন্টেন্ট ইতিমধ্যেই /data পার্টিশনের /data/preloads ডিরেক্টরিতে অন্তর্ভুক্ত রয়েছে।

সুবিধা : এটি ইনস্টল করার সাথে সাথেই কাজ করে - প্রথম বুটে ফাইল কপি করার জন্য ডিভাইসে কোনো কাস্টমাইজেশন করার প্রয়োজন নেই। কন্টেন্ট আগে থেকেই /data পার্টিশনে থাকে।

অসুবিধা : ফ্যাক্টরি রিসেট করার পর আগে থেকে লোড করা কন্টেন্ট হারিয়ে যায়। যদিও এটি কারও কারও জন্য গ্রহণযোগ্য হতে পারে, তবে যারা গুণমান নিয়ন্ত্রণ পরিদর্শনের পর ডিভাইস ফ্যাক্টরি রিসেট করে, সেইসব OEM-দের জন্য এটি সবসময় কার্যকর নাও হতে পারে।

android.content.ContextgetPreloadsFileCache() নামে একটি নতুন @SystemApi মেথড যোগ করা হয়েছে। এটি প্রি-লোডেড ক্যাশে থাকা অ্যাপ-নির্দিষ্ট একটি ডিরেক্টরির অ্যাবসোলিউট পাথ রিটার্ন করে।

IPackageManager.deletePreloadsFileCache নামে একটি নতুন মেথড যোগ করা হয়েছে, যা প্রিলোডস ডিরেক্টরি মুছে ফেলে সমস্ত জায়গা পুনরুদ্ধার করতে দেয়। এই মেথডটি শুধুমাত্র SYSTEM_UID যুক্ত অ্যাপ, অর্থাৎ সিস্টেম সার্ভার বা সেটিংস দ্বারা কল করা যাবে।

অ্যাপ প্রস্তুতি

শুধুমাত্র বিশেষাধিকারপ্রাপ্ত অ্যাপগুলোই প্রিলোড ক্যাশ ডিরেক্টরি অ্যাক্সেস করতে পারে। এই অ্যাক্সেসের জন্য, অ্যাপগুলোকে অবশ্যই /system/priv-app ডিরেক্টরিতে ইনস্টল করতে হবে।

বৈধতা

  • প্রথমবার বুট করার পর, ডিভাইসটির /data/preloads/file_cache ডিরেক্টরিতে কন্টেন্ট থাকা উচিত।
  • ডিভাইসের স্টোরেজ কমে গেলে file_cache/ ডিরেক্টরির ভেতরের কন্টেন্ট মুছে ফেলতে হবে।

APK ক্যাশে পরীক্ষা করার জন্য উদাহরণ ApkCacheTest অ্যাপটি ব্যবহার করুন।

  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. অ্যাপটি পরীক্ষা করুন। অ্যাপটি ইনস্টল করার পর এবং test file_cache ডিরেক্টরি তৈরি করার পর, ApkCacheTest অ্যাপটি খুলুন। এটিতে test.txt নামের একটি ফাইল এবং তার ভেতরের বিষয়বস্তু দেখানো উচিত। ইউজার ইন্টারফেসে এই ফলাফলগুলো কীভাবে দেখা যায় তা দেখতে এই স্ক্রিনশটটি দেখুন।

    চিত্র ১. ApkCacheTest-এর ফলাফল।