1page.title=Inside OTA Packages 2@jd:body 3 4<!-- 5 Copyright 2015 The Android Open Source Project 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18--> 19 20<div id="qv-wrapper"> 21 <div id="qv"> 22 <h2>In this document</h2> 23 <ol id="auto-toc"> 24 </ol> 25 </div> 26</div> 27 28<p>The system builds the updater binary from <code>bootable/recovery/updater 29</code> and uses it in an OTA package.</p>The package itself is a .zip file 30(<code>ota_update.zip</code>, <code>incremental_ota_update.zip</code>) that 31contains the executable binary <code>META-INF/com/google/android/update-binary 32</code>. 33 34<p>Updater contains several builtin functions and an interpreter for an 35extensible scripting language (<b>edify</b>) that supports commands for typical 36update-related tasks. Updater looks in the package .zip file for a script in the 37file <code>META-INF/com/google/android/updater-script</code>.</p> 38 39<p class="note"><strong>Note:</strong> Using the edify script and/or builtin 40functions is not a common activity, but can be helpful if you need to debug the 41update file.</p> 42 43<h2 id="edify-syntax">Edify syntax</h2> 44<p>An edify script is a single expression in which all values are strings. 45Empty strings are <i>false</i> in a Boolean context and all other strings are 46<i>true</i>. Edify supports the following operators (with the usual meanings): 47</p> 48 49<pre> 50(<i>expr</i> ) 51 <i>expr</i> <b>+</b> <i>expr</i> # string concatenation, not integer addition 52 <i>expr</i> <b>==</b> <i>expr</i> 53 <i>expr</i> <b>!=</b> <i>expr</i> 54 <i>expr</i> <b>&&</b> <i>expr</i> 55 <i>expr</i> <b>||</b> <i>expr</i> 56 ! <i>expr</i> 57 if <i>expr</i> <b>then</b> <i>expr</i> <b>endif</b> 58 if <i>expr</i> <b>then</b> <i>expr</i> <b>else</b> <i>expr</i> <b>endif</b> 59 <i>function_name</i><b>(</b><i>expr</i><b>,</b> <i>expr</i><b>,</b><i>...</i><b>)</b> 60 <i>expr</i><b>;</b> <i>expr</i> 61</pre> 62 63<p>Any string of the characters <i>a-z, A-Z, 0-9, _, :, /, .</i> that isn't a 64reserved word is considered a string literal. (Reserved words are <b>if else 65</b> then <b>endif.</b>) String literals may also appear in double-quotes; 66this is how to create values with whitespace and other characters not in the 67above set. \n, \t, \", and \\ serve as escapes within quoted strings, as does 68\x<i>##</i>.</p> 69<p>The && and || operators are short-circuiting; the right side is not 70evaluated if the logical result is determined by the left side. The 71following are equivalent:</p> 72<pre> 73<i>e1</i> <b>&&</b> <i>e2</i> 74<b>if</b> <i>e1</i> <b>then</b> <i>e2</i> <b>endif</b></pre> 75<p>The ; operator is a sequence point; it means to evaluate first the left 76side and then the right side. Its value is the value of the right-side 77expression. A semicolon can also appear after an expression, so the effect 78simulates C-style statements:</p> 79 80<pre> 81<b>prepare(); 82do_other_thing("argument"); 83finish_up();</b> 84</pre> 85 86<h2 id="builtin-functions">Built-in functions</h2> 87<p>Most update functionality is contained in the functions available for 88execution by scripts. (Strictly speaking these are <i>macros</i> rather than 89<i>functions</i> in the Lisp sense, since they need not evaluate all of their 90arguments.) Unless otherwise noted, functions return <b>true</b> on success 91and <b>false</b> on error. If you want errors to abort execution of the 92script, use the <code>abort()</code> and/or <code>assert()</code> functions. 93The set of functions available in updater can also be extended to provide 94<a href="{@docRoot}devices/tech/ota/device_code.html">device-specific 95functionality</a>. 96 97<dl> 98<dt><code>abort([<i>msg</i>])</code></dt> 99<dd>Aborts execution of the script immediately, with the optional <i>msg</i>. 100If the user has turned on text display, <i>msg</i> appears in the recovery log 101and on-screen.</dd> 102<dt><code>assert(<i>expr</i>[, <i>expr</i>, ...])</code></dt> 103<dd>Evaluates each <i>expr</i> in turn. If any is false, immediately aborts 104execution with the message "assert failed" and the source text of the failed 105expression.</dd> 106<dt><code>apply_patch(<i>src_file</i>, <i>tgt_file</i>, <i>tgt_sha1</i>, <i> 107tgt_size</i>, <i>patch1_sha1</i>, <i>patch1_blob</i>, [...])</code></dt> 108<dd>Applies a binary patch to the <i>src_file</i> to produce the <i>tgt_file 109</i>. If the desired target is the same as the source, pass "-" for <i>tgt_file 110</i>. <i>tgt_sha1</i> and <i>tgt_size</i> are the expected final SHA1 hash and 111size of the target file. The remaining arguments must come in pairs: a SHA1 112hash (a 40-character hex string) and a blob. The blob is the patch to be 113applied whe the source file's current contents have the given SHA1. 114<p>The patching is done in a safe manner that guarantees the target file 115either has the desired SHA1 hash and size, or it is untouched—it will not be 116left in an unrecoverable intermediate state. If the process is interrupted 117during patching, the target file may be in an intermediate state; a copy exists 118in the cache partition so restarting the update can successfully update the 119file.</p> 120<p>Special syntax is supported to treat the contents of Memory Technology 121Device (MTD) partitions as files, allowing patching of raw partitions such as 122boot. To read an MTD partition, you must know how much data you want to read 123since the partition does not have an end-of-file notion. You can use the 124string "MTD:<i>partition</i>:<i>size_1</i>:<i>sha1_1</i>:<i>size_2</i>:<i> 125sha1_2</i>" as a filename to read the given partition. You must specify at 126least one <i>(size, sha-1)</i> pair; you can specify more than one if there 127are multiple possibilities for what you expect to read.</p></dd> 128<dt><code>apply_patch_check(<i>filename</i>, <i>sha1</i>[, <i>sha1</i>, ...]) 129</code></dt> 130<dd>Returns true if the contents of <i>filename</i> or the temporary copy in 131the cache partition (if present) have a SHA1 checksum equal to one of the 132given <i>sha1</i> values. <i>sha1</i> values are specified as 40 hex digits. 133This function differs from <code>sha1_check(read_file(<i>filename</i>), 134<i>sha1</i> [, ...])</code> in that it knows to check the cache partition copy, 135so <code>apply_patch_check()</code> will succeed even if the file was corrupted 136by an interrupted <code>apply_patch() update</code>.</dd> 137<dt><code>apply_patch_space(<i>bytes</i>)</code></dt> 138<dd>Returns true if at least <i>bytes</i> of scratch space is available for 139applying binary patches.</dd> 140<dt><code>concat(<i>expr</i>[, <i>expr</i>, ...])</code></dt> 141<dd>Evaluates each expression and concatenates them. The + operator is 142syntactic sugar for this function in the special case of two arguments (but 143the function form can take any number of expressions). The expressions must be 144strings; it can't concatenate blobs.</dd> 145<dt><code>delete([<i>filename</i>, ...])</code></dt> 146<dd>Deletes all the <i>filename</i>s listed. Returns the number of files 147successfully deleted.</dd> 148<dt><code>delete_recursive([<i>dirname</i>, ...])</code></dt> 149<dd>Recursively deletes <i>dirname</i>s and all their contents. Returns the 150number of directories successfully deleted.</dd> 151<dt><code>file_getprop(<i>filename</i>, <i>key</i>)</code></dt> 152<dd>Reads the given <i>filename</i>, interprets it as a properties file (e.g. 153<code>/system/build.prop</code>), and returns the value of the given <i>key</i> 154, or the empty string if <i>key</i> is not present.</dd> 155<dt><code>format(<i>fs_type</i>, <i>partition_type</i>, <i>location</i>, <i> 156fs_size</i>, <i>mount_point</i>)</code></dt> 157<dd>Reformats a given partition. Supported partition types: 158<ul> 159<li>fs_type="yaffs2" and partition_type="MTD". Location must be the name of 160the MTD partition; an empty yaffs2 filesystem is constructed there. Remaining 161arguments are unused.</li> 162<li>fs_type="ext4" and partition_type="EMMC". Location must be the device file 163for the partition. An empty ext4 filesystem is constructed there. If 164<i>fs_size</i> is zero, the filesystem takes up the entire partition. If 165<i>fs_size</i> is a positive number, the filesystem takes the first 166<i>fs_size</i> bytes of the partition. If <i>fs_size</i> is a 167negative number, the filesystem takes all except the last <i>|fs_size|</i> 168bytes of the partition.</li> 169<li>fs_type="f2fs" and partition_type="EMMC". Location must be the device file 170for the partition. <i>fs_size</i> must be a non-negative number. If 171<i>fs_size</i> is zero, the filesystem takes up the entire partition. If 172<i>fs_size</i> is a positive number, the filesystem takes the first 173<i>fs_size</i> bytes of the partition.</li> 174<li>mount_point should be the future mount point for the filesystem.</li></ul> 175</dd> 176<dt><code>getprop(<i>key</i>)</code></dt> 177<dd>Returns the value of system property <i>key</i> (or the empty string, if 178it's not defined). The system property values defined by the recovery 179partition are not necessarily the same as those of the main system. This 180function returns the value in recovery.</dd> 181<dt><code>greater_than_int(<i>a</i>, <i>b</i>)</code></dt> 182<dd>Returns true if and only if (iff) <i>a</i> (interpreted as an integer) is 183greater than <i>b</i> (interpreted as an integer).</dd> 184<dt><code>ifelse(<i>cond</i>, <i>e1</i>[, <i>e2</i>])</code></dt> 185<dd>Evaluates <i>cond</i>, and if it is true evaluates and returns the value 186of <i>e1</i>, otherwise it evaluates and returns <i>e2</i> (if present). The 187"if ... else ... then ... endif" construct is just syntactic sugar for this 188function.</dd> 189<dt><code>is_mounted(<i>mount_point</i>)</code></dt> 190<dd>Returns true iff there is a filesystem mounted at <i>mount_point</i>.</dd> 191<dt><code>is_substring(<i>needle</i>, <i>haystack</i>)</b></code></dt> 192<dd>Returns true iff <i>needle</i> is a substring of <i>haystack</i>.</dd> 193<dt><code>less_than_int(<i>a</i>, <i>b</i>)</code></dt> 194<dd>Returns true iff <i>a</i> (interpreted as an integer) is less than <i>b</i> 195(interpreted as an integer).</dd> 196<dt><code>mount(<i>fs_type</i>, <i>partition_type</i>, <i>name</i>, 197<i>mount_point</i>)</code></dt> 198<dd>Mounts a filesystem of <i>fs_type</i> at <i>mount_point</i>. 199<i>partition_type</i> must be one of: 200<ul> 201<li><b>MTD</b>. Name is the name of an MTD partition (e.g., system, userdata; 202see <code>/proc/mtd</code> on the device for a complete list).</li> 203<li><b>EMMC.</b></li> 204</ul> 205<p>Recovery does not mount any filesystems by default (except the SD card if 206the user is doing a manual install of a package from the SD card); your script 207must mount any partitions it needs to modify.</p></dd> 208<dt><code>package_extract_dir(<i>package_dir</i>, <i>dest_dir</i>)</code></dt> 209<dd>Extracts all files from the package underneath <i>package_dir</i> and 210writes them to the corresponding tree beneath <i>dest_dir</i>. Any existing 211files are overwritten.</dd> 212<dt><code>package_extract_file(<i>package_file</i>[, <i>dest_file</i>])</code> 213</dt> 214<dd>Extracts a single <i>package_file</i> from the update package and writes 215it to <i>dest_file</i>, overwriting existing files if necessary. Without the 216<i>dest_file</i> argument, returns the contents of the package file as a 217binary blob.</dd> 218<dt><code>read_file(<i>filename</i>)</code></dt> 219<dd>Reads <i>filename</i> and returns its contents as a binary blob.</dd> 220<dt><code>rename(<i>src_filename</i>, <i>tgt_filename</i>)</code></dt> 221<dd>Renames <i>src_filename</i> to <i>tgt_filename</i>. It automatically creates 222the necessary directories for the <i>tgt_filename</i>. Example: <code> 223rename("system/app/Hangouts/Hangouts.apk", 224"system/priv-app/Hangouts/Hangouts.apk")</code>.</dd> 225<dt><code>run_program(<i>path</i>[, <i>arg</i>, ...])</code></dt> 226<dd>Executes the binary at <i>path</i>, passing <i>arg</i>s. Returns the 227program's exit status.</dd> 228<dt><code>set_metadata(<i>filename</i>, <i>key1</i>, <i>value1</i>[, <i>key2 229</i>, <i>value2</i>, ...])</code></dt> 230<dd>Sets the keys of the given <i>filename</i> to <i>values</i>. For example: 231<code>set_metadata("/system/bin/netcfg", "uid", 0, "gid", 3003, "mode", 02750, 232"selabel", "u:object_r:system_file:s0", "capabilities", 0x0)</code>.</dd> 233<dt><code>set_metadata_recursive(<i>dirname</i>, <i>key1</i>, <i>value1</i>[, 234<i>key2</i>, <i>value2</i>, ...])</code></dt> 235<dd>Recursively sets the keys of the given <i>dirname</i> and all its children 236to <i>values</i>. For example: <code>set_metadata_recursive("/system", "uid", 2370, "gid", 0, "fmode", 0644, "dmode", 0755, "selabel", 238"u:object_r:system_file:s0", "capabilities", 0x0)</code>.</dd> 239<dt><code>set_progress(<i>frac</i>)</code></dt> 240<dd>Sets the position of the progress meter within the chunk defined by the 241most recent <code>show_progress()</code> call. <i>frac</i> must be in the 242range [0.0, 1.0]. The progress meter never moves backwards; attempts to make 243it do so are ignored.</dd> 244<dt><code>sha1_check(<i>blob</i>[, <i>sha1</i>])</code></dt> 245<dd>The <i>blob</i> argument is a blob of the type returned by <code> 246read_file()</code> or the one-argument form of <code>package_extract_file() 247</code>. With no <i>sha1</i> arguments, this function returns the SHA1 hash of 248the blob (as a 40-digit hex string). With one or more <i>sha1</i> arguments, 249this function returns the SHA1 hash if it equals one of the arguments, or the 250empty string if it does not equal any of them.</dd> 251<dt><code>show_progress(<i>frac</i>, <i>secs</i>)</code></dt> 252<dd>Advances the progress meter over the next <i>frac</i> of its length over 253the <i>secs</i> seconds (must be an integer). <i>secs</i> may be 0, in which 254case the meter is not advanced automatically but by use of the <code> 255set_progress()</code> function defined above.</dd> 256<dt><code>sleep(<i>secs</i>)</code></dt> 257<dd>Sleeps for <i>secs</i> seconds (must be an integer).</dd> 258<dt><code>stdout(<i>expr</i>[, <i>expr</i>, ...])</code></dt> 259<dd>Evaluates each expression and dumps its value to stdout. Useful for 260debugging.</dd> 261<dt><code>symlink(<i>target</i>[, <i>source</i>, ...])</code></dt> 262<dd>Creates all <i>source</i>s as symlinks to <i>target</i>.</dd> 263<dt><code>tune2fs(<i>device</i>[, <i>arg</i>, …])</code></dt> 264<dd>Adjusts tunable parameters <i>args</i> on <i>device</i>.</dd> 265<dt><code>ui_print([<i>text</i>, ...])</code></dt> 266<dd>Concatenates all <i>text</i> arguments and prints the result to the UI 267(where it will be visible if the user has turned on the text display).</dd> 268<dt><code>unmount(<i>mount_point</i>)</code></dt> 269<dd>Unmounts the filesystem mounted at <i>mount_point</i>.</dd> 270<dt><code>wipe_block_device(<i>block_dev</i>, <i>len</i>)</code></dt> 271<dd>Wipes the <i>len</i> bytes of the given block device <i>block_dev</i>.</dd> 272<dt><code>wipe_cache()</code></dt> 273<dd>Causes the cache partition to be wiped at the end of a successful 274installation.</dd> 275<dt><code>write_raw_image(<i>filename_or_blob</i>, <i>partition</i>)</code> 276</dt> 277<dd>Writes the image in <i>filename_or_blob</i> to the MTD <i>partition</i>. 278<i>filename_or_blob</i> can be a string naming a local file or a blob-valued 279argument containing the data to write. To copy a file from the OTA package to 280a partition, use: 281<code>write_raw_image(package_extract_file("zip_filename"), "partition_name"); 282</code> 283</dd> 284</dl> 285 286<p class="note"><strong>Note:</strong> Prior to Android 4.1, only filenames 287were accepted, so to accomplish this the data first had to be unzipped into a 288temporary local file.</p>