1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tests.apex; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assume.assumeTrue; 22 23 import android.cts.install.lib.host.InstallUtilsHost; 24 25 import com.android.compatibility.common.util.CpuFeatures; 26 import com.android.internal.util.test.SystemPreparer; 27 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 28 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 29 30 import org.junit.Rule; 31 import org.junit.Test; 32 import org.junit.rules.RuleChain; 33 import org.junit.rules.TemporaryFolder; 34 import org.junit.runner.RunWith; 35 36 import java.time.Duration; 37 38 @RunWith(DeviceJUnit4ClassRunner.class) 39 public class SharedLibsApexTest extends BaseHostJUnit4Test { 40 41 private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this); 42 private final TemporaryFolder mTemporaryFolder = new TemporaryFolder(); 43 private final SystemPreparer mPreparer = new SystemPreparer(mTemporaryFolder, 44 this::getDevice); 45 46 @Rule 47 public final RuleChain ruleChain = RuleChain.outerRule(mTemporaryFolder).around(mPreparer); 48 49 enum ApexName { 50 FOO, 51 BAR, 52 BAZ, 53 PONY, 54 SHAREDLIBS, 55 SHAREDLIBS_SECONDARY 56 } 57 58 enum ApexVersion { 59 ONE, 60 TWO 61 } 62 63 enum ApexType { 64 DEFAULT, 65 STRIPPED 66 } 67 68 enum SharedLibsVersion { 69 X, 70 Y, 71 Z 72 } 73 74 /** 75 * Utility function to generate test apex names in the form e.g.: 76 * "com.android.apex.test.bar.v1.libvX.apex" 77 */ getTestApex(ApexName apexName, ApexType apexType, ApexVersion apexVersion, SharedLibsVersion sharedLibsVersion)78 private String getTestApex(ApexName apexName, ApexType apexType, ApexVersion apexVersion, 79 SharedLibsVersion sharedLibsVersion) { 80 StringBuilder ret = new StringBuilder(); 81 ret.append("com.android.apex.test."); 82 switch(apexName) { 83 case FOO: 84 ret.append("foo"); 85 break; 86 case BAR: 87 ret.append("bar"); 88 break; 89 case BAZ: 90 ret.append("baz"); 91 break; 92 case PONY: 93 ret.append("pony"); 94 break; 95 case SHAREDLIBS: 96 ret.append("sharedlibs_generated"); 97 break; 98 case SHAREDLIBS_SECONDARY: 99 ret.append("sharedlibs_secondary_generated"); 100 break; 101 } 102 103 switch(apexType) { 104 case STRIPPED: 105 ret.append("_stripped"); 106 break; 107 case DEFAULT: 108 break; 109 } 110 111 switch(apexVersion) { 112 case ONE: 113 ret.append(".v1"); 114 break; 115 case TWO: 116 ret.append(".v2"); 117 break; 118 } 119 120 switch(sharedLibsVersion) { 121 case X: 122 ret.append(".libvX.apex"); 123 break; 124 case Y: 125 ret.append(".libvY.apex"); 126 break; 127 case Z: 128 ret.append(".libvZ.apex"); 129 break; 130 } 131 132 return ret.toString(); 133 } 134 135 /** 136 * Utility function to generate the file name of an installed package as per 137 * apexd convention e.g.: "com.android.apex.test.bar@1.apex" 138 */ getInstalledApexFileName(ApexName apexName, ApexVersion apexVersion)139 private String getInstalledApexFileName(ApexName apexName, ApexVersion apexVersion) { 140 StringBuilder ret = new StringBuilder(); 141 ret.append("com.android.apex.test."); 142 switch(apexName) { 143 case FOO: 144 ret.append("foo"); 145 break; 146 case BAR: 147 ret.append("bar"); 148 break; 149 case BAZ: 150 ret.append("baz"); 151 break; 152 case PONY: 153 ret.append("pony"); 154 break; 155 case SHAREDLIBS: 156 ret.append("sharedlibs"); 157 break; 158 case SHAREDLIBS_SECONDARY: 159 ret.append("sharedlibs_secondary"); 160 break; 161 } 162 ret.append("@"); 163 switch(apexVersion) { 164 case ONE: 165 ret.append("1"); 166 break; 167 case TWO: 168 ret.append("2"); 169 break; 170 } 171 ret.append(".apex"); 172 return ret.toString(); 173 } 174 175 /** 176 * Tests basic functionality of two apex packages being force-installed and the C++ binaries 177 * contained in them being executed correctly. 178 */ 179 @Test testInstallAndRunDefaultApexs()180 public void testInstallAndRunDefaultApexs() throws Exception { 181 assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported()); 182 assumeTrue("Device requires root", getDevice().isAdbRoot()); 183 184 for (String apex : new String[]{ 185 getTestApex(ApexName.BAR, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.X), 186 getTestApex(ApexName.FOO, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.X), 187 getTestApex(ApexName.PONY, ApexType.DEFAULT, ApexVersion.ONE, SharedLibsVersion.Z), 188 }) { 189 mPreparer.pushResourceFile(apex, 190 "/system/apex/" + apex); 191 } 192 mPreparer.reboot(); 193 194 getDevice().disableAdbRoot(); 195 String runAsResult = getDevice().executeShellCommand( 196 "/apex/com.android.apex.test.foo/bin/foo_test"); 197 assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X"); 198 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 199 runAsResult = getDevice().executeShellCommand( 200 "/apex/com.android.apex.test.bar/bin/bar_test32"); 201 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 202 } 203 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 204 runAsResult = getDevice().executeShellCommand( 205 "/apex/com.android.apex.test.bar/bin/bar_test64"); 206 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 207 } 208 runAsResult = getDevice().executeShellCommand( 209 "/apex/com.android.apex.test.pony/bin/pony_test"); 210 assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z"); 211 212 mPreparer.stageMultiplePackages( 213 new String[]{ 214 getTestApex(ApexName.BAR, ApexType.DEFAULT, ApexVersion.TWO, SharedLibsVersion.Y), 215 getTestApex(ApexName.FOO, ApexType.DEFAULT, ApexVersion.TWO, SharedLibsVersion.Y), 216 }, 217 new String[] { 218 "com.android.apex.test.bar", 219 "com.android.apex.test.foo", 220 }).reboot(); 221 222 runAsResult = getDevice().executeShellCommand( 223 "/apex/com.android.apex.test.foo/bin/foo_test"); 224 assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y"); 225 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 226 runAsResult = getDevice().executeShellCommand( 227 "/apex/com.android.apex.test.bar/bin/bar_test32"); 228 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 229 } 230 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 231 runAsResult = getDevice().executeShellCommand( 232 "/apex/com.android.apex.test.bar/bin/bar_test64"); 233 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 234 } 235 } 236 237 /** 238 * Tests functionality of shared libraries apex: installs two apexs "stripped" of libc++.so and 239 * one apex containing it and verifies that C++ binaries can run. 240 */ 241 @Test testInstallAndRunOptimizedApexs()242 public void testInstallAndRunOptimizedApexs() throws Exception { 243 assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported()); 244 assumeTrue("Device requires root", getDevice().isAdbRoot()); 245 246 // Base case: 247 // 248 // Pre-installed on /system: 249 // package bar version 1 using library version X 250 // package foo version 1 using library version X 251 // package sharedlibs version 1 exporting library version X 252 // 253 // package pony version 1 using library version Z 254 // package sharedlibs_secondary version 1 exporting library version Z 255 256 for (String apex : new String[]{ 257 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 258 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 259 getTestApex(ApexName.PONY, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.Z), 260 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE, 261 SharedLibsVersion.X), 262 getTestApex(ApexName.SHAREDLIBS_SECONDARY, ApexType.DEFAULT, ApexVersion.ONE, 263 SharedLibsVersion.Z), 264 }) { 265 mPreparer.pushResourceFile(apex, 266 "/system/apex/" + apex); 267 } 268 mPreparer.reboot(); 269 270 getDevice().disableAdbRoot(); 271 String runAsResult = getDevice().executeShellCommand( 272 "/apex/com.android.apex.test.foo/bin/foo_test"); 273 assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X"); 274 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 275 runAsResult = getDevice().executeShellCommand( 276 "/apex/com.android.apex.test.bar/bin/bar_test32"); 277 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 278 } 279 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 280 runAsResult = getDevice().executeShellCommand( 281 "/apex/com.android.apex.test.bar/bin/bar_test64"); 282 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 283 } 284 runAsResult = getDevice().executeShellCommand( 285 "/apex/com.android.apex.test.pony/bin/pony_test"); 286 assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z"); 287 288 // Edge case: sharedlibs updated with a same version apex. 289 // 290 // Updated packages (installed on /data/apex/active): 291 // package sharedlibs version 1 exporting library version X <-- new 292 // package sharedlibs_secondary version 1 exporting library version Z <-- new 293 // 294 // Pre-installed: 295 // package bar version 1 using library version X 296 // package foo version 1 using library version X 297 // (inactive) package sharedlibs version 1 exporting library version X 298 // 299 // package pony version 1 using library version Z 300 // (inactive) package sharedlibs_secondary version 1 exporting library version Z 301 302 mPreparer.stageMultiplePackages( 303 new String[]{ 304 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE, 305 SharedLibsVersion.X), 306 getTestApex(ApexName.SHAREDLIBS_SECONDARY, ApexType.DEFAULT, ApexVersion.ONE, 307 SharedLibsVersion.Z), 308 }, 309 new String[]{ 310 "com.android.apex.test.sharedlibs", 311 "com.android.apex.test.sharedlibs_secondary", 312 }).reboot(); 313 314 runAsResult = getDevice().executeShellCommand( 315 "/apex/com.android.apex.test.foo/bin/foo_test"); 316 assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X"); 317 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 318 runAsResult = getDevice().executeShellCommand( 319 "/apex/com.android.apex.test.bar/bin/bar_test32"); 320 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 321 } 322 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 323 runAsResult = getDevice().executeShellCommand( 324 "/apex/com.android.apex.test.bar/bin/bar_test64"); 325 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 326 } 327 runAsResult = getDevice().executeShellCommand( 328 "/apex/com.android.apex.test.pony/bin/pony_test"); 329 assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z"); 330 331 // Updated packages (installed on /data/apex/active): 332 // package bar version 2 using library version Y <-- new 333 // package foo version 2 using library version Y <-- new 334 // package sharedlibs version 2 exporting library version Y <-- new 335 // package sharedlibs_secondary version 1 exporting library version Z 336 // 337 // Pre-installed: 338 // (inactive) package bar version 1 using library version X 339 // (inactive) package foo version 1 using library version X 340 // package sharedlibs version 1 exporting library version X 341 // 342 // package pony version 1 using library version Z 343 // (inactive) package sharedlibs_secondary version 1 exporting library version Z 344 345 mPreparer.stageMultiplePackages( 346 new String[]{ 347 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y), 348 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y), 349 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.TWO, 350 SharedLibsVersion.Y), 351 }, 352 new String[]{ 353 "com.android.apex.test.bar", 354 "com.android.apex.test.foo", 355 "com.android.apex.test.sharedlibs", 356 }).reboot(); 357 358 runAsResult = getDevice().executeShellCommand( 359 "/apex/com.android.apex.test.foo/bin/foo_test"); 360 assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y"); 361 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 362 runAsResult = getDevice().executeShellCommand( 363 "/apex/com.android.apex.test.bar/bin/bar_test32"); 364 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 365 } 366 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 367 runAsResult = getDevice().executeShellCommand( 368 "/apex/com.android.apex.test.bar/bin/bar_test64"); 369 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 370 } 371 runAsResult = getDevice().executeShellCommand( 372 "/apex/com.android.apex.test.pony/bin/pony_test"); 373 assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z"); 374 375 // Assume that an OTA now adds a package baz on /system needing libraries installed on 376 // /system: 377 // 378 // Updated packages (installed on /data/apex/active): 379 // package bar version 2 using library version Y 380 // package foo version 2 using library version Y 381 // package sharedlibs version 2 exporting library version Y 382 // 383 // Pre-installed: 384 // (inactive) package bar version 1 using library version X 385 // package baz version 1 using library version X <-- new 386 // (inactive) package foo version 1 using library version X 387 // package sharedlibs version 1 exporting library version X 388 // package pony version 1 using library version Z 389 // package sharedlibs_secondary version 1 exporting library version Z 390 391 String baz_apex = 392 getTestApex(ApexName.BAZ, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X); 393 mPreparer.pushResourceFile(baz_apex, "/system/apex/" + baz_apex); 394 mPreparer.reboot(); 395 396 runAsResult = getDevice().executeShellCommand( 397 "/apex/com.android.apex.test.foo/bin/foo_test"); 398 assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y"); 399 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 400 runAsResult = getDevice().executeShellCommand( 401 "/apex/com.android.apex.test.bar/bin/bar_test32"); 402 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 403 } 404 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 405 runAsResult = getDevice().executeShellCommand( 406 "/apex/com.android.apex.test.bar/bin/bar_test64"); 407 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 408 } 409 runAsResult = getDevice().executeShellCommand( 410 "/apex/com.android.apex.test.baz/bin/baz_test"); 411 assertThat(runAsResult).isEqualTo("BAZ_VERSION_1 SHARED_LIB_VERSION_X"); 412 runAsResult = getDevice().executeShellCommand( 413 "/apex/com.android.apex.test.pony/bin/pony_test"); 414 assertThat(runAsResult).isEqualTo("PONY_VERSION_1 SHARED_LIB_VERSION_Z"); 415 } 416 417 /** 418 * Tests that when a shared library apex is updated via OTA the previously 419 * downloaded version is remoted. 420 */ 421 @Test testHigherVersionOnSystemDeletesDataVersion()422 public void testHigherVersionOnSystemDeletesDataVersion() throws Exception { 423 assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported()); 424 assumeTrue("Device requires root", getDevice().isAdbRoot()); 425 426 // Base case: 427 // 428 // Pre-installed on /system: 429 // package bar version 1 using library version X 430 // package foo version 1 using library version X 431 // package sharedlibs version 1 exporting library version X 432 for (String apex : new String[]{ 433 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 434 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 435 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE, 436 SharedLibsVersion.X), 437 }) { 438 mPreparer.pushResourceFile(apex, 439 "/system/apex/" + apex); 440 } 441 mPreparer.reboot(); 442 String runAsResult = getDevice().executeShellCommand( 443 "/apex/com.android.apex.test.foo/bin/foo_test"); 444 assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X"); 445 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 446 runAsResult = getDevice().executeShellCommand( 447 "/apex/com.android.apex.test.bar/bin/bar_test32"); 448 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 449 } 450 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 451 runAsResult = getDevice().executeShellCommand( 452 "/apex/com.android.apex.test.bar/bin/bar_test64"); 453 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 454 } 455 456 // Same-grade case: 457 // 458 // Pre-installed on /system: 459 // package bar version 1 using library version X 460 // package foo version 1 using library version X 461 // package sharedlibs version 1 exporting library version X 462 // Updated packages (installed on /data/apex/active): 463 // package bar version 1 using library version X 464 // package foo version 1 using library version X 465 // package sharedlibs version 1 exporting library version X 466 mPreparer.stageMultiplePackages( 467 new String[]{ 468 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 469 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 470 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE, 471 SharedLibsVersion.X), 472 }, 473 new String[]{ 474 "com.android.apex.test.bar", 475 "com.android.apex.test.foo", 476 "com.android.apex.test.sharedlibs", 477 }).reboot(); 478 479 runAsResult = getDevice().executeShellCommand( 480 "/apex/com.android.apex.test.foo/bin/foo_test"); 481 assertThat(runAsResult).isEqualTo("FOO_VERSION_1 SHARED_LIB_VERSION_X"); 482 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 483 runAsResult = getDevice().executeShellCommand( 484 "/apex/com.android.apex.test.bar/bin/bar_test32"); 485 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 486 } 487 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 488 runAsResult = getDevice().executeShellCommand( 489 "/apex/com.android.apex.test.bar/bin/bar_test64"); 490 assertThat(runAsResult).isEqualTo("BAR_VERSION_1 SHARED_LIB_VERSION_X"); 491 } 492 493 // Simulate OTA upgrading pre-installed modules: 494 // 495 // Pre-installed on /system: 496 // package bar version 2 using library version Y 497 // package foo version 2 using library version Y 498 // package sharedlibs version 2 exporting library version Y 499 // 500 // Updated packages (installed on /data/apex/active): 501 // package bar version 1 using library version X (deleted) 502 // package foo version 1 using library version X (deleted) 503 // package sharedlibs version 1 exporting library version X (deleted) 504 // 505 for (String apex : new String[]{ 506 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 507 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.ONE, SharedLibsVersion.X), 508 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.ONE, 509 SharedLibsVersion.X), 510 }) { 511 mPreparer.deleteFile("/system/apex/" + apex); 512 } 513 for (String apex : new String[]{ 514 getTestApex(ApexName.BAR, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y), 515 getTestApex(ApexName.FOO, ApexType.STRIPPED, ApexVersion.TWO, SharedLibsVersion.Y), 516 getTestApex(ApexName.SHAREDLIBS, ApexType.DEFAULT, ApexVersion.TWO, 517 SharedLibsVersion.Y), 518 }) { 519 mPreparer.pushResourceFile(apex, 520 "/system/apex/" + apex); 521 } 522 523 // Check that files in /data are deleted on first boot. 524 assertThat(getDevice().doesFileExist("/data/apex/active/" 525 + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE))).isTrue(); 526 assertThat(getDevice().doesFileExist("/data/apex/active/" 527 + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE))).isTrue(); 528 assertThat(getDevice().doesFileExist("/data/apex/active/" 529 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE))).isTrue(); 530 mPreparer.reboot(); 531 mHostUtils.waitForFileDeleted("/data/apex/active/" 532 + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE), Duration.ofMinutes(3)); 533 mHostUtils.waitForFileDeleted("/data/apex/active/" 534 + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE), Duration.ofMinutes(3)); 535 mHostUtils.waitForFileDeleted("/data/apex/active/" 536 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE), 537 Duration.ofMinutes(3)); 538 539 getDevice().disableAdbRoot(); 540 runAsResult = getDevice().executeShellCommand( 541 "/apex/com.android.apex.test.foo/bin/foo_test"); 542 assertThat(runAsResult).isEqualTo("FOO_VERSION_2 SHARED_LIB_VERSION_Y"); 543 if (CpuFeatures.isX86_32(getDevice()) || CpuFeatures.isArm32(getDevice())) { 544 runAsResult = getDevice().executeShellCommand( 545 "/apex/com.android.apex.test.bar/bin/bar_test32"); 546 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 547 } 548 if (CpuFeatures.isX86_64(getDevice()) || CpuFeatures.isArm64(getDevice())) { 549 runAsResult = getDevice().executeShellCommand( 550 "/apex/com.android.apex.test.bar/bin/bar_test64"); 551 assertThat(runAsResult).isEqualTo("BAR_VERSION_2 SHARED_LIB_VERSION_Y"); 552 } 553 } 554 } 555