OTA untuk perangkat non-A/B dengan partisi dinamis

Android 10 mendukung partisi dinamis, sistem partisi ruang pengguna yang dapat membuat, mengubah ukuran, dan menghancurkan partisi selama update over-the-air (OTA).

Halaman ini menjelaskan bagaimana klien OTA mengubah ukuran partisi dinamis selama proses update untuk perangkat non-A/B.

Untuk perangkat non-A/B, update OTA untuk partisi dinamis akan diterapkan menggunakan updater di dalam paket update.

Memperbarui perangkat peluncuran

Bagian ini berlaku untuk perangkat non-A/B yang diluncurkan dengan dukungan untuk partisi; perangkat ini diupgrade dari Android 10 ke rilis yang lebih tinggi.

Membuat paket update

Paket update OTA dibuat oleh skrip ota_from_target_files, yang terletak di build/make/tools/releasetools. Secara default, skrip menghasilkan paket yang mengupdate system dan partisi vendor. Jika ada pertanyaan partisi, seperti product, product_services, atau odm, pembaruan harus dibuat di khusus perangkat dari kode Anda.

Untuk menghasilkan update, dalam modul Python yang diperluas, implementasikan FullOTA_GetBlockDifferences() dan IncrementalOTA_GetBlockDifferences(). Kedua fungsi ini menampilkan daftar objek BlockDifference, yang masing-masing menjelaskan patch update yang akan diterapkan pada partisi. Partisi yang ditampilkan oleh kedua fungsi ini tidak boleh diubah secara manual atau diverifikasi di tempat lain, misalnya di *_InstallBegin() atau *_InstallEnd().

Contoh pembuatan update:

# device/yoyodyne/tardis/releasetools.py

import os
from common import BlockDifference, EmptyImage, GetUserImage

# The joined list of user image partitions of source and target builds.
# - Items should be added to the list if new dynamic partitions are added.
# - Items should not be removed from the list even if dynamic partitions are
#   deleted. When generating an incremental OTA package, this script needs to
#   know that an image is present in source build but not in target build.
USERIMAGE_PARTITIONS = [
    "product",
    "odm",
]

def GetUserImages(input_tmp, input_zip):
  return {partition: GetUserImage(partition, input_tmp, input_zip)
          for partition in USERIMAGE_PARTITIONS
          if os.path.exists(os.path.join(input_tmp,
                                         "IMAGES", partition + ".img"))}

def FullOTA_GetBlockDifferences(info):
  images = GetUserImages(info.input_tmp, info.input_zip)
  return [BlockDifference(partition, image)
          for partition, image in images.items()]

def IncrementalOTA_GetBlockDifferences(info):
  source_images = GetUserImages(info.source_tmp, info.source_zip)
  target_images = GetUserImages(info.target_tmp, info.target_zip)

  # Use EmptyImage() as a placeholder for partitions that will be deleted.
  for partition in source_images:
    target_images.setdefault(partition, EmptyImage())

  # Use source_images.get() because new partitions are not in source_images.
  return [BlockDifference(partition, target_image, source_images.get(partition))
          for partition, target_image in target_images.items()]

Alur pembaruan

Di balik layar, fungsi berikut ditambahkan ke skrip edify:

  • unmap_partition(name)
    • Batalkan pemetaan partisi jika dipetakan. Jika tidak dipetakan, jangan lakukan apa pun.
    • Tampilkan string t jika berhasil, atau string kosong jika gagal.
  • map_partition(name)
    • Petakan partisi jika belum dipetakan.
    • Menampilkan jalur absolut perangkat blok yang dipetakan jika berhasil, atau string kosong jika gagal.
  • update_dynamic_partitions(op_list)
    • Menerapkan daftar operasi yang diberikan pada metadata partisi dinamis, membatalkan pemetaan partisi jika diperlukan.
    • Menampilkan t jika berhasil, atau string kosong jika gagal.

Argumen op_list ke update_dynamic_partitions mengarah ke file dalam paket update. Setiap baris dalam file menetapkan sebuah operasi. Jika ada gagal, update_dynamic_partitions akan langsung mengalami kegagalan mengembalikan {i>string<i} kosong. Operasinya adalah:

  • resize partition-name size
    • Hapus pemetaan partisi, lalu ubah ukurannya menjadi size.
  • remove partition_name
    • Batalkan pemetaan partisi, lalu hapus.
  • add partition-name group-name
    • Menambahkan partisi baru ke grup yang ditentukan.
    • Batalkan jika grup tidak ada atau jika partisi sudah ada.
  • move partition-name group-name
    • Pindahkan partisi ke grup yang ditentukan.
    • Batalkan jika grup tidak ada atau partisi tidak ada.
  • add_group group-name maximum-size
    • Menambahkan grup dengan nama tertentu dan ukuran maksimum.
    • Batalkan jika grup sudah ada.
    • maximum_size 0 berarti tidak ada batas ukuran pada partisi dalam grup. Pengujian tambahan diperlukan untuk memastikan partisi dalam grup tidak melebihi ruang yang tersedia di perangkat.
  • resize_group group-name maximum-size
    • Ubah ukuran grup ke ukuran maksimum yang ditentukan.
    • Batalkan jika grup tidak ada.
    • maximum_size 0 berarti tidak ada batas ukuran pada partisi dalam grup. Pengujian tambahan diperlukan untuk memastikan bahwa partisi dalam grup tidak melebihi ruang yang tersedia di perangkat.
  • remove_group group-name
    • Menghapus grup.
    • Batalkan jika ada partisi dalam grup.
  • remove_all_groups
    • Hapus pemetaan semua partisi dari pemetaan perangkat.
    • Hapus semua partisi dan grup.

OTA inkremental

Update OTA inkremental menggunakan logika berikut:

  1. Kecilkan partisi/hapus partisi/pindahkan partisi dari grup (sehingga ada cukup ruang untuk memperkecil grup)
  2. Memperkecil grup (agar ada cukup ruang untuk mengembangkan grup)
  3. Mengembangkan grup (agar memiliki cukup ruang untuk bertambah/bertambah partisi)
  4. Memperbesar partisi/menambahkan partisi/memindahkan partisi ke grup baru

Secara mendetail, update-script dibuat dengan logika:

for each shrinking partition:
    block_image_update(map_partition(name), …)

update_dynamic_partitions(op_list)

for each growing / adding partition:
    block_image_update(map_partition(name), …)

File op_list untuk update_dynamic_partitions dibuat dengan ini logika:

for each deleting partition:
    remove
for each partition that changes groups:
    move to "default"
for each shrinking partition:
    resize
for each shrinking / removing group:
    resize_group / remove_group
for each growing / adding group:
    resize_group / add_group
for each adding partition:
    add
for each growing / adding partition:
    resize
for each partition that changes groups:
    move to target group

OTA lengkap

Update OTA lengkap menggunakan logika berikut:

  1. Menghapus semua grup dan partisi yang ada
  2. Tambahkan grup
  3. Menambahkan partisi

Secara mendetail, update-script dihasilkan dengan logika ini:

update_dynamic_partitions(op_list)

for each adding partition:
    block_image_update(map_partition(name), …)

File op_list untuk update_dynamic_partitions dibuat dengan ini logika:

remove_all_groups
for each adding group:
    add_group
for each adding partition:
    add
for each adding partition:
    resize