درون بسته‌های آژانس مسافرتی آنلاین

سیستم باینری به‌روزرسان را از bootable/recovery/updater می‌سازد و از آن در بسته OTA استفاده می‌کند.

خود بسته یک فایل ‎ .zip است (ota_update.zip، incremental_ota_update.zip) که حاوی فایل اجرایی دودویی META-INF/com/google/android/update-binary است.

«به‌روزرسان» شامل چندین عملکرد داخلی و مفسری برای زبان اسکریپت توسعه‌پذیر (edify) است که از دستورات مربوط به وظایف معمول به‌روزرسانی پشتیبانی می‌کند. «به‌روزرسان» در فایل .zip بسته به‌دنبال یک دستورگان در فایل META-INF/com/google/android/updater-script می‌گردد.

توجه: استفاده از دستورگان edify و/یا توابع داخلی فعالیت رایجی نیست، اما اگر نیاز به اشکال‌زدایی فایل به‌روزرسانی دارید می‌تواند مفید باشد.

نحو Edify

یک اسکریپت edify یک عبارت واحد است که در آن همه مقادیر رشته هستند. رشته‌های خالی در بافت بولی نادرست هستند و همه رشته‌های دیگر درست هستند. 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،‏ ۰-۹،‏ _،‏ :،‏ /،‏ . که واژه رزروشده‌ای نباشد، به‌عنوان حرف‌نویس رشته‌ای درنظر گرفته می‌شود. (واژه‌های رزروشده عبارت‌اند از if else then endif.) نویسه‌های رشته‌ای نیز ممکن است در نقل‌قول‌های دوگانه ظاهر شوند؛ این روش ایجاد مقادیر با فضای سفید و نویسه‌های دیگری است که در مجموعه بالا نیستند. \n،‏ \t،‏ \"، و \\ به‌عنوان نویسه‌های گریز در رشته‌های نقل‌قول‌دار عمل می‌کنند، همان‌طور که \x## عمل می‌کند.

عملگرهای && و || اتصال کوتاه هستند؛ اگر نتیجه منطقی با سمت چپ تعیین شود، سمت راست ارزیابی نمی‌شود. موارد زیر معادل هستند:

e1 && e2
if e1 then e2 endif

عملگر ; یک نقطه توالی است؛ یعنی ابتدا سمت چپ و سپس سمت راست ارزیابی می‌شود. مقدار آن مقدار عبارت سمت راست است. همچنین می‌توان از نقطه‌ویرگول بعداز عبارت استفاده کرد، بنابراین جلوه عبارات سبک C را شبیه‌سازی می‌کند:

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

توابع داخلی

بیشتر عملکرد به‌روزرسانی در عملکردهای دردسترس برای اجرای اسکریپت‌ها گنجانده شده است. (به‌طور دقیق، این‌ها بیشتر ماکرو هستند تا تابع به مفهوم Lisp، زیرا لازم نیست همه آرگومان‌هایشان را ارزیابی کنند.) مگر اینکه خلاف آن ذکر شده باشد، توابع درصورت موفقیت درست و درصورت خطا نادرست برمی‌گردانند. اگر می‌خواهید خطاها اجرای اسکریپت را متوقف کنند، از تابع‌های abort() و/یا assert() استفاده کنید. مجموعه عملکردهای دردسترس در به‌روزرسان را می‌توان برای ارائه عملکرد مختص دستگاه نیز گسترش داد.

abort([msg])
اجرای بلافاصله دستورگان را با msg اختیاری لغو می‌کند. اگر کاربر نمایش نوشتار را روشن کرده باشد، msg در گزارش بازیابی و روی صفحه ظاهر می‌شود.
assert(expr[, expr, ...])
هر expr را به‌نوبت ارزیابی می‌کند. اگر هرکدام نادرست باشد، بلافاصله اجرا را با پیام «assert failed» و متن منبع عبارت ناموفق لغو می‌کند.
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
وصله دودویی را روی src_file اعمال می‌کند تا tgt_file را تولید کند. اگر هدف موردنظر با منبع یکسان است، «-» را برای tgt_file ارسال کنید. tgt_sha1 و tgt_size درهم‌سازی SHA1 نهایی و اندازه موردانتظار فایل هدف هستند. آرگومان‌های باقی‌مانده باید به‌صورت جفت باشند: یک درهم‌سازی SHA1 (یک رشته هگز ۴۰ نویسه‌ای) و یک حباب. blob وصله‌ای است که وقتی محتوای فعلی فایل منبع SHA1 داده‌شده را داشته باشد اعمال می‌شود.

وصله‌گذاری به‌شیوه‌ای ایمن انجام می‌شود که تضمین می‌کند فایل هدف یا اندازه و درهم‌سازی SHA1 مطلوب را دارد یا دست‌نخورده است—در وضعیت میانی غیرقابل‌بازیابی رها نخواهد شد. اگر فرایند درحین وصله‌گذاری قطع شود، ممکن است فایل هدف در وضعیت واسطه‌ای قرار بگیرد؛ نسخه‌ای از آن در پارتیشن حافظه نهان وجود دارد، بنابراین با بازراه‌اندازی به‌روزرسانی، فایل می‌تواند باموفقیت به‌روزرسانی شود.

