ओटीए पैकेज के अंदर

सिस्टम, bootable/recovery/updater से अपडेटर बाइनरी बनाता है और उसका इस्तेमाल, ओटीए पैकेज में करता है.

पैकेज एक .zip फ़ाइल (ota_update.zip, incremental_ota_update.zip) है, जिसमें एक्ज़ीक्यूटेबल बाइनरी META-INF/com/google/android/update-binary शामिल है.

Updater में कई इन-बिल्ट फ़ंक्शन और एक्सटेंसिबल स्क्रिप्टिंग भाषा (edify) के लिए एक इंटरप्रेटर होता है. यह अपडेट से जुड़े सामान्य टास्क के लिए निर्देशों के साथ काम करता है. अपडेटर, पैकेज की .zip फ़ाइल में, फ़ाइल META-INF/com/google/android/updater-script में मौजूद स्क्रिप्ट खोजता है.

ध्यान दें: edify स्क्रिप्ट और/या पहले से मौजूद फ़ंक्शन का इस्तेमाल करना आम बात नहीं है. हालांकि, अपडेट फ़ाइल को डीबग करने के लिए, इनका इस्तेमाल मददगार हो सकता है.

Edify सिंटैक्स

edify स्क्रिप्ट एक ऐसा एक्सप्रेशन है जिसमें सभी वैल्यू स्ट्रिंग होती हैं. बूलियन कॉन्टेक्स्ट में, खाली स्ट्रिंग false होती हैं और अन्य सभी स्ट्रिंग true होती हैं. Edify में ये ऑपरेटर इस्तेमाल किए जा सकते हैं:

(expr )
 expr + expr  # string concatenation, not integer addition
 expr == expr
 expr != expr
 expr && expr
 expr || expr
 ! expr
 if expr then expr endif
 if expr then expr else expr endif
 function_name(expr, expr,...)
 expr; expr

a-z, A-Z, 0-9, _, :, /, . वर्ण वाली कोई भी स्ट्रिंग को स्ट्रिंग लिटरल माना जाता है. (रिज़र्व किए गए शब्द if else हैं, इसके बाद endif.) स्ट्रिंग लिटरल, डबल कोट में भी दिख सकते हैं. इस तरह, ऊपर दिए गए सेट में शामिल नहीं होने वाले व्हाइटस्पेस और अन्य वर्णों के साथ वैल्यू बनाई जा सकती हैं. कोट की गई स्ट्रिंग में, \n, \t, \", और \\ एस्केप कैरेक्टर के तौर पर काम करते हैं. \x## भी ऐसा ही करता है.

&& और || ऑपरेटर शॉर्ट-सर्किट कर रहे हैं; अगर बाईं ओर मौजूद वैल्यू के आधार पर लॉजिकल नतीजा तय हो जाता है, तो दाईं ओर मौजूद वैल्यू का आकलन नहीं किया जाता. ये एक जैसे हैं:

e1 && e2
if e1 then e2 endif

; ऑपरेटर एक क्रम बिंदु है. इसका मतलब है कि पहले बाईं ओर और फिर दाईं ओर का आकलन करना. इसकी वैल्यू, दाईं ओर मौजूद एक्सप्रेशन की वैल्यू होती है. सेमीकोलन, किसी एक्सप्रेशन के बाद भी दिख सकता है, ताकि C-स्टाइल स्टेटमेंट का असर दिखे:

prepare();
do_other_thing("argument");
finish_up();

पहले से मौजूद फ़ंक्शन

अपडेट करने की ज़्यादातर सुविधाएं, स्क्रिप्ट के ज़रिए लागू करने के लिए उपलब्ध फ़ंक्शन में होती हैं. (सही मायनों में, ये Lisp के हिसाब से फ़ंक्शन के बजाय मैक्रो हैं, क्योंकि इन्हें अपने सभी आर्ग्युमेंट का आकलन करने की ज़रूरत नहीं होती.) जब तक कोई जानकारी अलग से नहीं दी जाती, तब तक फ़ंक्शन, काम करने पर true और गड़बड़ी होने पर false दिखाते हैं. अगर आपको गड़बड़ियों की वजह से स्क्रिप्ट को बंद करना है, तो abort() और/या assert() फ़ंक्शन का इस्तेमाल करें. अपडेटर में उपलब्ध फ़ंक्शन के सेट को भी बढ़ाया जा सकता है, ताकि डिवाइस के हिसाब से फ़ंक्शन उपलब्ध कराए जा सकें.

