互換性マトリックスとマニフェストの 2 つのペアが整合性を持ち、フレームワークとベンダー実装が連携して動作できるかを検証する必要があります。この検証は、フレームワーク互換性マトリックスとデバイス マニフェストが一致し、フレームワーク マニフェストとデバイス互換性マトリックスが一致していれば成功します。
この検証は、ビルド時、OTA アップデート パッケージ生成時、起動時、VTS 互換性テストで行われます。
以下のセクションでは、さまざまなコンポーネントで使用されるマッチング ルールについて詳しく説明します。
フレームワーク互換性マトリックスのバージョンの一致
デバイス マニフェストとフレームワーク互換性マトリックスが一致するためには、manifest.target-level
で指定された Shipping FCM バージョンと、compatibility-matrix.level
で指定された FCM バージョンが完全に同じである必要があります。同じでない場合は一致しません。
フレームワーク互換性マトリックスが libvintf
を使用して要求された場合、このマッチングは常に成功します。これは、libvintf
がデバイス マニフェストを開いて Shipping FCM バージョンを取得し、その Shipping FCM バージョンのフレームワーク互換性マトリックスを返すためです(さらに、上位の FCM バージョンの互換性マトリックスからオプションの HAL もいくつか返します)。
HAL の一致
HAL のマッチング ルールは、対応する互換性マトリックスのオーナーによってサポートされていると想定されるマニフェスト ファイルの hal
要素のバージョンを識別します。
HIDL HAL とネイティブ HAL
HIDL HAL とネイティブ HAL のマッチング ルールは次のとおりです。
- 複数の
<hal>
要素は単一の AND 関係で評価されます。 <hal>
要素には、必須ではないことを示すために<hal optional="true">
が含まれる場合があります。- 同じ
<hal>
内の複数の<version>
要素は OR 関係を持ちます。2 つ以上のバージョンが指定されている場合は、いずれか 1 つのみを実装する必要があります(下記の DRM の例をご覧ください)。 - 同じ
<hal>
内の複数の<instance>
要素と<regex-instance>
要素は、<hal>
が必須である場合、単一の AND 関係で評価されます(下記の <ahref="#drm">DRM の例</ahref="#drm">をご覧ください)。
例: モジュールの HAL マッチングが成功する場合
バージョン 2.5 の HAL の場合、マッチング ルールは次のようになります。
マトリックス | 一致するマニフェスト |
---|---|
2.5 |
2.5~2.∞。互換性マトリックスでは、2.5 は 2.5-5 の省略形です。 |
2.5-7 |
2.5~2.∞。次のことを示します。
2.5-7 を指定しているフレームワークとの互換性が維持されます。 |
例: DRM モジュールの HAL マッチングが成功する場合
フレームワーク互換性マトリックスに、次のような DRM HAL のバージョン情報が記述されているとします。
<hal> <name>android.hardware.drm <version>1.0</version> <version>3.1-2</version> <interface> <name>IDrmFactory</name> <instance>default</instance> <instance>specific</instance> </interface> </hal> <hal> <name>android.hardware.drm <version>2.0</version> <interface> <name>ICryptoFactory</name> <instance>default</instance> <regex-instance>[a-z]+/[0-9]+</regex-instance> </interface> </hal>
この場合、ベンダーは次のインスタンスのいずれか 1 つを実装する必要があります。
android.hardware.drm@1.x::IDrmFactory/default // where x >= 0 android.hardware.drm@1.x::IDrmFactory/specific // where x >= 0または
android.hardware.drm@3.y::IDrmFactory/default // where y >= 1 android.hardware.drm@3.y::IDrmFactory/specific // where y >= 1
さらに、次のインスタンスをすべて実装する必要もあります。
android.hardware.drm@2.z::ICryptoFactory/default // where z >= 0 android.hardware.drm@2.z::ICryptoFactory/${INSTANCE} // where z >= 0 and ${INSTANCE} matches [a-z]+/[0-9]+ // e.g. legacy/0
AIDL HAL
Android 11 より後の Android バージョン(Android 11 を除く)はすべて、VINTF の AIDL HAL 向けのバージョンをサポートしています。AIDL HAL のマッチング ルールは HIDL HAL やネイティブ HAL のルールと似ていますが、メジャー バージョンがなく、HAL インスタンスごとにバージョンが 1 つだけある(バージョンが指定されていない場合は 1
)という点が異なります。
- 複数の
<hal>
要素は単一の AND 関係で評価されます。 <hal>
要素には、必須ではないことを示すために<hal optional="true">
が含まれる場合があります。- 同じ
<hal>
内の複数の<instance>
要素と<regex-instance>
要素は、<hal>
が必須である場合、単一の AND 関係で評価されます(下記の<ahref="#vibrator">バイブレーターの例</ahref="#vibrator">をご覧ください)。
例: モジュールの HAL マッチングが成功する場合
バージョン 5 の HAL の場合、マッチング ルールは次のようになります。
マトリックス | 一致するマニフェスト |
---|---|
5 |
5~∞。互換性マトリックスでは、5 は 5-5 の省略形です。 |
5-7 |
5~∞。次のことを示します。
5-7 を指定しているフレームワークとの互換性が維持されます。 |
例: 複数のモジュールの HAL マッチングが成功する場合
フレームワーク互換性マトリックスに、バイブレーター HAL とカメラ HAL の次のようなバージョン情報が記載されているとします。
<hal> <name>android.hardware.vibrator <version>1-2</version> <interface> <name>IVibrator</name> <instance>default</instance> <instance>specific</instance> </interface> </hal> <hal> <name>android.hardware.camera <version>5</version> <interface> <name>ICamera</name> <instance>default</instance> <regex-instance>[a-z]+/[0-9]+</regex-instance> </interface> </hal>
この場合、ベンダーは次のインスタンスをすべて実装する必要があります。
android.hardware.vibrator.IVibrator/default // version >= 1 android.hardware.vibrator.IVibrator/specific // version >= 1 android.hardware.camera.ICamera/default // version >= 5 android.hardware.camera.ICamera/${INSTANCE} // with version >= 5, where ${INSTANCE} matches [a-z]+/[0-9]+ // e.g. legacy/0
カーネルの一致
フレームワーク互換性マトリックスの <kernel>
セクションには、デバイス上の Linux カーネルのフレームワークの要件が記述されています。この情報は、デバイスの VINTF オブジェクトによって報告されたカーネルの情報とマッチングされます。
カーネル ブランチとのマッチング
各カーネル ブランチ サフィックス(5.4-r
など)は、一意のカーネル FCM バージョン(たとえば 5)にマッピングされます。このマッピングは、リリース文字(R など)と FCM バージョン(5 など)のマッピングと同じです。
次のいずれかに該当する場合、VTS テストにより、デバイスはデバイス マニフェスト /vendor/etc/vintf/manifest.xml
でカーネルの FCM バージョンを明示的に指定することになります。
-
カーネル FCM バージョンはターゲット FCM バージョンとは異なります。たとえば、上記のデバイスのターゲット FCM バージョンは 4 で、そのカーネル FCM バージョンは 5 です(カーネル ブランチ サフィックスは
r
です)。 - カーネル FCM バージョンは 5 以上です(カーネル ブランチ サフィックスは
r
です)。
VTS テストでは、カーネル FCM バージョンが指定されている場合、カーネル FCM バージョンはデバイス マニフェストのターゲット FCM バージョン以上であることが確認されます。
例: カーネル ブランチを決定する場合
デバイスにターゲット FCM バージョン 4(Android 10 でリリース済み)があり、4.19-r
ブランチからカーネルを実行している場合、デバイス マニフェストは次のように指定する必要があります。
<manifest version="2.0" type="device" target-level="4"> <kernel target-level="5" /> </manifest>
VINTF オブジェクトは、FCM バージョン 5 で指定されている 4.19-r
カーネル ブランチの要件に対してカーネル互換性を確認します。これらの要件は、Android ソースツリーの kernel/configs/r/android-4.19
からビルドされています。
例: GKI のカーネル ブランチを決定する場合
デバイスが汎用カーネル イメージ(GKI)を使用しており、/proc/version
のカーネル リリース文字列が次のとおりである場合、
5.4.42-android12-0-00544-ged21d463f856
VINTF オブジェクトはカーネル リリースから Android リリースを取得し、それを使用してカーネル FCM バージョンを特定します。この例の android12
は、カーネル FCM バージョン 6(Android 12 でリリース)を意味します。
カーネル リリース文字列の解析方法については、GKI のバージョニングをご覧ください。
カーネル バージョンとのマッチング
マトリックスには複数の <kernel>
セクションがあり、それぞれに異なる version
属性が次の形式で指定されています。
${ver}.${major_rev}.${kernel_minor_rev}
VINTF オブジェクトで考慮されるのは、FCM バージョンに一致し、デバイス カーネルと同じ ${ver}
と ${major_rev}
を持つ <kernel>
セクションだけです(すなわち version="${ver}.${major_rev}.${matrix_minor_rev}")
)。他のセクションは無視されます。さらに、カーネルのマイナー リビジョンは、互換性マトリックスと同じ値である必要があります(${kernel_minor_rev} >=
${matrix_minor_rev}
)。これらの要件を満たす <kernel>
セクションがない場合は、一致しません。
例: 一致要件を選択する場合
/system/etc/vintf
の FCM で次の要件を宣言すると仮定します(ヘッダータグとフッタータグは省略されます)。
<!-- compatibility_matrix.3.xml --> <kernel version="4.4.107" level="3"/> <!-- See kernel/configs/p/android-4.4/ for 4.4-p requirements --> <kernel version="4.9.84" level="3"/> <!-- See kernel/configs/p/android-4.9/ for 4.9-p requirements --> <kernel version="4.14.42" level="3"/> <!-- See kernel/configs/p/android-4.14/ for 4.14-p requirements --> <!-- compatibility_matrix.4.xml --> <kernel version="4.9.165" level="4"/> <!-- See kernel/configs/q/android-4.9/ for 4.9-q requirements --> <kernel version="4.14.105" level="4"/> <!-- See kernel/configs/q/android-4.14/ for 4.14-q requirements --> <kernel version="4.19.42" level="4"/> <!-- See kernel/configs/q/android-4.19/ for 4.19-q requirements --> <!-- compatibility_matrix.5.xml --> <kernel version="4.14.180" level="5"/> <!-- See kernel/configs/r/android-4.14/ for 4.14-r requirements --> <kernel version="4.19.123" level="5"/> <!-- See kernel/configs/r/android-4.19/ for 4.19-r requirements --> <kernel version="5.4.41" level="5"/> <!-- See kernel/configs/r/android-5.4/ for 5.4-r requirements -->
ターゲット FCM バージョン、カーネル FCM バージョン、カーネル バージョンは、一緒に FCM から次のカーネル要件を選択します。
ターゲット FCM バージョン | カーネル FCM バージョン | カーネル バージョン | マッチング結果 |
---|---|---|---|
3(P) | 指定なし | 4.4.106 | 不一致(マイナー バージョンが一致しません) |
3(P) | 指定なし | 4.4.107 | 4.4-p |
3(P) | 指定なし | 4.19.42 | 4.19-q (下記の注をご覧ください) |
3(P) | 指定なし | 5.4.41 | 5.4-r (下記の注をご覧ください) |
3(P) | 3(P) | 4.4.107 | 4.4-p |
3(P) | 3(P) | 4.19.42 | 不一致(4.19-p カーネル ブランチがありません) |
3(P) | 4(Q) | 4.19.42 | 4.19-q |
4(Q) | 指定なし | 4.4.107 | 不一致(4.4-q カーネル ブランチがありません) |
4(Q) | 指定なし | 4.9.165 | 4.9-q |
4(Q) | 指定なし | 5.4.41 | 5.4-r (下記の注をご覧ください) |
4(Q) | 4(Q) | 4.9.165 | 4.9-q |
4(Q) | 4(Q) | 5.4.41 | 不一致(5.4-q カーネル ブランチがありません) |
4(Q) | 5(R) | 4.14.105 | 4.14-r |
4(Q) | 5(R) | 5.4.41 | 5.4-r |
5(R) | 指定なし | すべて | VTS が失敗しました(ターゲット FCM バージョン 5 にカーネル FCM バージョンを指定する必要があります) |
5(R) | 4(Q) | すべて | VTS が失敗しました(カーネル FCM バージョン < ターゲット FCM バージョン) |
5(R) | 5(R) | 4.14.180 | 4.14-r |
カーネル設定とのマッチング
<kernel>
セクションが一致する場合は、処理が続行されて config
要素が /proc/config.gz
とマッチングされます。互換性マトリックスの config 要素ごとに /proc/config.gz
がルックアップされ、その config が存在するかどうかが確認されます。一致する <kernel>
セクションの互換性マトリックスで config 項目が n
に設定されている場合、config 項目は /proc/config.gz
に存在しません。最後に、互換性マトリックスに存在しない config 項目は、/proc/config.gz
に存在する場合も、存在しない場合もあります。
例: カーネル設定とマッチングする場合
<value type="string">bar</value>
は"bar"
と一致します。互換性マトリックスでは引用符が省略されていますが、/proc/config.gz
では引用符があります。<value type="int">4096</value>
は4096
、0x1000
、0X1000
のいずれかと一致します。<value type="int">0x1000</value>
は4096
、0x1000
、0X1000
のいずれかと一致します。<value type="int">0X1000</value>
は4096
、0x1000
、0X1000
のいずれかと一致します。<value type="tristate">y</value>
はy
と一致します。<value type="tristate">m</value>
はm
と一致します。<value type="tristate">n</value>
は、config 項目が/proc/config.gz
に存在しないことを意味します。<value type="range">1-0x3</value>
は、1
、2
、3
、または 16 進数の同等の値と一致します。
例: カーネルのマッチングが成功する場合
FCM バージョン 1 のフレームワーク互換性マトリックスに次のカーネル情報が記述されているとします。
<kernel version="4.14.42"> <config> <key>CONFIG_TRI</key> <value type="tristate">y</value> </config> <config> <key>CONFIG_NOEXIST</key> <value type="tristate">n</value> </config> <config> <key>CONFIG_DEC</key> <value type="int">4096</value> </config> <config> <key>CONFIG_HEX</key> <value type="int">0XDEAD</value> </config> <config> <key>CONFIG_STR</key> <value type="string">str</value> </config> <config> <key>CONFIG_EMPTY</key> <value type="string"></value> </config> </kernel>
カーネル ブランチの一致が最初に確認されます。カーネル ブランチは manifest.kernel.target-level
のデバイス マニフェストで指定されています。指定しない場合、デフォルトでは manifest.level
になります。デバイス マニフェスト内のカーネル ブランチが次の値である場合:
- 1: 次のステップに進んで、カーネル バージョンを確認します。
- 2: マトリックスと一致しません。VINTF オブジェクトは、FCM バージョン 2 のマトリックスからカーネル要件を読み取ります。
その後、カーネル バージョンが一致します。デバイスは uname()
で次の情報を報告します。
- 4.9.84(
<kernel version="4.9.x">
(x <= 84
)の別のカーネル セクションがない限り、マトリックスに一致しません) - 4.14.41(
version
より小さいため、マトリックスに一致しません) - 4.14.42(マトリックスと一致します)
- 4.14.43(マトリックスと一致します)
- 4.1.22(
<kernel version="4.1.x">
(x <= 22
)の別のカーネル セクションがない限り、マトリックスに一致しません)
適切な <kernel>
セクションが選択されると、n
以外の値を持つ各 <config>
項目については、対応するエントリが /proc/config.gz
に存在することが期待されます。n
の値を持つ各 <config>
項目については、対応するエントリが /proc/config.gz
に存在しないことが期待されます。<value>
の内容については、等号(引用符を含む)の後から、次の行の文字または #
までのテキストと完全に一致することが予想されます(先頭と末尾の空白文字は除く)。
次のカーネル構成は、マッチングが成功する例です。
# comments don't matter CONFIG_TRI=y # CONFIG_NOEXIST shouldn't exist CONFIG_DEC = 4096 # trailing comments and whitespaces are fine CONFIG_HEX=57005 # 0XDEAD == 57005 CONFIG_STR="str" CONFIG_EMPTY="" # empty string must have quotes CONFIG_EXTRA="extra config items are fine too"
次のカーネル構成は、マッチングが成功しない例です。
CONFIG_TRI="y" # mismatch: quotes CONFIG_NOEXIST=y # mismatch: CONFIG_NOEXIST exists CONFIG_HEX=0x0 # mismatch; value doesn't match CONFIG_DEC="" # mismatch; type mismatch (expect int) CONFIG_EMPTY=1 # mismatch; expects "" # mismatch: CONFIG_STR is missing
SE ポリシーの一致
SE ポリシーでは、次のような一致が求められます。
<sepolicy-version>
は、すべてのメジャー バージョンについて、マイナー バージョンの範囲を定義します。デバイスが報告する sepolicy のバージョンは、フレームワークと互換性がある範囲に含まれている必要があります。マッチング ルールは HAL バージョンと同様で、sepolicy のバージョンが範囲の最小バージョン以上であれば、一致します。最大バージョンは単なる情報です。<kernel-sepolicy-version>
は policydb のバージョンです。デバイスが報告するsecurity_policyvers()
より小さい値でなければなりません。
例: SE ポリシーのマッチングが成功する場合
フレームワーク互換性マトリックスに、次のような sepolicy 情報が記述されているとします。
<sepolicy> <kernel-sepolicy-version>30</kernel-sepolicy-version> <sepolicy-version>25.0</sepolicy-version> <sepolicy-version>26.0-3</sepolicy-version> </sepolicy>
デバイス側の要件:
security_policyvers()
が返す値は 30 以上であることが必要です。それ以外の場合は一致しません。たとえば、次のようになります。- デバイスが 29 を返す場合は、一致しません。
- デバイスが 31 を返す場合は、一致します。
- SE ポリシーのバージョンは、25.0~∞ または 26.0~∞ のいずれかであることが必要です。それ以外の場合は一致しません。「
26.0
」の後の「-3
」は単なる情報です。
AVB バージョンの一致
AVB バージョンには、MAJOR バージョンと MINOR バージョンが MAJOR.MINOR(1.0、2.1 など)という形式で含まれています。詳細については、バージョニングと互換性をご覧ください。AVB バージョンには次のシステム プロパティがあります。
ro.boot.vbmeta.avb_version
は、ブートローダー内のlibavb
バージョンです。ro.boot.avb_version
は、Android OS(init/fs_mgr
)内のlibavb
バージョンです。
システム プロパティが表示されるのは、対応する libavb が AVB メタデータの検証に使用されており、OK を返したときだけです。検証が失敗したとき(または検証がまったく行われなかったとき)は、含まれません。
互換性のマッチングでは、次の比較が行われます。
- sysprop の
ro.boot.vbmeta.avb_version
とフレームワーク互換性マトリックスのavb.vbmeta-version
の比較。ro.boot.vbmeta.avb_version.MAJOR == avb.vbmeta-version.MAJOR
ro.boot.vbmeta.avb_version.MINOR >= avb.vbmeta-version.MINOR
- sysprop の
ro.boot.avb_version
とフレームワーク互換性マトリックスのavb.vbmeta-version
の比較。ro.boot.avb_version.MAJOR == avb.vbmeta-version.MAJOR
ro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR
ブートローダーまたは Android OS には、libavb
ライブラリのコピーが 2 つ(アップグレード デバイスとリリース デバイス用の MAJOR バージョンが 1 つずつ)含まれていることがあります。この場合、同じ無署名のシステム イメージを共有できますが、最終の署名済みシステム イメージは別々になります(avb.vbmeta-version
が異なります)。
/system
は P、他のすべてのパーティションは O)例: AVB バージョンのマッチングが成功する場合
フレームワーク互換性マトリックスに、次のような AVB 情報が記述されているとします。
<avb> <vbmeta-version>2.1</vbmeta-version> </avb>
デバイス側の要件:
ro.boot.avb_version == 1.0 && ro.boot.vbmeta.avb_version == 2.1 mismatch
ro.boot.avb_version == 2.1 && ro.boot.vbmeta.avb_version == 3.0 mismatch
ro.boot.avb_version == 2.1 && ro.boot.vbmeta.avb_version == 2.3 match
ro.boot.avb_version == 2.3 && ro.boot.vbmeta.avb_version == 2.1 match
OTA 時の AVB バージョンのマッチング
Android 9 以下でリリースするデバイスでは、Android 10 にアップデートすると、フレームワーク互換性マトリックスの AVB バージョン要件とデバイスの現行 AVB バージョンの一致が確認されます。OTA 時に AVB バージョンがメジャー バージョンにアップグレードされた場合(たとえば 0.0 から 1.0)、その OTA の互換性に対する VINTF チェックは、OTA 後の互換性を反映しません。
この問題を軽減するには、OEM で OTA パッケージ(compatibility.zip
)に偽の AVB バージョンを設定し、チェックをパスできるようにします。手順は次のとおりです。
- Android 9 のソースツリーで以下の CL を選択します。
- デバイスの
BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE
を定義します。この値は、OTA 前の AVB バージョン、つまりデバイスがリリースされたときの AVB バージョンと同じにする必要があります。 - OTA パッケージを再ビルドします。
上記の変更により、次のファイルで自動的に BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE
が compatibility-matrix.avb.vbmeta-version
に設定されます。
- デバイス上の
/system/compatibility_matrix.xml
(Android 9 では使用されません) - OTA パッケージの
compatibility.zip
に含まれるsystem_matrix.xml
上記の変更は、他のフレームワーク互換性マトリックス(/system/etc/vintf/compatibility_matrix.xml
など)には影響しません。OTA 後は、/system/etc/vintf/compatibility_matrix.xml
内の新しい値が互換性チェックに使用されます。
VNDK バージョンの一致
デバイス互換性マトリックスでは、必要な VNDK バージョンを compatibility-matrix.vendor-ndk.version
で宣言します。デバイス互換性マトリックスに <vendor-ndk>
タグがない場合は、適用される要件がないため、常に一致すると見なされます。
デバイス互換性マトリックスに <vendor-ndk>
タグがある場合は、フレームワーク マニフェストのフレームワークによって提供される VNDK ベンダー スナップショットのセットから、<version>
が一致する <vendor-ndk>
エントリがルックアップされます。一致するエントリが存在しない場合は、一致しません。
一致するエントリが存在する場合は、デバイス互換性マトリックスで列挙されるライブラリ セットが、フレームワーク マニフェストに記述されたライブラリ セットのサブセットであることが必要です。それ以外の場合、エントリは一致すると見なされません。
- 特別なケースとして、デバイス互換性マトリックスでライブラリが 1 つも列挙されていない場合、エントリは常に一致すると見なされます。空のセットは任意のセットのサブセットであるためです。
例: VNDK バージョンのマッチングが成功する場合
デバイス互換性マトリックスに、次のような VNDK に関する要件が記述されているとします。
<!-- Example Device Compatibility Matrix --> <vendor-ndk> <version>27</version> <library>libjpeg.so</library> <library>libbase.so</library> </vendor-ndk>
フレームワーク マニフェストでは、バージョン 27 のエントリのみが考慮されます。
<!-- Framework Manifest Example A --> <vendor-ndk> <version>27</version> <library>libjpeg.so</library> <library>libbase.so</library> <library>libfoo.so</library> </vendor-ndk>
VNDK バージョン 27 がフレームワーク マニフェストに含まれており、{libjpeg.so, libbase.so, libfoo.so} ⊇ {libjpeg.so, libbase.so}
であるため、例 A は一致します。
<!-- Framework Manifest Example B --> <vendor-ndk> <version>26</version> <library>libjpeg.so</library> <library>libbase.so</library> </vendor-ndk> <vendor-ndk> <version>27</version> <library>libbase.so</library> </vendor-ndk>
例 B は一致しません。VNDK バージョン 27 はフレームワーク マニフェストに含まれていますが、そのスナップショットのフレームワークで libjpeg.so
がサポートされていないためです。VNDK バージョン 26 は無視されます。
システム SDK バージョンの一致
デバイス互換性マトリックスでは、必要なシステム SDK バージョンのセットを compatibility-matrix.system-sdk.version
で宣言します。このシステム SDK バージョンのセットが、フレームワーク マニフェストの manifest.system-sdk.version
で宣言されているシステム SDK バージョンのサブセットである場合にのみ、一致します。
- 特別なケースとして、デバイス互換性マトリックスでシステム SDK バージョンが 1 つも列挙されていない場合は、常に一致すると見なされます。空のセットは任意のセットのサブセットであるためです。
例: システム SDK バージョンのマッチングが成功する場合
デバイス互換性マトリックスに、次のようなシステム SDK に関する要件が記述されているとします。
<!-- Example Device Compatibility Matrix --> <system-sdk> <version>26</version> <version>27</version> </system-sdk>
この場合、一致するためには、フレームワークでシステム SDK バージョン 26 と 27 を指定されている必要があります。
<!-- Framework Manifest Example A --> <system-sdk> <version>26</version> <version>27</version> </system-sdk>
例 A は一致します。
<!-- Framework Manifest Example B --> <system-sdk> <version>26</version> <version>27</version> <version>28</version> </system-sdk>
例 B は一致します。
<!-- Framework Manifest Example C --> <system-sdk> <version>26</version> </system-sdk>
システム SDK バージョン 27 が指定されていないため、例 C は一致しません。