OTA パッケージのビルド

build/make/tools/releasetools に用意されている ota_from_target_files ツールを使用して、A/B システム アップデートまたは非 A/B システム アップデートを使用するデバイス向けのフル OTA パッケージと増分 OTA パッケージをビルドできます。このツールは、Android ビルドシステムによって生成された target-files.zip ファイルを入力として使用します。

Android 11 以降を搭載するデバイスでは、SKU の異なる複数のデバイス向けに 1 つの OTA パッケージをビルドできます。そのためには、動的フィンガープリントを使用するようにターゲット デバイスを設定し、事前条件と事後条件のエントリがデバイス名とフィンガープリントを含むように OTA メタデータを更新する必要があります。

非 A/B デバイス向けのファイルベースの OTA パッケージは、Android 8.0 でサポートが終了しました。代わりにブロックベースの OTA パッケージを使用する必要があります。Android 7.x 以前を搭載するデバイス向けにブロックベースの OTA パッケージを生成するには、ota_from_target_files のパラメータに --block オプションを渡します。

フル アップデートのビルド

フル アップデートとは、デバイスの最終的な状態(システム、ブート、リカバリ パーティション)をすべて収めた OTA パッケージのことです。デバイスによるパッケージの受け取りと適用が可能でありさえすれば、デバイスの現在の状態に関係なく、そのパッケージでビルドをインストールできます。以下は、リリースツールを使用して tardis デバイス向けの target-files.zip アーカイブをビルドするコマンドの例です。

. build/envsetup.sh && lunch tardis-eng
mkdir dist_output
make dist DIST_DIR=dist_output

make dist は($OUT で)フル OTA パッケージをビルドします。生成された .zip ファイルには、tardis デバイス向けの OTA パッケージの作成に必要なものがすべて含まれています。また、ota_from_target_files を Python バイナリとしてビルドし、それを呼び出してフルパッケージまたは増分パッケージをビルドすることもできます。

ota_from_target_files dist_output/tardis-target_files.zip ota_update.zip

ota_from_target_files パスが $PATH に設定され、生成された Python バイナリが out/ ディレクトリに配置されます。

これで ota_update.zip をテストデバイスに送信する準備ができました。すべてがテストキーで署名されています。ユーザー デバイス向けには、リリース用ビルドへの署名に説明されているとおり、独自の秘密鍵を生成して使用します。

増分アップデートのビルド

増分アップデートとは、デバイス上の既存のデータに対するバイナリパッチを収めた OTA パッケージのことです。増分アップデートのパッケージは通常、変更されていないファイルを収める必要がない分、サイズを小さくできます。さらに、変更されたファイルも変更前のバージョンとほぼ同じであることが多く、パッケージに含めるのは 2 つのファイルの違いをエンコードしたものだけで済みます。

増分アップデート パッケージをインストールできるのは、その作成に使用したソースビルドがインストールされているデバイスに対してのみです。増分アップデートのビルドには、更新前のビルドの target_files.zip ファイルと、新しいビルドの target_files.zip ファイルが必要です。以下は、リリースツールを使用して tardis デバイス向けの増分アップデートをビルドするコマンドの例です。

ota_from_target_files -i PREVIOUS-tardis-target_files.zip dist_output/tardis-target_files.zip incremental_ota_update.zip

このビルドは更新前のビルドとほぼ同じであるため、増分アップデートのパッケージ(incremental_ota_update.zip)は約 1 MB と、同じバージョンのフル アップデート(60 MB)よりもかなり小さくなります。

増分パッケージは、その開始ポイントに使用したものとまったく同じビルドを実行しているデバイスにのみ配信します。書き込むイメージは、PRODUCT_OUT ディレクトリに含まれるもの(make でビルドし、fastboot flashall で書き込む)ではなく、PREVIOUS-tardis-target_files.zip または PREVIOUS-tardis-img.zip に含まれるもの(どちらも make dist でビルドし、fastboot update で書き込む)にする必要があります。増分パッケージを上記以外のビルドを実行しているデバイスにインストールしようとすると、インストール エラーが発生します。インストールが失敗した場合は、デバイスの動作状態は変わりません(古いシステムを実行し続けます)。更新対象のファイルはすべて、パッケージによって事前に更新前の状態が確認されるため、デバイスが中途半端に更新された状態になることはありません。

最適なユーザー エクスペリエンスを実現するには、3~4 回の増分アップデートごとにフル アップデートを提供するようにします。これにより、ユーザーは何度も増分アップデートを繰り返すことなく、最新のリリースを利用できます。

複数の SKU 向けの OTA パッケージのビルド

Android 11 以降では、1 つの OTA パッケージを SKU の異なる複数のデバイスに適用できます。そのためには、動的フィンガープリントを使用するようにターゲット デバイスを設定し、事前条件と事後条件のエントリがデバイス名とフィンガープリントを含むように、OTA ツールを使用して OTA メタデータを更新する必要があります。

SKU について