abort([msg])
msg के साथ, स्क्रिप्ट को तुरंत बंद कर देता है. हालांकि, msg का इस्तेमाल करना ज़रूरी नहीं है. अगर उपयोगकर्ता ने टेक्स्ट डिसप्ले की सुविधा चालू की है, तो रिकवरी लॉग और स्क्रीन पर msg दिखता है.
assert(expr[, expr, ...])
हर expr का आकलन करता है. अगर कोई भी एक्सप्रेशन गलत है, तो "असर्ट पूरा नहीं हुआ" मैसेज और गलत एक्सप्रेशन के सोर्स टेक्स्ट के साथ, एक्सप्रेशन को तुरंत बंद कर दिया जाता है.
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
tgt_file बनाने के लिए, src_file में बाइनरी पैच लागू करता है. अगर आपका टारगेट, सोर्स जैसा ही है, तो tgt_file के लिए "-" पास करें. tgt_sha1 और tgt_size, टारगेट फ़ाइल के अनुमानित फ़ाइनल SHA1 हैश और साइज़ हैं. बाकी आर्ग्युमेंट, एक साथ दो में होने चाहिए: SHA1 हैश (40 वर्णों की हेक्स स्ट्रिंग) और ब्लॉब. सोर्स फ़ाइल के मौजूदा कॉन्टेंट में दिया गया SHA1 होने पर, ब्लॉब को पैच के तौर पर लागू किया जाता है.

पैच करने की प्रोसेस को सुरक्षित तरीके से किया जाता है, ताकि यह पक्का किया जा सके कि टारगेट फ़ाइल में, SHA1 हैश और साइज़ सही हो या उसमें कोई बदलाव न किया गया हो. साथ ही, उसे ऐसी स्थिति में न छोड़ा जाए जिसे ठीक न किया जा सके. अगर पैच करने के दौरान प्रोसेस में रुकावट आती है, तो टारगेट फ़ाइल अधूरी हो सकती है. कैश मेमोरी में फ़ाइल की एक कॉपी मौजूद होती है. इसलिए, अपडेट को फिर से शुरू करने पर, फ़ाइल को अपडेट किया जा सकता है.

मेमोरी टेक्नोलॉजी डिवाइस (MTD) के सेगमेंट के कॉन्टेंट को फ़ाइलों के तौर पर इस्तेमाल करने के लिए, खास सिंटैक्स का इस्तेमाल किया जा सकता है. इससे, बूट जैसे रॉ सेगमेंट को पैच करने में मदद मिलती है. एमटीडी पार्टीशन को पढ़ने के लिए, आपको यह पता होना चाहिए कि आपको कितना डेटा पढ़ना है, क्योंकि इस पार्टीशन में फ़ाइल के आखिर में मौजूद डेटा का पता नहीं चलता. दिए गए पार्टीशन को पढ़ने के लिए, स्ट्रिंग "MTD:partition:size_1:sha1_1:size_2: sha1_2" का इस्तेमाल, फ़ाइल के नाम के तौर पर किया जा सकता है. आपको कम से कम एक (size, sha-1) पेयर की जानकारी देनी होगी. अगर आपको पढ़ने के लिए एक से ज़्यादा विकल्प मिलते हैं, तो एक से ज़्यादा पेयर की जानकारी दी जा सकती है.

