एपीके कैशिंग

यह दस्तावेज़ ए/बी विभाजन का समर्थन करने वाले डिवाइस पर प्रीलोडेड ऐप्स की त्वरित स्थापना के लिए एपीके कैशिंग समाधान के डिज़ाइन का वर्णन करता है।

ओईएम किसी भी उपयोगकर्ता-सामना वाले डेटा स्थान को प्रभावित किए बिना नए ए/बी-विभाजित उपकरणों पर ज्यादातर खाली बी विभाजन में संग्रहीत एपीके कैश में प्रीलोड और लोकप्रिय ऐप्स रख सकते हैं। डिवाइस पर एपीके कैश उपलब्ध होने से, नए या हाल ही में फ़ैक्टरी रीसेट डिवाइस Google Play से एपीके फ़ाइलों को डाउनलोड किए बिना, लगभग तुरंत उपयोग के लिए तैयार हो जाते हैं।

बक्सों का इस्तेमाल करें

  • तेज़ सेटअप के लिए प्रीलोडेड ऐप्स को बी पार्टीशन में स्टोर करें
  • तेजी से पुनर्स्थापन के लिए लोकप्रिय ऐप्स को बी पार्टीशन में स्टोर करें

आवश्यक शर्तें

इस सुविधा का उपयोग करने के लिए, डिवाइस को चाहिए:

  • Android 8.1 (O MR1) रिलीज़ स्थापित
  • ए/बी विभाजन लागू किया गया

प्रीलोडेड सामग्री को केवल पहले बूट के दौरान ही कॉपी किया जा सकता है। ऐसा इसलिए है क्योंकि ए/बी सिस्टम अपडेट का समर्थन करने वाले उपकरणों पर, बी विभाजन वास्तव में सिस्टम छवि फ़ाइलों को संग्रहीत नहीं करता है, बल्कि इसके बजाय खुदरा डेमो संसाधनों, ओएटी फाइलों और एपीके कैश जैसी सामग्री को प्रीलोड करता है। संसाधनों को /डेटा विभाजन में कॉपी करने के बाद (यह पहले बूट पर होता है), बी विभाजन का उपयोग सिस्टम छवि के अद्यतन संस्करणों को डाउनलोड करने के लिए ओवर-द-एयर (ओटीए) अपडेट द्वारा किया जाएगा।

इसलिए, एपीके कैश को ओटीए के माध्यम से अपडेट नहीं किया जा सकता है; इसे केवल किसी फ़ैक्टरी में ही प्रीलोड किया जा सकता है। फ़ैक्टरी रीसेट केवल /डेटा विभाजन को प्रभावित करता है। ओटीए छवि डाउनलोड होने तक सिस्टम बी विभाजन में अभी भी प्रीलोडेड सामग्री है। फ़ैक्टरी रीसेट के बाद, सिस्टम फिर से पहले बूट से गुजरेगा। इसका मतलब यह है कि यदि ओटीए छवि बी पार्टीशन में डाउनलोड की जाती है और फिर डिवाइस फ़ैक्टरी रीसेट होता है तो एपीके कैशिंग उपलब्ध नहीं है।

कार्यान्वयन

दृष्टिकोण 1. system_other विभाजन पर सामग्री