نحو ویژه برای رفتار با محتوای پارتیشن‌های «دستگاه فناوری حافظه» (MTD) به‌عنوان فایل پشتیبانی می‌شود و امکان وصله کردن پارتیشن‌های خام مانند بوت را فراهم می‌کند. برای خواندن پارتیشن MTD باید بدانید که می‌خواهید چقدر داده بخوانید زیرا پارتیشن مفهوم پایان فایل ندارد. می‌توانید از رشته «MTD:partition:size_1:sha1_1:size_2: sha1_2» به‌عنوان نام فایل برای خواندن پارتیشن داده‌شده استفاده کنید. باید حداقل یک جفت (اندازه، sha-1) مشخص کنید؛ اگر چندین امکان برای آنچه انتظار دارید بخوانید وجود دارد، می‌توانید بیش‌از یک جفت مشخص کنید.

apply_patch_check(filename, sha1[, sha1, ...])
اگر محتوای filename یا نسخه موقت در بخش حافظه نهان (درصورت وجود) دارای مجموع وارسی SHA1 برابر با یکی از مقادیر sha1 داده‌شده باشد، درست برمی‌گرداند. مقادیر sha1 به‌صورت ۴۰ رقم هگزادسیمال مشخص می‌شوند. این تابع با sha1_check(read_file(filename), sha1 [, ...]) تفاوت دارد زیرا می‌داند که نسخه پارتیشن حافظه نهان را بررسی کند، بنابراین حتی اگر فایل به‌دلیل apply_patch() update قطع‌شده خراب شده باشد، apply_patch_check() موفق خواهد بود.
apply_patch_space(bytes)
اگر حداقل بایت فضای کار برای اعمال وصله‌های باینری دردسترس باشد، درست برمی‌گرداند.
concat(expr[, expr, ...])
هر عبارت را ارزیابی می‌کند و آن‌ها را به‌هم می‌پیوندد. عملگر + برای این تابع در حالت خاص دو آرگومان، قند نحوی است (اما شکل تابع می‌تواند هر تعداد عبارت را بپذیرد). عبارت‌ها باید رشته باشند؛ نمی‌تواند حباب‌ها را به‌هم متصل کند.
file_getprop(filename, key)
نام فایل داده‌شده را می‌خواند، آن را به‌عنوان فایل خصوصیات تفسیر می‌کند (برای نمونه، /system/build.prop)، و مقدار کلید داده‌شده را برمی‌گرداند، یا اگر کلید وجود نداشته باشد، رشته خالی را برمی‌گرداند.
format(fs_type, partition_type, location, fs_size, mount_point)
پارتیشن داده‌شده را قالب‌بندی مجدد می‌کند. انواع پارتیشن پشتیبانی‌شده:
  • fs_type="yaffs2" and partition_type="MTD". مکان باید نام پارتیشن MTD باشد؛ سیستم فایل yaffs2 خالی در آنجا ساخته می‌شود. متغیرهای مستقل باقی‌مانده استفاده‌نشده است.
  • fs_type="ext4" و partition_type="EMMC" باشد. مکان باید فایل دستگاه برای پارتیشن باشد. سیستم فایل ext4 خالی در آنجا ساخته می‌شود. اگر fs_size صفر باشد، سیستم فایل کل پارتیشن را اشغال می‌کند. اگر fs_size عددی مثبت باشد، سیستم فایل fs_size بایت اول پارتیشن را می‌گیرد. اگر fs_size عددی منفی باشد، سیستم فایل همه به‌جز |fs_size| بایت آخر پارتیشن را می‌گیرد.
  • fs_type="f2fs" و partition_type="EMMC" باشد. مکان باید فایل دستگاه برای پارتیشن باشد. fs_size باید عددی غیرمنفی باشد. اگر fs_size صفر باشد، سیستم فایل کل پارتیشن را اشغال می‌کند. اگر fs_size عددی مثبت باشد، سیستم فایل اولین بایت‌های fs_size پارتیشن را می‌گیرد.
  • ‫mount_point باید نقطه نصب آینده برای سیستم فایل باشد.