apply_patch_check(filename, sha1[, sha1, ...])
अगर filename के कॉन्टेंट या कैश मेमोरी वाले सेक्शन में मौजूद फ़ाइल की अस्थायी कॉपी (अगर मौजूद हो) का SHA1 चेकसम, दी गई sha1 वैल्यू में से किसी एक के बराबर है, तो यह फ़ंक्शन 'सही' दिखाता है. sha1 वैल्यू को 40 हेक्साडेसिमल अंकों के तौर पर दिखाया जाता है. यह फ़ंक्शन, sha1_check(read_file(filename), sha1 [, ...]) से अलग है, क्योंकि यह कैश मेमोरी के सेगमेंट की कॉपी की जांच करता है. इसलिए, apply_patch() update के बीच में रुकने की वजह से फ़ाइल खराब होने पर भी, apply_patch_check() काम करेगा.
apply_patch_space(bytes)
अगर बाइनरी पैच लागू करने के लिए, कम से कम बाइट का स्क्रैच स्पेस उपलब्ध है, तो यह फ़ंक्शन 'सही' दिखाता है.
concat(expr[, expr, ...])
हर एक्सप्रेशन का आकलन करता है और उन्हें आपस में जोड़ता है. + ऑपरेटर, दो आर्ग्युमेंट के खास मामले में, इस फ़ंक्शन के लिए सिंटैक्टिक शुगर है. हालांकि, फ़ंक्शन फ़ॉर्म में किसी भी संख्या में एक्सप्रेशन हो सकते हैं. एक्सप्रेशन स्ट्रिंग होने चाहिए. इनमें ब्लॉब को जोड़ा नहीं जा सकता.
file_getprop(filename, key)
दिए गए filename को पढ़ता है और उसे प्रॉपर्टी फ़ाइल (उदाहरण के लिए, /system/build.prop) के तौर पर समझता है.साथ ही, दिए गए key की वैल्यू दिखाता है. अगर key मौजूद नहीं है , तो वह खाली स्ट्रिंग दिखाता है.
format(fs_type, partition_type, location, fs_size, mount_point)
किसी दिए गए पार्टीशन को फिर से फ़ॉर्मैट करता है. इस्तेमाल किए जा सकने वाले पार्टीशन टाइप:
  • fs_type="yaffs2" और partition_type="MTD". जगह का नाम, MTD के partition का नाम होना चाहिए. यहां एक खाली yaffs2 फ़ाइल सिस्टम बनाया जाता है. बाकी आर्ग्युमेंट का इस्तेमाल नहीं किया जाता.
  • fs_type="ext4" और partition_type="EMMC". जगह की जानकारी, डिवाइस के उस partition की फ़ाइल होनी चाहिए. वहां एक खाली ext4 फ़ाइलसिस्टम बनाया जाता है. अगर fs_size शून्य है, तो फ़ाइल सिस्टम पूरे पार्टीशन को ले लेता है. अगर fs_size कोई धनात्मक संख्या है, तो फ़ाइल सिस्टम, पार्टिशन के पहले fs_size बाइट का इस्तेमाल करता है. अगर fs_size एक ऋणात्मक संख्या है, तो फ़ाइल सिस्टम, विभाजन के आखिरी |fs_size| बाइट को छोड़कर, बाकी सभी बाइट लेता है.
  • fs_type="f2fs" और partition_type="EMMC". जगह, डिवाइस के लिए बने partition की फ़ाइल होनी चाहिए. fs_size की वैल्यू, शून्य से ज़्यादा होनी चाहिए. अगर fs_size शून्य है, तो फ़ाइल सिस्टम पूरे पार्टीशन को ले लेता है. अगर fs_size कोई धनात्मक संख्या है, तो फ़ाइल सिस्टम, पार्टिशन के पहले fs_size बाइट का इस्तेमाल करता है.
  • mount_point, फ़ाइल सिस्टम के लिए आने वाले समय में माउंट पॉइंट होना चाहिए.
getprop(key)
सिस्टम प्रॉपर्टी key की वैल्यू दिखाता है. अगर यह प्रॉपर्टी तय नहीं की गई है, तो खाली स्ट्रिंग दिखाता है. रिकवरी पार्टीशन से तय की गई सिस्टम प्रॉपर्टी की वैल्यू, मुख्य सिस्टम की वैल्यू से अलग हो सकती हैं. यह फ़ंक्शन रिकवरी में वैल्यू दिखाता है.
greater_than_int(a, b)
सिर्फ़ तब सही वैल्यू दिखाता है, जब a (इसे पूर्णांक के तौर पर समझा जाता है) की वैल्यू, b (इसे पूर्णांक के तौर पर समझा जाता है) की वैल्यू से ज़्यादा हो.
ifelse(cond, e1[, e2])
cond का आकलन करता है. अगर यह सही है, तो e1 की वैल्यू का आकलन करता है और उसे दिखाता है, अगर यह गलत है, तो e2 (अगर मौजूद है) का आकलन करता है और उसे दिखाता है. "if ... else ... then ... endif" कंस्ट्रक्ट, इस फ़ंक्शन के लिए सिर्फ़ सिंटैक्स शुगर है.
is_mounted(mount_point)
अगर mount_point पर कोई फ़ाइल सिस्टम माउंट किया गया है, तो यह फ़ंक्शन True दिखाता है.
is_substring(needle, haystack)
अगर needle, haystack की सबस्ट्रिंग है, तो यह फ़ंक्शन True दिखाता है.
less_than_int(a, b)
अगर a (इसे पूर्णांक के तौर पर समझा जाता है) b (इसे पूर्णांक के तौर पर समझा जाता है) से कम है, तो यह फ़ंक्शन True दिखाता है.
mount(fs_type, partition_type, name, mount_point)
mount_point पर fs_type का फ़ाइल सिस्टम माउंट करता है. partition_type, इनमें से कोई एक होना चाहिए:
  • MTD. नाम, किसी MTD पार्टीशन का नाम होता है.जैसे, सिस्टम, उपयोगकर्ता डेटा. पूरी सूची के लिए, डिवाइस पर /proc/mtd देखें.
  • EMMC.

रिकवरी मोड में, डिफ़ॉल्ट रूप से कोई फ़ाइल सिस्टम माउंट नहीं होता. हालांकि, अगर उपयोगकर्ता एसडी कार्ड से किसी पैकेज को मैन्युअल तरीके से इंस्टॉल कर रहा है, तो एसडी कार्ड को माउंट किया जाता है. आपकी स्क्रिप्ट को उन सभी पार्टिशन को माउंट करना होगा जिनमें बदलाव करना है.