प्रो : फ़ैक्टरी रीसेट के बाद प्रीलोडेड सामग्री नष्ट नहीं होती है - इसे रीबूट के बाद बी विभाजन से कॉपी किया जाएगा।

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
    
    उदाहरण स्क्रिप्ट स्रोत यहां ढूंढें: डिवाइस/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 फ़ाइल स्रोत यहां ढूंढें: डिवाइस/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/+/main/sepolicy/preloads_copy.te
  4. डोमेन को नये रूप में पंजीकृत करें /sepolicy/file_contexts फ़ाइल:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    यहां SELinux संदर्भ फ़ाइल का एक उदाहरण ढूंढें: डिवाइस/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)
    
    यह मेकफ़ाइल में बदलाव का एक उदाहरण है जो विक्रेता के गिट रिपॉजिटरी से एपीके कैश संसाधनों की प्रतिलिपि बनाने की अनुमति देता है (हमारे मामले में यह विक्रेता/google_devices/ था) मार्लिन/प्रीलोड्स) को system_other विभाजन पर स्थित स्थान पर ले जाएं, जिसे बाद में डिवाइस के पहली बार बूट होने पर /डेटा/प्रीलोड्स में कॉपी किया जाएगा। यह स्क्रिप्ट system_other छवि तैयार करने के लिए बिल्ड समय पर चलती है। यह अपेक्षा करता है कि विक्रेता/google_devices/marlin/preloads में प्रीलोडेड सामग्री उपलब्ध हो। OEM वास्तविक रिपॉजिटरी नाम/पथ चुनने के लिए स्वतंत्र है।
  6. एपीके कैश /data/preloads/file_cache में स्थित है और इसमें निम्नलिखित लेआउट है:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    यह डिवाइस पर अंतिम निर्देशिका संरचना है। OEM किसी भी कार्यान्वयन दृष्टिकोण को चुनने के लिए स्वतंत्र हैं, जब तक कि अंतिम फ़ाइल संरचना ऊपर वर्णित की नकल करती है।

दृष्टिकोण 2. उपयोगकर्ता डेटा छवि पर सामग्री फ़ैक्टरी में फ़्लैश हुई

यह वैकल्पिक दृष्टिकोण मानता है कि प्रीलोडेड सामग्री पहले से ही / /data /data/preloads निर्देशिका में शामिल है।

प्रो : बॉक्स से बाहर काम करता है - पहले बूट पर फ़ाइलों की प्रतिलिपि बनाने के लिए डिवाइस अनुकूलन करने की आवश्यकता नहीं है। सामग्री पहले से ही /data विभाजन पर है।

Con : फ़ैक्टरी रीसेट के बाद प्रीलोडेड सामग्री खो जाती है। हालांकि यह कुछ लोगों के लिए स्वीकार्य हो सकता है, लेकिन यह हमेशा ओईएम के लिए काम नहीं कर सकता है जो गुणवत्ता नियंत्रण निरीक्षण करने के बाद डिवाइस को फ़ैक्टरी रीसेट करते हैं।

android.content.Context में एक नई @SystemApi विधि, getPreloadsFileCache() जोड़ी गई। यह प्रीलोडेड कैश में एप्लिकेशन-विशिष्ट निर्देशिका के लिए एक पूर्ण पथ लौटाता है।

एक नई विधि, IPackageManager.deletePreloadsFileCache , जोड़ी गई जो सभी स्थान को पुनः प्राप्त करने के लिए प्रीलोड निर्देशिका को हटाने की अनुमति देती है। इस विधि को केवल SYSTEM_UID, यानी सिस्टम सर्वर या सेटिंग्स वाले ऐप्स द्वारा ही कॉल किया जा सकता है।

ऐप की तैयारी

केवल विशेषाधिकार प्राप्त एप्लिकेशन ही प्रीलोड कैश निर्देशिका तक पहुंच सकते हैं। उस पहुंच के लिए, ऐप्स को /system/priv-app निर्देशिका में इंस्टॉल किया जाना चाहिए।

मान्यकरण

  • पहले बूट के बाद, डिवाइस में /data/preloads/file_cache निर्देशिका में सामग्री होनी चाहिए।
  • यदि डिवाइस में स्टोरेज कम हो जाए तो file_cache/ डायरेक्टरी की सामग्री को हटा देना चाहिए।

एपीके कैश का परीक्षण करने के लिए उदाहरण ApkCacheTest ऐप का उपयोग करें।

  1. इस कमांड को रूट डायरेक्टरी से चलाकर ऐप बनाएं:
    make ApkCacheTest
    
  2. ऐप को एक विशेषाधिकार प्राप्त एप्लिकेशन के रूप में इंस्टॉल करें। (याद रखें, केवल विशेषाधिकार प्राप्त ऐप्स ही एपीके कैश तक पहुंच सकते हैं।) इसके लिए रूट किए गए डिवाइस की आवश्यकता होती है:
    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. ApkCacheTest परिणाम