SKU の形式は、ビルド パラメータ値の組み合わせのバリエーションであり、通常は現在の build_fingerprint パラメータの宣言されていないサブセットです。OEM は、CDD で認められているビルド パラメータの組み合わせであれば、どのようなものでも SKU に使用できます。また、複数の SKU に対して 1 つのイメージを使用できます。たとえば、次の SKU には複数のバリエーションがあります。

SKU = <product><device><modifierA><modifierB><modifierC>
  • modifierA はデバイスレベル(Pro、Premium、Plus など)です。
  • modifierB はハードウェアのバリエーション(radio など)です。
  • modifierC は地域で、広範(NA、EMEA、CHN など)にすることも、国や言語(JPN、ENG、CHN など)を指定することもできます。

多くの OEM は複数の SKU に対して 1 つのイメージを使用し、デバイスが起動した後のランタイムに、最終的な製品名とデバイス フィンガープリントを取得します。この方法によって、違いはわずかでありながら製品名が異なるデバイスの間で同じイメージを共有できるようになり(tardistardispro など)、プラットフォームの開発プロセスがシンプルになります。

動的なフィンガープリントの使用

フィンガープリントとは、ro.product.brandro.product.namero.product.device などのビルド パラメータの連結を定義したものです。デバイスのフィンガープリントは、システム パーティションのフィンガープリントから取得され、デバイスで実行されるイメージ(およびバイト)の一意の識別子として使用されます。動的フィンガープリントを作成するには、デバイスの build.prop ファイルの動的ロジックを使用してデバイス起動時にブートローダー変数の値を取得し、そのデータからデバイスの動的フィンガープリントを作成します。

たとえば、tardis デバイスと tardispro デバイスで動的フィンガープリントを使用するには、以下のように各ファイルを更新します。

  • odm/etc/build_std.prop ファイルに次の行を含めます。

    ro.odm.product.device=tardis
    
  • odm/etc/build_pro.prop ファイルに次の行を含めます。

    ro.odm.product.device=tardispro
    
  • odm/etc/build.prop ファイルに次の 2 行を含めます。

    ro.odm.product.device=tardis
    import /odm/etc/build_${ro.boot.product.hardware.sku}.prop
    

上記の各行により、デバイス名、フィンガープリント、ro.build.fingerprint 値がブートローダー プロパティ ro.boot.product.hardware.sku の値(読み取り専用)に基づいて動的に設定されます。

OTA パッケージのメタデータの更新

OTA パッケージには、OTA パッケージの事前条件や事後条件など、パッケージについて記述したメタデータ ファイル(META-INF/com/android/metadata)が含まれています。以下のコードは、tardis デバイスをターゲットとする OTA パッケージのメタデータ ファイルの例です。

post-build=google/tardis/tardis:11/RP1A.200521.001/6516341:userdebug/dev-keys
post-build-incremental=6516341
post-sdk-level=30
post-security-patch-level=2020-07-05
post-timestamp=1590026334
pre-build=google/tardis/tardis:11/RP1A.200519.002.A1/6515794:userdebug/dev-keys
pre-build-incremental=6515794
pre-device=tardis

pre-devicepre-build-incrementalpre-build の値は、OTA パッケージがインストールされる前のデバイスの状態に対する要件を定義しています。post-build-incrementalpost-build の値は、OTA パッケージがインストールされた後に想定されるデバイスの状態を定義しています。pre-post- の各値は、以下の対応するビルド プロパティから取得されます。

  • pre-device 値は ro.product.device ビルド プロパティから取得されます。
  • pre-build-incrementalpost-build-incremental の値は、ro.build.version.incremental ビルド プロパティから取得されます。
  • pre-buildpost-build の値は、ro.build.fingerprint ビルド プロパティから取得されます。

Android 11 以降を搭載するデバイスでは、OTA ツールの --boot_variable_file フラグを使用して、デバイスの動的フィンガープリントの作成に使用するランタイム変数値を含むファイルのパスを指定できます。このデータはその後、pre- 条件と post- 条件にデバイス名とフィンガープリントを含めるよう OTA メタデータを更新するために使用されます(区切り文字にはパイプ文字 | を使用します)。--boot_variable_file フラグの構文と説明は次のとおりです。

  • 構文: --boot_variable_file <path>
  • 説明: 有効な ro.boot.* プロパティ値を含むファイルのパスを指定します。import ステートメントによって一部の ro.product.* プロパティがオーバーライドされた場合に、有効なランタイム フィンガープリントを計算するために使用されます。このファイルには、prop_name=value1,value2 の形式で 1 行に 1 プロパティを指定します。

たとえば、プロパティが ro.boot.product.hardware.sku=std,pro の場合、tardis デバイスと tardispro デバイスの OTA メタデータは次のようになります。

post-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-device=tardis|tardispro

Android 10 を搭載するデバイスでこの機能をサポートするには、リファレンス実装をご覧ください。このチェンジリストにより、build.prop ファイルの import ステートメントが条件付きで解析されます。これにより、プロパティのオーバーライドが認識され、最終的な OTA メタデータへの反映が可能になります。