package_extract_dir(package_dir, dest_dir)
package_dir में मौजूद पैकेज से सभी फ़ाइलें निकालता है और उन्हें dest_dir में मौजूद उसी ट्री में लिखता है. मौजूदा फ़ाइलें ओवरराइट हो जाती हैं.
package_extract_file(package_file[, dest_file])
अपडेट पैकेज से एक package_file निकालता है और उसे dest_file में लिखता है. ज़रूरत पड़ने पर, मौजूदा फ़ाइलों को बदल देता है. dest_file आर्ग्युमेंट के बिना, पैकेज फ़ाइल के कॉन्टेंट को बाइनरी ब्लॉब के तौर पर दिखाता है.
read_file(filename)
filename को पढ़ता है और उसके कॉन्टेंट को बाइनरी ब्लॉब के तौर पर दिखाता है.
run_program(path[, arg, ...])
arg पास करके, path पर बाइनरी को चलाता है. प्रोग्राम के बंद होने का स्टेटस दिखाता है.
set_progress(frac)
हाल ही में किए गए show_progress() कॉल से तय किए गए चंक में, प्रोग्रेस मेटर की पोज़िशन सेट करता है. frac की वैल्यू, [0.0, 1.0] के बीच होनी चाहिए. प्रोग्रेस मीटर कभी पीछे नहीं जाता. इसे पीछे ले जाने की कोशिशों को अनदेखा कर दिया जाता है.
sha1_check(blob[, sha1])
blob आर्ग्युमेंट, read_file() से मिलने वाले टाइप का ब्लॉब होता है या package_extract_file() का एक आर्ग्युमेंट वाला फ़ॉर्म होता है. sha1 आर्ग्युमेंट के बिना, यह फ़ंक्शन ब्लॉब का SHA1 हैश (40 अंकों की हेक्स स्ट्रिंग के तौर पर) दिखाता है. एक या एक से ज़्यादा sha1 आर्ग्युमेंट के साथ, यह फ़ंक्शन SHA1 हैश दिखाता है. ऐसा तब होता है, जब यह किसी एक आर्ग्युमेंट के बराबर हो. अगर यह किसी भी आर्ग्युमेंट के बराबर नहीं है, तो यह खाली स्ट्रिंग दिखाता है.
show_progress(frac, secs)
प्रोग्रेस मेटर को secs सेकंड में, उसकी लंबाई के अगले frac हिस्से तक आगे बढ़ाता है. secs 0 हो सकता है. ऐसे में, मेटर अपने-आप आगे नहीं बढ़ता, बल्कि ऊपर बताए गए set_progress() फ़ंक्शन का इस्तेमाल करके आगे बढ़ता है.
sleep(secs)
secs सेकंड के लिए रुकें (यह एक पूर्णांक होना चाहिए).
stdout(expr[, expr, ...])
हर एक्सप्रेशन का आकलन करता है और उसकी वैल्यू को स्टैंडर्ड आउटपुट (stdout) में डालता है. डीबग करने के लिए काम की है.
tune2fs(device[, arg, …])
डिवाइस पर, ट्यून किए जा सकने वाले पैरामीटर args में बदलाव करता है.
ui_print([text, ...])
सभी text आर्ग्युमेंट को जोड़ता है और नतीजे को यूज़र इंटरफ़ेस (यूआई) पर प्रिंट करता है. अगर उपयोगकर्ता ने टेक्स्ट डिसप्ले चालू किया है, तो यह नतीजा दिखेगा.
unmount(mount_point)
mount_point पर माउंट किए गए फ़ाइल सिस्टम को अनमाउंट करता है.
wipe_block_device(block_dev, len)
यह दिए गए ब्लॉक डिवाइस block_dev के len बाइट को मिटा देता है.
wipe_cache()
इससे, इंस्टॉलेशन पूरा होने के बाद कैश मेमोरी का पार्टीशन मिट जाता है.
write_raw_image(filename_or_blob, partition)
MTD partition में, filename_or_blob में इमेज को लिखता है. filename_or_blob, किसी लोकल फ़ाइल का नाम हो सकती है या लिखने के लिए डेटा वाला ब्लॉब वैल्यू वाला आर्ग्युमेंट हो सकता है. ओटीए पैकेज से किसी फ़ाइल को किसी पार्टीशन में कॉपी करने के लिए, इनका इस्तेमाल करें: write_raw_image(package_extract_file("zip_filename"), "partition_name");

ध्यान दें: Android 4.1 से पहले, सिर्फ़ फ़ाइल के नाम स्वीकार किए जाते थे. इसलिए, ऐसा करने के लिए, डेटा को पहले किसी अस्थायी लोकल फ़ाइल में अनज़िप करना पड़ता था.