bootclasspath_fragment_test.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  1. // Copyright (C) 2021 The Android Open Source Project
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package apex
  15. import (
  16. "fmt"
  17. "path"
  18. "sort"
  19. "strings"
  20. "testing"
  21. "android/soong/android"
  22. "android/soong/dexpreopt"
  23. "android/soong/java"
  24. "github.com/google/blueprint/proptools"
  25. )
  26. // Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART
  27. // bootclasspath_fragment requires modules from the ART apex.
  28. var prepareForTestWithBootclasspathFragment = android.GroupFixturePreparers(
  29. java.PrepareForTestWithDexpreopt,
  30. PrepareForTestWithApexBuildComponents,
  31. )
  32. // Some additional files needed for the art apex.
  33. var prepareForTestWithArtApex = android.GroupFixturePreparers(
  34. android.FixtureMergeMockFs(android.MockFS{
  35. "com.android.art.avbpubkey": nil,
  36. "com.android.art.pem": nil,
  37. "system/sepolicy/apex/com.android.art-file_contexts": nil,
  38. }),
  39. dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
  40. )
  41. func TestBootclasspathFragments(t *testing.T) {
  42. result := android.GroupFixturePreparers(
  43. prepareForTestWithBootclasspathFragment,
  44. // Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath.
  45. java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo", "platform:bar"),
  46. prepareForTestWithArtApex,
  47. java.PrepareForTestWithJavaSdkLibraryFiles,
  48. java.FixtureWithLastReleaseApis("foo"),
  49. ).RunTestWithBp(t, `
  50. java_sdk_library {
  51. name: "foo",
  52. srcs: ["b.java"],
  53. }
  54. java_library {
  55. name: "bar",
  56. srcs: ["b.java"],
  57. installable: true,
  58. }
  59. apex {
  60. name: "com.android.art",
  61. key: "com.android.art.key",
  62. bootclasspath_fragments: ["art-bootclasspath-fragment"],
  63. updatable: false,
  64. }
  65. apex_key {
  66. name: "com.android.art.key",
  67. public_key: "com.android.art.avbpubkey",
  68. private_key: "com.android.art.pem",
  69. }
  70. java_library {
  71. name: "baz",
  72. apex_available: [
  73. "com.android.art",
  74. ],
  75. srcs: ["b.java"],
  76. compile_dex: true,
  77. }
  78. java_library {
  79. name: "quuz",
  80. apex_available: [
  81. "com.android.art",
  82. ],
  83. srcs: ["b.java"],
  84. compile_dex: true,
  85. }
  86. bootclasspath_fragment {
  87. name: "art-bootclasspath-fragment",
  88. image_name: "art",
  89. // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
  90. contents: ["baz", "quuz"],
  91. apex_available: [
  92. "com.android.art",
  93. ],
  94. hidden_api: {
  95. split_packages: ["*"],
  96. },
  97. }
  98. `,
  99. )
  100. // Make sure that the art-bootclasspath-fragment is using the correct configuration.
  101. checkBootclasspathFragment(t, result, "art-bootclasspath-fragment", "android_common_apex10000",
  102. "com.android.art:baz,com.android.art:quuz")
  103. }
  104. func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
  105. result := android.GroupFixturePreparers(
  106. prepareForTestWithBootclasspathFragment,
  107. // Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath.
  108. java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
  109. java.FixtureConfigureApexBootJars("someapex:foo", "someapex:bar"),
  110. prepareForTestWithArtApex,
  111. java.PrepareForTestWithJavaSdkLibraryFiles,
  112. java.FixtureWithLastReleaseApis("foo", "baz"),
  113. ).RunTestWithBp(t, `
  114. java_sdk_library {
  115. name: "foo",
  116. srcs: ["b.java"],
  117. shared_library: false,
  118. public: {
  119. enabled: true,
  120. },
  121. system: {
  122. enabled: true,
  123. },
  124. }
  125. java_library {
  126. name: "bar",
  127. srcs: ["b.java"],
  128. installable: true,
  129. }
  130. apex {
  131. name: "com.android.art",
  132. key: "com.android.art.key",
  133. bootclasspath_fragments: ["art-bootclasspath-fragment"],
  134. updatable: false,
  135. }
  136. apex_key {
  137. name: "com.android.art.key",
  138. public_key: "com.android.art.avbpubkey",
  139. private_key: "com.android.art.pem",
  140. }
  141. java_sdk_library {
  142. name: "baz",
  143. apex_available: [
  144. "com.android.art",
  145. ],
  146. srcs: ["b.java"],
  147. shared_library: false,
  148. public: {
  149. enabled: true,
  150. },
  151. system: {
  152. enabled: true,
  153. },
  154. test: {
  155. enabled: true,
  156. },
  157. }
  158. java_library {
  159. name: "quuz",
  160. apex_available: [
  161. "com.android.art",
  162. ],
  163. srcs: ["b.java"],
  164. compile_dex: true,
  165. }
  166. bootclasspath_fragment {
  167. name: "art-bootclasspath-fragment",
  168. image_name: "art",
  169. // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
  170. contents: ["baz", "quuz"],
  171. apex_available: [
  172. "com.android.art",
  173. ],
  174. hidden_api: {
  175. split_packages: ["*"],
  176. },
  177. }
  178. bootclasspath_fragment {
  179. name: "other-bootclasspath-fragment",
  180. contents: ["foo", "bar"],
  181. fragments: [
  182. {
  183. apex: "com.android.art",
  184. module: "art-bootclasspath-fragment",
  185. },
  186. ],
  187. hidden_api: {
  188. split_packages: ["*"],
  189. },
  190. }
  191. `,
  192. )
  193. checkAPIScopeStubs := func(message string, info java.HiddenAPIInfo, apiScope *java.HiddenAPIScope, expectedPaths ...string) {
  194. t.Helper()
  195. paths := info.TransitiveStubDexJarsByScope.StubDexJarsForScope(apiScope)
  196. android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, apiScope), expectedPaths, paths)
  197. }
  198. // Check stub dex paths exported by art.
  199. artFragment := result.Module("art-bootclasspath-fragment", "android_common")
  200. artInfo := result.ModuleProvider(artFragment, java.HiddenAPIInfoProvider).(java.HiddenAPIInfo)
  201. bazPublicStubs := "out/soong/.intermediates/baz.stubs/android_common/dex/baz.stubs.jar"
  202. bazSystemStubs := "out/soong/.intermediates/baz.stubs.system/android_common/dex/baz.stubs.system.jar"
  203. bazTestStubs := "out/soong/.intermediates/baz.stubs.test/android_common/dex/baz.stubs.test.jar"
  204. checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
  205. checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
  206. checkAPIScopeStubs("art", artInfo, java.TestHiddenAPIScope, bazTestStubs)
  207. checkAPIScopeStubs("art", artInfo, java.CorePlatformHiddenAPIScope)
  208. // Check stub dex paths exported by other.
  209. otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
  210. otherInfo := result.ModuleProvider(otherFragment, java.HiddenAPIInfoProvider).(java.HiddenAPIInfo)
  211. fooPublicStubs := "out/soong/.intermediates/foo.stubs/android_common/dex/foo.stubs.jar"
  212. fooSystemStubs := "out/soong/.intermediates/foo.stubs.system/android_common/dex/foo.stubs.system.jar"
  213. checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
  214. checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
  215. checkAPIScopeStubs("other", otherInfo, java.TestHiddenAPIScope, bazTestStubs, fooSystemStubs)
  216. checkAPIScopeStubs("other", otherInfo, java.CorePlatformHiddenAPIScope)
  217. }
  218. func checkBootclasspathFragment(t *testing.T, result *android.TestResult, moduleName, variantName string, expectedConfiguredModules string) {
  219. t.Helper()
  220. bootclasspathFragment := result.ModuleForTests(moduleName, variantName).Module().(*java.BootclasspathFragmentModule)
  221. bootclasspathFragmentInfo := result.ModuleProvider(bootclasspathFragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
  222. modules := bootclasspathFragmentInfo.Modules()
  223. android.AssertStringEquals(t, "invalid modules for "+moduleName, expectedConfiguredModules, modules.String())
  224. }
  225. func TestBootclasspathFragmentInArtApex(t *testing.T) {
  226. commonPreparer := android.GroupFixturePreparers(
  227. prepareForTestWithBootclasspathFragment,
  228. prepareForTestWithArtApex,
  229. android.FixtureWithRootAndroidBp(`
  230. apex {
  231. name: "com.android.art",
  232. key: "com.android.art.key",
  233. bootclasspath_fragments: [
  234. "mybootclasspathfragment",
  235. ],
  236. // bar (like foo) should be transitively included in this apex because it is part of the
  237. // mybootclasspathfragment bootclasspath_fragment.
  238. updatable: false,
  239. }
  240. apex_key {
  241. name: "com.android.art.key",
  242. public_key: "testkey.avbpubkey",
  243. private_key: "testkey.pem",
  244. }
  245. java_library {
  246. name: "foo",
  247. srcs: ["b.java"],
  248. installable: true,
  249. apex_available: [
  250. "com.android.art",
  251. ],
  252. }
  253. java_library {
  254. name: "bar",
  255. srcs: ["b.java"],
  256. installable: true,
  257. apex_available: [
  258. "com.android.art",
  259. ],
  260. }
  261. java_import {
  262. name: "foo",
  263. jars: ["foo.jar"],
  264. apex_available: [
  265. "com.android.art",
  266. ],
  267. compile_dex: true,
  268. }
  269. java_import {
  270. name: "bar",
  271. jars: ["bar.jar"],
  272. apex_available: [
  273. "com.android.art",
  274. ],
  275. compile_dex: true,
  276. }
  277. `),
  278. )
  279. contentsInsert := func(contents []string) string {
  280. insert := ""
  281. if contents != nil {
  282. insert = fmt.Sprintf(`contents: ["%s"],`, strings.Join(contents, `", "`))
  283. }
  284. return insert
  285. }
  286. addSource := func(contents ...string) android.FixturePreparer {
  287. text := fmt.Sprintf(`
  288. bootclasspath_fragment {
  289. name: "mybootclasspathfragment",
  290. image_name: "art",
  291. %s
  292. apex_available: [
  293. "com.android.art",
  294. ],
  295. hidden_api: {
  296. split_packages: ["*"],
  297. },
  298. }
  299. `, contentsInsert(contents))
  300. return android.FixtureAddTextFile("art/build/boot/Android.bp", text)
  301. }
  302. addPrebuilt := func(prefer bool, contents ...string) android.FixturePreparer {
  303. text := fmt.Sprintf(`
  304. prebuilt_apex {
  305. name: "com.android.art",
  306. arch: {
  307. arm64: {
  308. src: "com.android.art-arm64.apex",
  309. },
  310. arm: {
  311. src: "com.android.art-arm.apex",
  312. },
  313. },
  314. exported_bootclasspath_fragments: ["mybootclasspathfragment"],
  315. }
  316. prebuilt_bootclasspath_fragment {
  317. name: "mybootclasspathfragment",
  318. image_name: "art",
  319. %s
  320. prefer: %t,
  321. apex_available: [
  322. "com.android.art",
  323. ],
  324. hidden_api: {
  325. annotation_flags: "mybootclasspathfragment/annotation-flags.csv",
  326. metadata: "mybootclasspathfragment/metadata.csv",
  327. index: "mybootclasspathfragment/index.csv",
  328. stub_flags: "mybootclasspathfragment/stub-flags.csv",
  329. all_flags: "mybootclasspathfragment/all-flags.csv",
  330. },
  331. }
  332. `, contentsInsert(contents), prefer)
  333. return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text)
  334. }
  335. t.Run("boot image files from source", func(t *testing.T) {
  336. result := android.GroupFixturePreparers(
  337. commonPreparer,
  338. // Configure some libraries in the art bootclasspath_fragment that match the source
  339. // bootclasspath_fragment's contents property.
  340. java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
  341. addSource("foo", "bar"),
  342. java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
  343. ).RunTest(t)
  344. ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
  345. "etc/boot-image.prof",
  346. "etc/classpaths/bootclasspath.pb",
  347. "javalib/bar.jar",
  348. "javalib/foo.jar",
  349. })
  350. java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
  351. `com.android.art.key`,
  352. `mybootclasspathfragment`,
  353. })
  354. // Make sure that the source bootclasspath_fragment copies its dex files to the predefined
  355. // locations for the art image.
  356. module := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
  357. checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
  358. })
  359. t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) {
  360. result := android.GroupFixturePreparers(
  361. commonPreparer,
  362. // Configure some libraries in the art bootclasspath_fragment that match the source
  363. // bootclasspath_fragment's contents property.
  364. java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
  365. addSource("foo", "bar"),
  366. java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"),
  367. dexpreopt.FixtureDisableDexpreoptBootImages(true),
  368. ).RunTest(t)
  369. ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
  370. "etc/boot-image.prof",
  371. "etc/classpaths/bootclasspath.pb",
  372. "javalib/bar.jar",
  373. "javalib/foo.jar",
  374. })
  375. })
  376. t.Run("boot image disable generate profile", func(t *testing.T) {
  377. result := android.GroupFixturePreparers(
  378. commonPreparer,
  379. // Configure some libraries in the art bootclasspath_fragment that match the source
  380. // bootclasspath_fragment's contents property.
  381. java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
  382. addSource("foo", "bar"),
  383. dexpreopt.FixtureDisableGenerateProfile(true),
  384. ).RunTest(t)
  385. files := getFiles(t, result.TestContext, "com.android.art", "android_common_com.android.art_image")
  386. for _, file := range files {
  387. matched, _ := path.Match("etc/boot-image.prof", file.path)
  388. android.AssertBoolEquals(t, "\"etc/boot-image.prof\" should not be in the APEX", matched, false)
  389. }
  390. })
  391. t.Run("boot image files with preferred prebuilt", func(t *testing.T) {
  392. result := android.GroupFixturePreparers(
  393. commonPreparer,
  394. // Configure some libraries in the art bootclasspath_fragment that match the source
  395. // bootclasspath_fragment's contents property.
  396. java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
  397. addSource("foo", "bar"),
  398. // Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
  399. addPrebuilt(true, "foo", "bar"),
  400. java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
  401. ).RunTest(t)
  402. ensureExactDeapexedContents(t, result.TestContext, "com.android.art", "android_common", []string{
  403. "etc/boot-image.prof",
  404. "javalib/bar.jar",
  405. "javalib/foo.jar",
  406. })
  407. java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
  408. `com.android.art.key`,
  409. `mybootclasspathfragment`,
  410. `prebuilt_com.android.art`,
  411. })
  412. // Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
  413. // locations for the art image.
  414. module := result.ModuleForTests("prebuilt_mybootclasspathfragment", "android_common_com.android.art")
  415. checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
  416. })
  417. t.Run("source with inconsistency between config and contents", func(t *testing.T) {
  418. android.GroupFixturePreparers(
  419. commonPreparer,
  420. // Create an inconsistency between the ArtApexJars configuration and the art source
  421. // bootclasspath_fragment module's contents property.
  422. java.FixtureConfigureBootJars("com.android.art:foo"),
  423. addSource("foo", "bar"),
  424. ).
  425. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
  426. RunTest(t)
  427. })
  428. t.Run("prebuilt with inconsistency between config and contents", func(t *testing.T) {
  429. android.GroupFixturePreparers(
  430. commonPreparer,
  431. // Create an inconsistency between the ArtApexJars configuration and the art
  432. // prebuilt_bootclasspath_fragment module's contents property.
  433. java.FixtureConfigureBootJars("com.android.art:foo"),
  434. addPrebuilt(false, "foo", "bar"),
  435. ).
  436. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
  437. RunTest(t)
  438. })
  439. t.Run("preferred prebuilt with inconsistency between config and contents", func(t *testing.T) {
  440. android.GroupFixturePreparers(
  441. commonPreparer,
  442. // Create an inconsistency between the ArtApexJars configuration and the art
  443. // prebuilt_bootclasspath_fragment module's contents property.
  444. java.FixtureConfigureBootJars("com.android.art:foo"),
  445. addPrebuilt(true, "foo", "bar"),
  446. // Source contents property is consistent with the config.
  447. addSource("foo"),
  448. ).
  449. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
  450. RunTest(t)
  451. })
  452. t.Run("source preferred and prebuilt with inconsistency between config and contents", func(t *testing.T) {
  453. android.GroupFixturePreparers(
  454. commonPreparer,
  455. // Create an inconsistency between the ArtApexJars configuration and the art
  456. // prebuilt_bootclasspath_fragment module's contents property.
  457. java.FixtureConfigureBootJars("com.android.art:foo"),
  458. addPrebuilt(false, "foo", "bar"),
  459. // Source contents property is consistent with the config.
  460. addSource("foo"),
  461. // This should pass because while the prebuilt is inconsistent with the configuration it is
  462. // not actually used.
  463. ).RunTest(t)
  464. })
  465. }
  466. func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
  467. preparers := android.GroupFixturePreparers(
  468. prepareForTestWithBootclasspathFragment,
  469. prepareForTestWithArtApex,
  470. android.FixtureMergeMockFs(android.MockFS{
  471. "com.android.art-arm64.apex": nil,
  472. "com.android.art-arm.apex": nil,
  473. }),
  474. // Configure some libraries in the art bootclasspath_fragment.
  475. java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
  476. java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
  477. )
  478. bp := `
  479. prebuilt_apex {
  480. name: "com.android.art",
  481. arch: {
  482. arm64: {
  483. src: "com.android.art-arm64.apex",
  484. },
  485. arm: {
  486. src: "com.android.art-arm.apex",
  487. },
  488. },
  489. exported_bootclasspath_fragments: ["mybootclasspathfragment"],
  490. }
  491. java_import {
  492. name: "foo",
  493. jars: ["foo.jar"],
  494. apex_available: [
  495. "com.android.art",
  496. ],
  497. }
  498. java_import {
  499. name: "bar",
  500. jars: ["bar.jar"],
  501. apex_available: [
  502. "com.android.art",
  503. ],
  504. }
  505. prebuilt_bootclasspath_fragment {
  506. name: "mybootclasspathfragment",
  507. image_name: "art",
  508. // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
  509. contents: ["foo", "bar"],
  510. apex_available: [
  511. "com.android.art",
  512. ],
  513. hidden_api: {
  514. annotation_flags: "mybootclasspathfragment/annotation-flags.csv",
  515. metadata: "mybootclasspathfragment/metadata.csv",
  516. index: "mybootclasspathfragment/index.csv",
  517. stub_flags: "mybootclasspathfragment/stub-flags.csv",
  518. all_flags: "mybootclasspathfragment/all-flags.csv",
  519. },
  520. }
  521. // A prebuilt apex with the same apex_name that shouldn't interfere when it isn't enabled.
  522. prebuilt_apex {
  523. name: "com.mycompany.android.art",
  524. apex_name: "com.android.art",
  525. %s
  526. src: "com.mycompany.android.art.apex",
  527. exported_bootclasspath_fragments: ["mybootclasspathfragment"],
  528. }
  529. `
  530. t.Run("disabled alternative APEX", func(t *testing.T) {
  531. result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
  532. java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
  533. `com.android.art.apex.selector`,
  534. `prebuilt_mybootclasspathfragment`,
  535. })
  536. java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{
  537. `com.android.art.deapexer`,
  538. `dex2oatd`,
  539. `prebuilt_bar`,
  540. `prebuilt_foo`,
  541. })
  542. module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art")
  543. checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
  544. })
  545. t.Run("enabled alternative APEX", func(t *testing.T) {
  546. preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
  547. "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.art and com.mycompany.android.art")).
  548. RunTestWithBp(t, fmt.Sprintf(bp, ""))
  549. })
  550. }
  551. // checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
  552. // predefined locations of boot dex jars used as inputs for the ART boot image.
  553. func checkCopiesToPredefinedLocationForArt(t *testing.T, config android.Config, module android.TestingModule, modules ...string) {
  554. t.Helper()
  555. bootJarLocations := []string{}
  556. for _, output := range module.AllOutputs() {
  557. output = android.StringRelativeToTop(config, output)
  558. if strings.HasPrefix(output, "out/soong/dexpreopt_arm64/dex_artjars_input/") {
  559. bootJarLocations = append(bootJarLocations, output)
  560. }
  561. }
  562. sort.Strings(bootJarLocations)
  563. expected := []string{}
  564. for _, m := range modules {
  565. expected = append(expected, fmt.Sprintf("out/soong/dexpreopt_arm64/dex_artjars_input/%s.jar", m))
  566. }
  567. sort.Strings(expected)
  568. android.AssertArrayString(t, "copies to predefined locations for art", expected, bootJarLocations)
  569. }
  570. func TestBootclasspathFragmentContentsNoName(t *testing.T) {
  571. result := android.GroupFixturePreparers(
  572. prepareForTestWithBootclasspathFragment,
  573. prepareForTestWithMyapex,
  574. // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
  575. java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
  576. // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
  577. // is disabled.
  578. android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
  579. java.PrepareForTestWithJavaSdkLibraryFiles,
  580. java.FixtureWithLastReleaseApis("foo"),
  581. ).RunTestWithBp(t, `
  582. apex {
  583. name: "myapex",
  584. key: "myapex.key",
  585. bootclasspath_fragments: [
  586. "mybootclasspathfragment",
  587. ],
  588. updatable: false,
  589. }
  590. apex_key {
  591. name: "myapex.key",
  592. public_key: "testkey.avbpubkey",
  593. private_key: "testkey.pem",
  594. }
  595. java_sdk_library {
  596. name: "foo",
  597. srcs: ["b.java"],
  598. shared_library: false,
  599. public: {enabled: true},
  600. apex_available: [
  601. "myapex",
  602. ],
  603. }
  604. java_library {
  605. name: "bar",
  606. srcs: ["b.java"],
  607. installable: true,
  608. apex_available: [
  609. "myapex",
  610. ],
  611. }
  612. bootclasspath_fragment {
  613. name: "mybootclasspathfragment",
  614. contents: [
  615. "foo",
  616. "bar",
  617. ],
  618. apex_available: [
  619. "myapex",
  620. ],
  621. hidden_api: {
  622. split_packages: ["*"],
  623. },
  624. }
  625. `)
  626. ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
  627. // This does not include art, oat or vdex files as they are only included for the art boot
  628. // image.
  629. "etc/classpaths/bootclasspath.pb",
  630. "javalib/bar.jar",
  631. "javalib/foo.jar",
  632. })
  633. java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
  634. `myapex.key`,
  635. `mybootclasspathfragment`,
  636. })
  637. apex := result.ModuleForTests("myapex", "android_common_myapex_image")
  638. apexRule := apex.Rule("apexRule")
  639. copyCommands := apexRule.Args["copy_commands"]
  640. // Make sure that the fragment provides the hidden API encoded dex jars to the APEX.
  641. fragment := result.Module("mybootclasspathfragment", "android_common_apex10000")
  642. info := result.ModuleProvider(fragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
  643. checkFragmentExportedDexJar := func(name string, expectedDexJar string) {
  644. module := result.Module(name, "android_common_apex10000")
  645. dexJar, err := info.DexBootJarPathForContentModule(module)
  646. if err != nil {
  647. t.Error(err)
  648. }
  649. android.AssertPathRelativeToTopEquals(t, name+" dex", expectedDexJar, dexJar)
  650. expectedCopyCommand := fmt.Sprintf("&& cp -f %s out/soong/.intermediates/myapex/android_common_myapex_image/image.apex/javalib/%s.jar", expectedDexJar, name)
  651. android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand)
  652. }
  653. checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar")
  654. checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar")
  655. }
  656. func getDexJarPath(result *android.TestResult, name string) string {
  657. module := result.Module(name, "android_common")
  658. return module.(java.UsesLibraryDependency).DexJarBuildPath().Path().RelativeToTop().String()
  659. }
  660. // TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
  661. // passed to the hiddenapi list tool.
  662. func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
  663. result := android.GroupFixturePreparers(
  664. prepareForTestWithBootclasspathFragment,
  665. prepareForTestWithArtApex,
  666. prepareForTestWithMyapex,
  667. // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
  668. java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
  669. java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
  670. // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
  671. // is disabled.
  672. android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
  673. java.PrepareForTestWithJavaSdkLibraryFiles,
  674. java.FixtureWithLastReleaseApis("foo", "quuz"),
  675. ).RunTestWithBp(t, `
  676. apex {
  677. name: "com.android.art",
  678. key: "com.android.art.key",
  679. bootclasspath_fragments: ["art-bootclasspath-fragment"],
  680. updatable: false,
  681. }
  682. apex_key {
  683. name: "com.android.art.key",
  684. public_key: "com.android.art.avbpubkey",
  685. private_key: "com.android.art.pem",
  686. }
  687. java_library {
  688. name: "baz",
  689. apex_available: [
  690. "com.android.art",
  691. ],
  692. srcs: ["b.java"],
  693. compile_dex: true,
  694. }
  695. java_sdk_library {
  696. name: "quuz",
  697. apex_available: [
  698. "com.android.art",
  699. ],
  700. srcs: ["b.java"],
  701. compile_dex: true,
  702. public: {enabled: true},
  703. system: {enabled: true},
  704. test: {enabled: true},
  705. module_lib: {enabled: true},
  706. }
  707. bootclasspath_fragment {
  708. name: "art-bootclasspath-fragment",
  709. image_name: "art",
  710. // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
  711. contents: ["baz", "quuz"],
  712. apex_available: [
  713. "com.android.art",
  714. ],
  715. hidden_api: {
  716. split_packages: ["*"],
  717. },
  718. }
  719. apex {
  720. name: "myapex",
  721. key: "myapex.key",
  722. bootclasspath_fragments: [
  723. "mybootclasspathfragment",
  724. ],
  725. updatable: false,
  726. }
  727. apex_key {
  728. name: "myapex.key",
  729. public_key: "testkey.avbpubkey",
  730. private_key: "testkey.pem",
  731. }
  732. java_sdk_library {
  733. name: "foo",
  734. srcs: ["b.java"],
  735. shared_library: false,
  736. public: {enabled: true},
  737. apex_available: [
  738. "myapex",
  739. ],
  740. }
  741. java_library {
  742. name: "bar",
  743. srcs: ["b.java"],
  744. installable: true,
  745. apex_available: [
  746. "myapex",
  747. ],
  748. }
  749. bootclasspath_fragment {
  750. name: "mybootclasspathfragment",
  751. contents: [
  752. "foo",
  753. "bar",
  754. ],
  755. apex_available: [
  756. "myapex",
  757. ],
  758. fragments: [
  759. {
  760. apex: "com.android.art",
  761. module: "art-bootclasspath-fragment",
  762. },
  763. ],
  764. hidden_api: {
  765. split_packages: ["*"],
  766. },
  767. }
  768. `)
  769. java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
  770. "art-bootclasspath-fragment",
  771. "bar",
  772. "dex2oatd",
  773. "foo",
  774. })
  775. fooStubs := getDexJarPath(result, "foo.stubs")
  776. quuzPublicStubs := getDexJarPath(result, "quuz.stubs")
  777. quuzSystemStubs := getDexJarPath(result, "quuz.stubs.system")
  778. quuzTestStubs := getDexJarPath(result, "quuz.stubs.test")
  779. quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.module_lib")
  780. // Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
  781. fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
  782. rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
  783. command := rule.RuleParams.Command
  784. android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
  785. // Make sure that the quuz stubs are available for resolving references from the implementation
  786. // boot dex jars provided by this module.
  787. android.AssertStringDoesContain(t, "quuz widest", command, "--dependency-stub-dex="+quuzModuleLibStubs)
  788. // Make sure that the quuz stubs are available for resolving references from the different API
  789. // stubs provided by this module.
  790. android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+quuzPublicStubs+":"+fooStubs)
  791. android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+quuzSystemStubs+":"+fooStubs)
  792. android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+quuzTestStubs+":"+fooStubs)
  793. }
  794. // TestBootclasspathFragment_AndroidNonUpdatable checks to make sure that setting
  795. // additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be
  796. // added to the hiddenapi list tool.
  797. func TestBootclasspathFragment_AndroidNonUpdatable(t *testing.T) {
  798. result := android.GroupFixturePreparers(
  799. prepareForTestWithBootclasspathFragment,
  800. prepareForTestWithArtApex,
  801. prepareForTestWithMyapex,
  802. // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
  803. java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
  804. java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
  805. // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
  806. // is disabled.
  807. android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
  808. java.PrepareForTestWithJavaSdkLibraryFiles,
  809. java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
  810. ).RunTestWithBp(t, `
  811. java_sdk_library {
  812. name: "android-non-updatable",
  813. srcs: ["b.java"],
  814. compile_dex: true,
  815. public: {
  816. enabled: true,
  817. },
  818. system: {
  819. enabled: true,
  820. },
  821. test: {
  822. enabled: true,
  823. },
  824. module_lib: {
  825. enabled: true,
  826. },
  827. }
  828. apex {
  829. name: "com.android.art",
  830. key: "com.android.art.key",
  831. bootclasspath_fragments: ["art-bootclasspath-fragment"],
  832. updatable: false,
  833. }
  834. apex_key {
  835. name: "com.android.art.key",
  836. public_key: "com.android.art.avbpubkey",
  837. private_key: "com.android.art.pem",
  838. }
  839. java_library {
  840. name: "baz",
  841. apex_available: [
  842. "com.android.art",
  843. ],
  844. srcs: ["b.java"],
  845. compile_dex: true,
  846. }
  847. java_library {
  848. name: "quuz",
  849. apex_available: [
  850. "com.android.art",
  851. ],
  852. srcs: ["b.java"],
  853. compile_dex: true,
  854. }
  855. bootclasspath_fragment {
  856. name: "art-bootclasspath-fragment",
  857. image_name: "art",
  858. // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
  859. contents: ["baz", "quuz"],
  860. apex_available: [
  861. "com.android.art",
  862. ],
  863. hidden_api: {
  864. split_packages: ["*"],
  865. },
  866. }
  867. apex {
  868. name: "myapex",
  869. key: "myapex.key",
  870. bootclasspath_fragments: [
  871. "mybootclasspathfragment",
  872. ],
  873. updatable: false,
  874. }
  875. apex_key {
  876. name: "myapex.key",
  877. public_key: "testkey.avbpubkey",
  878. private_key: "testkey.pem",
  879. }
  880. java_sdk_library {
  881. name: "foo",
  882. srcs: ["b.java"],
  883. shared_library: false,
  884. public: {enabled: true},
  885. apex_available: [
  886. "myapex",
  887. ],
  888. }
  889. java_library {
  890. name: "bar",
  891. srcs: ["b.java"],
  892. installable: true,
  893. apex_available: [
  894. "myapex",
  895. ],
  896. }
  897. bootclasspath_fragment {
  898. name: "mybootclasspathfragment",
  899. contents: [
  900. "foo",
  901. "bar",
  902. ],
  903. apex_available: [
  904. "myapex",
  905. ],
  906. additional_stubs: ["android-non-updatable"],
  907. fragments: [
  908. {
  909. apex: "com.android.art",
  910. module: "art-bootclasspath-fragment",
  911. },
  912. ],
  913. hidden_api: {
  914. split_packages: ["*"],
  915. },
  916. }
  917. `)
  918. java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
  919. "android-non-updatable.stubs",
  920. "android-non-updatable.stubs.module_lib",
  921. "android-non-updatable.stubs.system",
  922. "android-non-updatable.stubs.test",
  923. "art-bootclasspath-fragment",
  924. "bar",
  925. "dex2oatd",
  926. "foo",
  927. })
  928. nonUpdatablePublicStubs := getDexJarPath(result, "android-non-updatable.stubs")
  929. nonUpdatableSystemStubs := getDexJarPath(result, "android-non-updatable.stubs.system")
  930. nonUpdatableTestStubs := getDexJarPath(result, "android-non-updatable.stubs.test")
  931. nonUpdatableModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.module_lib")
  932. // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
  933. // API flags.
  934. fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
  935. rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
  936. command := rule.RuleParams.Command
  937. android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
  938. // Make sure that the module_lib non-updatable stubs are available for resolving references from
  939. // the implementation boot dex jars provided by this module.
  940. android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
  941. // Make sure that the appropriate non-updatable stubs are available for resolving references from
  942. // the different API stubs provided by this module.
  943. android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
  944. android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
  945. android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
  946. }
  947. // TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks checks to make sure that
  948. // setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable
  949. // modules to be added to the hiddenapi list tool.
  950. func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) {
  951. result := android.GroupFixturePreparers(
  952. prepareForTestWithBootclasspathFragment,
  953. java.PrepareForTestWithDexpreopt,
  954. prepareForTestWithArtApex,
  955. prepareForTestWithMyapex,
  956. // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
  957. java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
  958. java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
  959. // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
  960. // is disabled.
  961. android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
  962. android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
  963. variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
  964. }),
  965. java.PrepareForTestWithJavaSdkLibraryFiles,
  966. java.FixtureWithPrebuiltApis(map[string][]string{
  967. "current": {"android-non-updatable"},
  968. "30": {"foo"},
  969. }),
  970. ).RunTestWithBp(t, `
  971. apex {
  972. name: "com.android.art",
  973. key: "com.android.art.key",
  974. bootclasspath_fragments: ["art-bootclasspath-fragment"],
  975. updatable: false,
  976. }
  977. apex_key {
  978. name: "com.android.art.key",
  979. public_key: "com.android.art.avbpubkey",
  980. private_key: "com.android.art.pem",
  981. }
  982. java_library {
  983. name: "baz",
  984. apex_available: [
  985. "com.android.art",
  986. ],
  987. srcs: ["b.java"],
  988. compile_dex: true,
  989. }
  990. java_library {
  991. name: "quuz",
  992. apex_available: [
  993. "com.android.art",
  994. ],
  995. srcs: ["b.java"],
  996. compile_dex: true,
  997. }
  998. bootclasspath_fragment {
  999. name: "art-bootclasspath-fragment",
  1000. image_name: "art",
  1001. // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
  1002. contents: ["baz", "quuz"],
  1003. apex_available: [
  1004. "com.android.art",
  1005. ],
  1006. hidden_api: {
  1007. split_packages: ["*"],
  1008. },
  1009. }
  1010. apex {
  1011. name: "myapex",
  1012. key: "myapex.key",
  1013. bootclasspath_fragments: [
  1014. "mybootclasspathfragment",
  1015. ],
  1016. updatable: false,
  1017. }
  1018. apex_key {
  1019. name: "myapex.key",
  1020. public_key: "testkey.avbpubkey",
  1021. private_key: "testkey.pem",
  1022. }
  1023. java_sdk_library {
  1024. name: "foo",
  1025. srcs: ["b.java"],
  1026. shared_library: false,
  1027. public: {enabled: true},
  1028. apex_available: [
  1029. "myapex",
  1030. ],
  1031. }
  1032. java_library {
  1033. name: "bar",
  1034. srcs: ["b.java"],
  1035. installable: true,
  1036. apex_available: [
  1037. "myapex",
  1038. ],
  1039. }
  1040. bootclasspath_fragment {
  1041. name: "mybootclasspathfragment",
  1042. contents: [
  1043. "foo",
  1044. "bar",
  1045. ],
  1046. apex_available: [
  1047. "myapex",
  1048. ],
  1049. additional_stubs: ["android-non-updatable"],
  1050. fragments: [
  1051. {
  1052. apex: "com.android.art",
  1053. module: "art-bootclasspath-fragment",
  1054. },
  1055. ],
  1056. hidden_api: {
  1057. split_packages: ["*"],
  1058. },
  1059. }
  1060. `)
  1061. java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
  1062. "art-bootclasspath-fragment",
  1063. "bar",
  1064. "dex2oatd",
  1065. "foo",
  1066. "prebuilt_sdk_module-lib_current_android-non-updatable",
  1067. "prebuilt_sdk_public_current_android-non-updatable",
  1068. "prebuilt_sdk_system_current_android-non-updatable",
  1069. "prebuilt_sdk_test_current_android-non-updatable",
  1070. })
  1071. nonUpdatablePublicStubs := getDexJarPath(result, "sdk_public_current_android-non-updatable")
  1072. nonUpdatableSystemStubs := getDexJarPath(result, "sdk_system_current_android-non-updatable")
  1073. nonUpdatableTestStubs := getDexJarPath(result, "sdk_test_current_android-non-updatable")
  1074. nonUpdatableModuleLibStubs := getDexJarPath(result, "sdk_module-lib_current_android-non-updatable")
  1075. // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
  1076. // API flags.
  1077. fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
  1078. rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
  1079. command := rule.RuleParams.Command
  1080. android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
  1081. // Make sure that the module_lib non-updatable stubs are available for resolving references from
  1082. // the implementation boot dex jars provided by this module.
  1083. android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
  1084. // Make sure that the appropriate non-updatable stubs are available for resolving references from
  1085. // the different API stubs provided by this module.
  1086. android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
  1087. android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
  1088. android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
  1089. }
  1090. // TODO(b/177892522) - add test for host apex.