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