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