Dentro de Pacotes OTA

O sistema cria o binário do atualizador a partir do bootable/recovery/updater e o usa em um pacote OTA.

O pacote em si é um arquivo .zip ( ota_update.zip , incremental_ota_update.zip ) que contém o binário executável META-INF/com/google/android/update-binary .

O Updater contém várias funções internas e um interpretador para uma linguagem de script extensível ( edify ) que oferece suporte a comandos para tarefas típicas relacionadas à atualização. O atualizador procura no arquivo .zip do pacote um script no arquivo META-INF/com/google/android/updater-script .

Nota: Usar o script edify e/ou funções internas não é uma atividade comum, mas pode ser útil se você precisar depurar o arquivo de atualização.

Sintaxe do Edify

Um script edify é uma única expressão na qual todos os valores são strings. Strings vazias são false em um contexto booleano e todas as outras strings são true . Edify suporta os seguintes operadores (com os significados usuais):

(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

Qualquer cadeia de caracteres az, AZ, 0-9, _, :, /, . que não é uma palavra reservada é considerada uma string literal. (Palavras reservadas são if else então endif. ) Literais de string também podem aparecer entre aspas; é assim que se cria valores com espaços em branco e outros caracteres que não estão no conjunto acima. \n, \t, \", e \\ servem como escapes dentro de strings entre aspas, assim como \x ## .

O && e || os operadores estão em curto-circuito; o lado direito não é avaliado se o resultado lógico for determinado pelo lado esquerdo. São equivalentes:

e1 && e2
if e1 then e2 endif

O ; operador é um ponto de sequência; significa avaliar primeiro o lado esquerdo e depois o lado direito. Seu valor é o valor da expressão do lado direito. Um ponto e vírgula também pode aparecer após uma expressão, portanto, o efeito simula declarações no estilo C:

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

Funções incorporadas

A maioria das funcionalidades de atualização está contida nas funções disponíveis para execução por scripts. (Estritamente falando, estas são macros ao invés de funções no sentido Lisp, uma vez que elas não precisam avaliar todos os seus argumentos.) Salvo indicação em contrário, as funções retornam true em caso de sucesso e false em caso de erro. Se você quiser que erros abortem a execução do script, use as funções abort() e/ou assert() . O conjunto de funções disponíveis no atualizador também pode ser estendido para fornecer funcionalidades específicas do dispositivo .

abort([ msg ])
Aborta a execução do script imediatamente, com a msg opcional. Se o usuário tiver ativado a exibição de texto, msg aparecerá no log de recuperação e na tela.
assert( expr [, expr , ...])
Avalia cada expr por vez. Se algum for falso, interrompe imediatamente a execução com a mensagem "assert failed" e o texto de origem da expressão com falha.
apply_patch( src_file , tgt_file , tgt_sha1 , tgt_size , patch1_sha1 , patch1_blob , [...])
Aplica um patch binário ao src_file para produzir o tgt_file . Se o destino desejado for o mesmo que a origem, passe "-" para tgt_file . tgt_sha1 e tgt_size são o hash SHA1 final esperado e o tamanho do arquivo de destino. Os argumentos restantes devem vir em pares: um hash SHA1 (uma string hexadecimal de 40 caracteres) e um blob. O blob é o patch a ser aplicado quando o conteúdo atual do arquivo de origem tiver o SHA1 fornecido.

A correção é feita de uma maneira segura que garante que o arquivo de destino tenha o hash e o tamanho SHA1 desejados ou seja intocado - ele não será deixado em um estado intermediário irrecuperável. Se o processo for interrompido durante a aplicação de patches, o arquivo de destino pode estar em um estado intermediário; existe uma cópia na partição de cache, portanto, reiniciar a atualização pode atualizar o arquivo com êxito.

A sintaxe especial é suportada para tratar o conteúdo das partições do dispositivo de tecnologia de memória (MTD) como arquivos, permitindo a correção de partições brutas, como boot. Para ler uma partição MTD, você deve saber quantos dados deseja ler, pois a partição não possui uma noção de fim de arquivo. Você pode usar a string "MTD: partition : size_1 : sha1_1 : size_2 : sha1_2 " como um nome de arquivo para ler a partição fornecida. Você deve especificar pelo menos um par (tamanho, sha-1) ; você pode especificar mais de um se houver várias possibilidades para o que você espera ler.

apply_patch_check( filename , sha1 [, sha1 , ...])
Retorna true se o conteúdo de filename ou a cópia temporária na partição de cache (se houver) tiver uma soma de verificação SHA1 igual a um dos valores sha1 fornecidos. Os valores sha1 são especificados como 40 dígitos hexadecimais. Esta função difere de sha1_check(read_file( filename ), sha1 [, ...]) porque sabe verificar a cópia da partição de cache, então apply_patch_check() terá sucesso mesmo que o arquivo tenha sido corrompido por uma apply_patch() update interrompida.
apply_patch_space( bytes )
Retorna true se pelo menos bytes de espaço de rascunho estiverem disponíveis para aplicação de patches binários.
concat( expr [, expr , ...])
Avalia cada expressão e as concatena. O operador + é o açúcar sintático para esta função no caso especial de dois argumentos (mas a forma da função pode receber qualquer número de expressões). As expressões devem ser strings; ele não pode concatenar blobs.
file_getprop( filename , key )
Lê o nome do arquivo fornecido, interpreta-o como um arquivo de propriedades (por exemplo, /system/build.prop ) e retorna o valor da chave fornecida ou a string vazia se a chave não estiver presente.
format( fs_type , partition_type , location , fs_size , mount_point )
Reformata uma determinada partição. Tipos de partição suportados:
  • fs_type="yaffs2" e partition_type="MTD". O local deve ser o nome da partição MTD; um sistema de arquivos yaffs2 vazio é construído lá. Os argumentos restantes não são usados.
  • fs_type="ext4" e partition_type="EMMC". O local deve ser o arquivo de dispositivo para a partição. Um sistema de arquivos ext4 vazio é construído lá. Se fs_size for zero, o sistema de arquivos ocupará toda a partição. Se fs_size for um número positivo, o sistema de arquivos recebe os primeiros bytes fs_size da partição. Se fs_size for um número negativo, o sistema de arquivos aceita todos, exceto o último |fs_size| bytes da partição.
  • fs_type="f2fs" e partition_type="EMMC". O local deve ser o arquivo de dispositivo para a partição. fs_size deve ser um número não negativo. Se fs_size for zero, o sistema de arquivos ocupará toda a partição. Se fs_size for um número positivo, o sistema de arquivos recebe os primeiros bytes fs_size da partição.
  • mount_point deve ser o ponto de montagem futuro para o sistema de arquivos.
getprop( key )
Retorna o valor da chave de propriedade do sistema (ou a string vazia, se não estiver definida). Os valores das propriedades do sistema definidos pela partição de recuperação não são necessariamente os mesmos do sistema principal. Esta função retorna o valor em recuperação.
greater_than_int( a , b )
Retorna true se e somente se (iff) a (interpretado como um inteiro) for maior que b (interpretado como um inteiro).
ifelse( cond , e1 [, e2 ])
Avalia cond , e se for true avalia e retorna o valor de e1 , caso contrário avalia e retorna e2 (se presente). A construção "if ... else ... then ... endif" é apenas açúcar sintático para esta função.
is_mounted( mount_point )
Retorna true se houver um sistema de arquivos montado em mount_point .
is_substring( needle , haystack )
Retorna true se agulha é uma substring de haystack .
less_than_int( a , b )
Retorna verdadeiro se a (interpretado como um inteiro) for menor que b (interpretado como um inteiro).
mount( fs_type , partition_type , name , mount_point )
Monta um sistema de arquivos de fs_type em mount_point . partition_type deve ser um dos seguintes:
  • MTD . Nome é o nome de uma partição MTD (por exemplo, sistema, userdata; consulte /proc/mtd no dispositivo para obter uma lista completa).
  • EMMC.

A recuperação não monta nenhum sistema de arquivos por padrão (exceto o cartão SD se o usuário estiver fazendo uma instalação manual de um pacote do cartão SD); seu script deve montar quaisquer partições que precise modificar.

package_extract_dir( package_dir , dest_dir )
Extrai todos os arquivos do pacote abaixo de package_dir e os grava na árvore correspondente abaixo de dest_dir . Todos os arquivos existentes são substituídos.
package_extract_file( package_file [, dest_file ])
Extrai um único package_file do pacote de atualização e o grava em dest_file , substituindo os arquivos existentes, se necessário. Sem o argumento dest_file , retorna o conteúdo do arquivo de pacote como um blob binário.
read_file( filename )
Lê o nome do arquivo e retorna seu conteúdo como um blob binário.
run_program( path [, arg , ...])
Executa o binário em path , passando arg s. Retorna o status de saída do programa.
set_progress( frac )
Define a posição do medidor de progresso dentro do bloco definido pela chamada show_progress() mais recente. frac deve estar no intervalo [0,0, 1,0]. O medidor de progresso nunca se move para trás; tentativas de fazê-lo são ignoradas.
sha1_check( blob [, sha1 ])
O argumento blob é um blob do tipo retornado por read_file() ou a forma de um argumento de package_extract_file() . Sem argumentos sha1 , esta função retorna o hash SHA1 do blob (como uma string hexadecimal de 40 dígitos). Com um ou mais argumentos sha1 , esta função retorna o hash SHA1 se for igual a um dos argumentos, ou a string vazia se não for igual a nenhum deles.
show_progress( frac , secs )
Avança o medidor de progresso na próxima fração de seu comprimento ao longo dos segundos segundos (deve ser um número inteiro). secs pode ser 0, nesse caso o medidor não é avançado automaticamente, mas pelo uso da função set_progress() definida acima.
sleep( secs )
Suspensão por segundos segundos (deve ser um número inteiro).
stdout( expr [, expr , ...])
Avalia cada expressão e despeja seu valor em stdout. Útil para depuração.
tune2fs( device [, arg , …])
Ajusta os argumentos dos parâmetros ajustáveis ​​no dispositivo .
ui_print([ text , ...])
Concatena todos os argumentos de texto e imprime o resultado na interface do usuário (onde ficará visível se o usuário tiver ativado a exibição de texto).
unmount( mount_point )
Desmonta o sistema de arquivos montado em mount_point .
wipe_block_device( block_dev , len )
Limpa os bytes len do dispositivo de bloco especificado block_dev .
wipe_cache()
Faz com que a partição de cache seja apagada no final de uma instalação bem-sucedida.
write_raw_image( filename_or_blob , partition )
Grava a imagem em filename_or_blob na partição MTD. filename_or_blob pode ser uma string que nomeia um arquivo local ou um argumento com valor de blob contendo os dados a serem gravados. Para copiar um arquivo do pacote OTA para uma partição, use: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Nota: Antes do Android 4.1, apenas nomes de arquivos eram aceitos, então, para fazer isso, os dados primeiro precisavam ser descompactados em um arquivo local temporário.