getprop(key)
مقدار دارایی سیستم کلید را برمی‌گرداند (یا رشته خالی، اگر تعریف نشده باشد). مقادیر دارایی سیستم تعریف‌شده توسط پارتیشن بازیابی لزوماً با مقادیر سیستم اصلی یکسان نیست. این تابع مقدار را در بازیابی برمی‌گرداند.
greater_than_int(a, b)
اگر و فقط اگر (iff) a (تفسیرشده به‌عنوان عدد صحیح) بزرگ‌تر از b (تفسیرشده به‌عنوان عدد صحیح) باشد، درست برمی‌گرداند.
ifelse(cond, e1[, e2])
cond را ارزیابی می‌کند، و اگر درست باشد مقدار e1 را ارزیابی و برمی‌گرداند، درغیراین‌صورت e2 را (درصورت وجود) ارزیابی و برمی‌گرداند. ساخت «if ... else ... then ... endif» فقط یک شکر نحوی برای این تابع است.
is_mounted(mount_point)
اگر و فقط اگر سیستم فایلی در mount_point نصب شده باشد، مقدار درست را برمی‌گرداند.
is_substring(needle, haystack)
اگر و فقط اگر needle زیررشته haystack باشد، درست برمی‌گرداند.
less_than_int(a, b)
اگر و فقط اگر a (به‌عنوان عدد صحیح تفسیر شده باشد) کمتر از b (به‌عنوان عدد صحیح تفسیر شده باشد) باشد، مقدار «درست» را برمی‌گرداند.
mount(fs_type, partition_type, name, mount_point)
سیستم فایل fs_type را در mount_point سوار می‌کند. partition_type باید یکی از موارد زیر باشد:
  • MTD. «نام» نام پارتیشن MTD است (برای مثال، system،‏ userdata؛ برای مشاهده فهرست کامل، /proc/mtd را در دستگاه ببینید).
  • EMMC.

«بازیابی» به‌طور پیش‌فرض هیچ سیستم فایلی را سوار نمی‌کند (به‌جز کارت SD اگر کاربر درحال نصب دستی بسته‌ای از کارت SD باشد)؛ اسکریپت شما باید هر پارتیشنی را که نیاز به اصلاح دارد سوار کند.

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 را ارسال می‌کند. وضعیت خروج برنامه را برمی‌گرداند.
set_progress(frac)
موقعیت سنجه پیشرفت را در تکه تعریف‌شده توسط جدیدترین فراخوانی show_progress() تنظیم می‌کند. frac باید در محدوده [0.0, 1.0] باشد. پیشرفت‌سنج هرگز به عقب برنمی‌گردد؛ تلاش برای انجام این کار نادیده گرفته می‌شود.
sha1_check(blob[, sha1])
متغیر مستقل blob یک blob از نوع برگردانده‌شده توسط read_file() یا فرم تک‌متغیره package_extract_file() است. بدون آرگومان‌های sha1، این تابع مقدار درهم‌سازی SHA1 لکه را (به‌صورت رشته هگز ۴۰ رقمی) برمی‌گرداند. با یک یا چند آرگومان sha1، اگر مقدار درهم‌سازی SHA1 با یکی از آرگومان‌ها برابر باشد، این تابع مقدار درهم‌سازی SHA1 را برمی‌گرداند، و اگر با هیچ‌کدام از آن‌ها برابر نباشد، رشته خالی را برمی‌گرداند.
show_progress(frac, secs)
پیشرفت‌سنج را در frac بعدی از طول آن درطول secs ثانیه جلو می‌برد (باید عدد صحیح باشد). secs می‌تواند ۰ باشد، در این صورت سنج به‌طور خودکار جلو نمی‌رود بلکه بااستفاده از تابع set_progress() که در بالا تعریف شده است جلو می‌رود.
sleep(secs)
برای secs ثانیه می‌خوابد (باید عدد صحیح باشد).
stdout(expr[, expr, ...])
هر عبارت را ارزیابی می‌کند و مقدار آن را در stdout تخلیه می‌کند. برای اشکال‌زدایی مفید است.
tune2fs(device[, arg, …])
پارامترهای قابل‌تنظیم args را در دستگاه تنظیم می‌کند.
ui_print([text, ...])
همه آرگومان‌های نوشتار را به‌هم می‌چسباند و نتیجه را در واسط کاربر چاپ می‌کند (درصورتی‌که کاربر نمایش نوشتار را روشن کرده باشد، در اینجا قابل‌مشاهده خواهد بود).
unmount(mount_point)
سیستم فایل نصب‌شده در mount_point را جدا می‌کند.
wipe_block_device(block_dev, len)
len بایت از دستگاه بلوک داده‌شده block_dev را پاک می‌کند.
wipe_cache()
باعث می‌شود که پارتیشن حافظه نهان در پایان نصب موفق پاک شود.
write_raw_image(filename_or_blob, partition)
تصویر را در filename_or_blob در پارتیشن MTD می‌نویسد. filename_or_blob می‌تواند رشته‌ای باشد که نام فایل محلی یا آرگومان با مقدار blob را که حاوی داده‌های نوشتنی است مشخص می‌کند. برای کپی کردن فایل از بسته OTA به پارتیشن، از این دستور استفاده کنید: write_raw_image(package_extract_file("zip_filename"), "partition_name");

توجه: قبل‌از Android 4.1، فقط نام فایل‌ها پذیرفته می‌شد، بنابراین برای انجام این کار، ابتدا باید داده‌ها در یک فایل محلی موقت از حالت فشرده خارج می‌شدند.