APK ক্যাশিং

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

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

উদাহরণ

  • দ্রুত সেট-আপ করার জন্য B পার্টিশনে প্রি-লোডেড অ্যাপ স্টোর করা
  • আরও দ্রুত রিস্টোর করার জন্য B পার্টিশনে জনপ্রিয় অ্যাপ স্টোর করুন

পূর্বশর্ত

এই ফিচার ব্যবহার করতে, ডিভাইসে এগুলি থাকতে হবে:

  • Android 8.1 (O MR1) রিলিজ ইনস্টল করা হয়েছে
  • A/B পার্টিশন প্রয়োগ করা হয়েছে

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

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

প্রয়োগ

পদ্ধতি ১. system_other পার্টিশনে কন্টেন্ট

সুবিধা: ফ্যাক্টরি রিসেট করার পরে প্রি-লোডেড কন্টেন্ট হারিয়ে যায় না - এটি রি-বুট করার পরে B পার্টিশন থেকে কপি করা হবে।

বিপক্ষ: B পার্টিশনে জায়গা প্রয়োজন। ফ্যাক্টরি রিসেট করার পরে বুট করতে প্রিলোড করা কন্টেন্ট কপি করার জন্য অতিরিক্ত সময় প্রয়োজন।

প্রথম বুটের সময় প্রি-লোড কপি করার জন্য, সিস্টেম /system/bin/preloads_copy.sh-এ একটি স্ক্রিপ্ট কল করে। স্ক্রিপ্টটি একটি আর্গুমেন্ট (system_b পার্টিশনের জন্য কেবল পঠনযোগ্য মাউন্ট পয়েন্টের পাথ) সহ কল করা হয়:

এই ফিচার প্রয়োগ করতে, ডিভাইস-নির্দিষ্ট এইসব পরিবর্তন করুন। Marlin থেকে পাওয়া একটি উদাহরণ:

  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-এ পরিবর্তনের একটি উদাহরণ যা APK ক্যাশে কপি করার অনুমতি দেয় ভেন্ডরের Git রিপোজিটরি থেকে রিসোর্স (আমাদের ক্ষেত্রে এটি ছিল vendor/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/
    
    ডিভাইসে এটি হল চূড়ান্ত ডিরেক্টরি স্ট্রাকচার। চূড়ান্ত ফাইল স্ট্রাকচার উপরে বর্ণিত স্ট্রাকচারের মতো হলেই, OEM যেকোনও প্রয়োগের পদ্ধতি বেছে নিতে পারে।

পদ্ধতি ২. ব্যবহারকারীর ডেটাতে থাকা কন্টেন্ট ফ্যাক্টরিতে ফ্ল্যাশ করা ছবি

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

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

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

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

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

    ছবি ১. ApkCacheTest ফলাফল।