1 /* 2 * Copyright (C) 2022 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.server.pm; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.ArgumentMatchers.anyString; 24 import static org.mockito.Mockito.doAnswer; 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.doThrow; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.spy; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 import static org.testng.Assert.assertThrows; 33 34 import android.annotation.NonNull; 35 import android.annotation.Nullable; 36 import android.apex.ApexInfo; 37 import android.apex.ApexSessionInfo; 38 import android.apex.ApexSessionParams; 39 import android.apex.IApexService; 40 import android.content.pm.ApplicationInfo; 41 import android.content.pm.PackageManager; 42 import android.os.Build; 43 import android.os.Environment; 44 import android.os.RemoteException; 45 import android.os.ServiceSpecificException; 46 import android.platform.test.annotations.Presubmit; 47 48 import androidx.test.filters.SmallTest; 49 import androidx.test.runner.AndroidJUnit4; 50 51 import com.android.server.pm.parsing.PackageParser2; 52 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 53 import com.android.server.pm.pkg.AndroidPackage; 54 import com.android.server.pm.pkg.parsing.ParsingPackageUtils; 55 56 import org.junit.Before; 57 import org.junit.Rule; 58 import org.junit.Test; 59 import org.junit.runner.RunWith; 60 61 import java.io.BufferedOutputStream; 62 import java.io.File; 63 import java.io.FileOutputStream; 64 import java.io.IOException; 65 import java.io.InputStream; 66 import java.io.OutputStream; 67 import java.util.List; 68 import java.util.Objects; 69 70 @SmallTest 71 @Presubmit 72 @RunWith(AndroidJUnit4.class) 73 74 public class ApexManagerTest { 75 76 @Rule 77 public final MockSystemRule mMockSystem = new MockSystemRule(); 78 79 private static final String TEST_APEX_PKG = "com.android.apex.test"; 80 private static final String TEST_APEX_FILE_NAME = "apex.test.apex"; 81 private static final int TEST_SESSION_ID = 99999999; 82 private static final int[] TEST_CHILD_SESSION_ID = {8888, 7777}; 83 private ApexManager mApexManager; 84 private PackageParser2 mPackageParser2; 85 86 private IApexService mApexService = mock(IApexService.class); 87 88 private PackageManagerService mPmService; 89 90 private InstallPackageHelper mInstallPackageHelper; 91 92 @Before setUp()93 public void setUp() throws Exception { 94 ApexManager.ApexManagerImpl managerImpl = spy(new ApexManager.ApexManagerImpl()); 95 doReturn(mApexService).when(managerImpl).waitForApexService(); 96 when(mApexService.getActivePackages()).thenReturn(new ApexInfo[0]); 97 mApexManager = managerImpl; 98 mPackageParser2 = new PackageParser2(null, null, null, new PackageParser2.Callback() { 99 @Override 100 public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) { 101 return true; 102 } 103 104 @Override 105 public boolean hasFeature(String feature) { 106 return true; 107 } 108 }); 109 110 mMockSystem.system().stageNominalSystemState(); 111 mPmService = new PackageManagerService(mMockSystem.mocks().getInjector(), 112 false /*factoryTest*/, 113 MockSystem.Companion.getDEFAULT_VERSION_INFO().fingerprint, 114 false /*isEngBuild*/, 115 false /*isUserDebugBuild*/, 116 Build.VERSION_CODES.CUR_DEVELOPMENT, 117 Build.VERSION.INCREMENTAL); 118 mMockSystem.system().validateFinalState(); 119 mInstallPackageHelper = new InstallPackageHelper(mPmService, mock(AppDataHelper.class)); 120 } 121 122 @NonNull scanApexInfos(ApexInfo[] apexInfos)123 private List<ApexManager.ScanResult> scanApexInfos(ApexInfo[] apexInfos) { 124 return mInstallPackageHelper.scanApexPackages(apexInfos, 125 ParsingPackageUtils.PARSE_IS_SYSTEM_DIR, 126 PackageManagerService.SCAN_AS_SYSTEM, mPackageParser2, 127 ParallelPackageParser.makeExecutorService()); 128 } 129 130 @Nullable findActive(@onNull List<ApexManager.ScanResult> results)131 private ApexManager.ScanResult findActive(@NonNull List<ApexManager.ScanResult> results) { 132 return results.stream() 133 .filter(it -> it.apexInfo.isActive) 134 .filter(it -> Objects.equals(it.packageName, TEST_APEX_PKG)) 135 .findFirst() 136 .orElse(null); 137 } 138 139 @Nullable findFactory(@onNull List<ApexManager.ScanResult> results, @NonNull String packageName)140 private ApexManager.ScanResult findFactory(@NonNull List<ApexManager.ScanResult> results, 141 @NonNull String packageName) { 142 return results.stream() 143 .filter(it -> it.apexInfo.isFactory) 144 .filter(it -> Objects.equals(it.packageName, packageName)) 145 .findFirst() 146 .orElse(null); 147 } 148 149 @NonNull mockParsePackage(@onNull PackageParser2 parser, @NonNull ApexInfo apexInfo)150 private AndroidPackage mockParsePackage(@NonNull PackageParser2 parser, 151 @NonNull ApexInfo apexInfo) { 152 var flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; 153 try { 154 var parsedPackage = parser.parsePackage(new File(apexInfo.modulePath), flags, 155 /* useCaches= */ false); 156 ScanPackageUtils.applyPolicy(parsedPackage, 157 PackageManagerService.SCAN_AS_APEX | PackageManagerService.SCAN_AS_SYSTEM, 158 mPmService.getPlatformPackage(), /* isUpdatedSystemApp */ false); 159 // isUpdatedSystemApp is ignoreable above, only used for shared library adjustment 160 return parsedPackage.hideAsFinal(); 161 } catch (PackageManagerException e) { 162 throw new RuntimeException(e); 163 } 164 } 165 166 @Test testScanActivePackage()167 public void testScanActivePackage() { 168 var apexInfos = createApexInfoForTestPkg(true, false); 169 var results = scanApexInfos(apexInfos); 170 var active = findActive(results); 171 var factory = findFactory(results, TEST_APEX_PKG); 172 173 assertThat(active).isNotNull(); 174 assertThat(active.packageName).isEqualTo(TEST_APEX_PKG); 175 176 assertThat(factory).isNull(); 177 } 178 179 @Test testScanFactoryPackage()180 public void testScanFactoryPackage() { 181 var apexInfos = createApexInfoForTestPkg(false, true); 182 var results = scanApexInfos(apexInfos); 183 var active = findActive(results); 184 var factory = findFactory(results, TEST_APEX_PKG); 185 186 assertThat(factory).isNotNull(); 187 assertThat(factory.packageName).contains(TEST_APEX_PKG); 188 189 assertThat(active).isNull(); 190 } 191 192 @Test testGetApexSystemServices()193 public void testGetApexSystemServices() { 194 ApexInfo[] apexInfo = new ApexInfo[]{ 195 createApexInfoForTestPkg(false, true, 1), 196 // only active apex reports apex-system-service 197 createApexInfoForTestPkg(true, false, 2), 198 }; 199 200 List<ApexManager.ScanResult> scanResults = scanApexInfos(apexInfo); 201 mApexManager.notifyScanResult(scanResults); 202 203 List<ApexSystemServiceInfo> services = mApexManager.getApexSystemServices(); 204 assertThat(services).hasSize(1); 205 assertThat(services.stream().map(ApexSystemServiceInfo::getName).findFirst().orElse(null)) 206 .matches("com.android.apex.test.ApexSystemService"); 207 } 208 209 @Test testIsApexPackage()210 public void testIsApexPackage() { 211 var apexInfos = createApexInfoForTestPkg(false, true); 212 var results = scanApexInfos(apexInfos); 213 var factory = findFactory(results, TEST_APEX_PKG); 214 assertThat(factory.pkg.isApex()).isTrue(); 215 } 216 217 @Test testIsApexSupported()218 public void testIsApexSupported() { 219 assertThat(mApexManager.isApexSupported()).isTrue(); 220 } 221 222 @Test testGetStagedSessionInfo()223 public void testGetStagedSessionInfo() throws RemoteException { 224 when(mApexService.getStagedSessionInfo(anyInt())).thenReturn( 225 getFakeStagedSessionInfo()); 226 227 mApexManager.getStagedSessionInfo(TEST_SESSION_ID); 228 verify(mApexService, times(1)).getStagedSessionInfo(TEST_SESSION_ID); 229 } 230 231 @Test testGetStagedSessionInfo_unKnownStagedSessionId()232 public void testGetStagedSessionInfo_unKnownStagedSessionId() throws RemoteException { 233 when(mApexService.getStagedSessionInfo(anyInt())).thenReturn( 234 getFakeUnknownSessionInfo()); 235 236 assertThat(mApexManager.getStagedSessionInfo(TEST_SESSION_ID)).isNull(); 237 } 238 239 @Test testSubmitStagedSession_throwPackageManagerException()240 public void testSubmitStagedSession_throwPackageManagerException() throws RemoteException { 241 doAnswer(invocation -> { 242 throw new Exception(); 243 }).when(mApexService).submitStagedSession(any(), any()); 244 245 assertThrows(PackageManagerException.class, 246 () -> mApexManager.submitStagedSession(testParamsWithChildren())); 247 } 248 249 @Test testSubmitStagedSession_throwRunTimeException()250 public void testSubmitStagedSession_throwRunTimeException() throws RemoteException { 251 doThrow(RemoteException.class).when(mApexService).submitStagedSession(any(), any()); 252 253 assertThrows(RuntimeException.class, 254 () -> mApexManager.submitStagedSession(testParamsWithChildren())); 255 } 256 257 @Test testGetStagedApexInfos_throwRunTimeException()258 public void testGetStagedApexInfos_throwRunTimeException() throws RemoteException { 259 doThrow(RemoteException.class).when(mApexService).getStagedApexInfos(any()); 260 261 assertThrows(RuntimeException.class, 262 () -> mApexManager.getStagedApexInfos(testParamsWithChildren())); 263 } 264 265 @Test testGetStagedApexInfos_returnsEmptyArrayOnError()266 public void testGetStagedApexInfos_returnsEmptyArrayOnError() throws RemoteException { 267 doThrow(ServiceSpecificException.class).when(mApexService).getStagedApexInfos(any()); 268 269 assertThat(mApexManager.getStagedApexInfos(testParamsWithChildren())).hasLength(0); 270 } 271 272 @Test testMarkStagedSessionReady_throwPackageManagerException()273 public void testMarkStagedSessionReady_throwPackageManagerException() throws RemoteException { 274 doAnswer(invocation -> { 275 throw new Exception(); 276 }).when(mApexService).markStagedSessionReady(anyInt()); 277 278 assertThrows(PackageManagerException.class, 279 () -> mApexManager.markStagedSessionReady(TEST_SESSION_ID)); 280 } 281 282 @Test testMarkStagedSessionReady_throwRunTimeException()283 public void testMarkStagedSessionReady_throwRunTimeException() throws RemoteException { 284 doThrow(RemoteException.class).when(mApexService).markStagedSessionReady(anyInt()); 285 286 assertThrows(RuntimeException.class, 287 () -> mApexManager.markStagedSessionReady(TEST_SESSION_ID)); 288 } 289 290 @Test testRevertActiveSessions_remoteException()291 public void testRevertActiveSessions_remoteException() throws RemoteException { 292 doThrow(RemoteException.class).when(mApexService).revertActiveSessions(); 293 294 try { 295 assertThat(mApexManager.revertActiveSessions()).isFalse(); 296 } catch (Exception e) { 297 throw new AssertionError("ApexManager should not raise Exception"); 298 } 299 } 300 301 @Test testMarkStagedSessionSuccessful_throwRemoteException()302 public void testMarkStagedSessionSuccessful_throwRemoteException() throws RemoteException { 303 doThrow(RemoteException.class).when(mApexService).markStagedSessionSuccessful(anyInt()); 304 305 assertThrows(RuntimeException.class, 306 () -> mApexManager.markStagedSessionSuccessful(TEST_SESSION_ID)); 307 } 308 309 @Test testUninstallApex_throwException_returnFalse()310 public void testUninstallApex_throwException_returnFalse() throws RemoteException { 311 doAnswer(invocation -> { 312 throw new Exception(); 313 }).when(mApexService).unstagePackages(any()); 314 315 assertThat(mApexManager.uninstallApex(TEST_APEX_PKG)).isFalse(); 316 } 317 318 @Test testReportErrorWithApkInApex()319 public void testReportErrorWithApkInApex() throws RemoteException { 320 when(mApexService.getActivePackages()).thenReturn(createApexInfoForTestPkg(true, true)); 321 final ApexManager.ActiveApexInfo activeApex = mApexManager.getActiveApexInfos().get(0); 322 assertThat(activeApex.apexModuleName).isEqualTo(TEST_APEX_PKG); 323 324 ApexInfo[] apexInfo = createApexInfoForTestPkg(true, true); 325 List<ApexManager.ScanResult> scanResults = scanApexInfos(apexInfo); 326 mApexManager.notifyScanResult(scanResults); 327 328 assertThat(mApexManager.getApkInApexInstallError(activeApex.apexModuleName)).isNull(); 329 mApexManager.reportErrorWithApkInApex(activeApex.apexDirectory.getAbsolutePath(), 330 "Some random error"); 331 assertThat(mApexManager.getApkInApexInstallError(activeApex.apexModuleName)) 332 .isEqualTo("Some random error"); 333 } 334 335 /** 336 * registerApkInApex method checks if the prefix of base apk path contains the apex package 337 * name. When an apex package name is a prefix of another apex package name, e.g, 338 * com.android.media and com.android.mediaprovider, then we need to ensure apk inside apex 339 * mediaprovider does not get registered under apex media. 340 */ 341 @Test testRegisterApkInApexDoesNotRegisterSimilarPrefix()342 public void testRegisterApkInApexDoesNotRegisterSimilarPrefix() throws RemoteException { 343 when(mApexService.getActivePackages()).thenReturn(createApexInfoForTestPkg(true, true)); 344 final ApexManager.ActiveApexInfo activeApex = mApexManager.getActiveApexInfos().get(0); 345 assertThat(activeApex.apexModuleName).isEqualTo(TEST_APEX_PKG); 346 347 AndroidPackage fakeApkInApex = mock(AndroidPackage.class); 348 when(fakeApkInApex.getBaseApkPath()).thenReturn("/apex/" + TEST_APEX_PKG + "randomSuffix"); 349 when(fakeApkInApex.getPackageName()).thenReturn("randomPackageName"); 350 351 ApexInfo[] apexInfo = createApexInfoForTestPkg(true, true); 352 List<ApexManager.ScanResult> scanResults = scanApexInfos(apexInfo); 353 mApexManager.notifyScanResult(scanResults); 354 355 assertThat(mApexManager.getApksInApex(activeApex.apexModuleName)).isEmpty(); 356 mApexManager.registerApkInApex(fakeApkInApex); 357 assertThat(mApexManager.getApksInApex(activeApex.apexModuleName)).isEmpty(); 358 } 359 360 @Test testInstallPackage_activeOnSystem()361 public void testInstallPackage_activeOnSystem() throws Exception { 362 ApexInfo activeApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ true, 363 /* isFactory= */ true, extractResource("test.apex_rebootless_v1", 364 "test.rebootless_apex_v1.apex")); 365 ApexInfo[] apexInfo = new ApexInfo[]{activeApexInfo}; 366 var results = scanApexInfos(apexInfo); 367 368 File finalApex = extractResource("test.rebootles_apex_v2", "test.rebootless_apex_v2.apex"); 369 ApexInfo newApexInfo = createApexInfo("test.apex_rebootless", 2, /* isActive= */ true, 370 /* isFactory= */ false, finalApex); 371 when(mApexService.installAndActivatePackage(anyString())).thenReturn(newApexInfo); 372 373 File installedApex = extractResource("installed", "test.rebootless_apex_v2.apex"); 374 newApexInfo = mApexManager.installPackage(installedApex); 375 376 var newPkg = mockParsePackage(mPackageParser2, newApexInfo); 377 assertThat(newPkg.getBaseApkPath()).isEqualTo(finalApex.getAbsolutePath()); 378 assertThat(newPkg.getLongVersionCode()).isEqualTo(2); 379 380 var factoryPkg = mockParsePackage(mPackageParser2, 381 findFactory(results, "test.apex.rebootless").apexInfo); 382 assertThat(factoryPkg.getBaseApkPath()).isEqualTo(activeApexInfo.modulePath); 383 assertThat(factoryPkg.getLongVersionCode()).isEqualTo(1); 384 assertThat(AndroidPackageUtils.isSystem(factoryPkg)).isTrue(); 385 } 386 387 @Test testInstallPackage_activeOnData()388 public void testInstallPackage_activeOnData() throws Exception { 389 ApexInfo factoryApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ false, 390 /* isFactory= */ true, extractResource("test.apex_rebootless_v1", 391 "test.rebootless_apex_v1.apex")); 392 ApexInfo activeApexInfo = createApexInfo("test.apex_rebootless", 1, /* isActive= */ true, 393 /* isFactory= */ false, extractResource("test.apex.rebootless@1", 394 "test.rebootless_apex_v1.apex")); 395 ApexInfo[] apexInfo = new ApexInfo[]{factoryApexInfo, activeApexInfo}; 396 var results = scanApexInfos(apexInfo); 397 398 File finalApex = extractResource("test.rebootles_apex_v2", "test.rebootless_apex_v2.apex"); 399 ApexInfo newApexInfo = createApexInfo("test.apex_rebootless", 2, /* isActive= */ true, 400 /* isFactory= */ false, finalApex); 401 when(mApexService.installAndActivatePackage(anyString())).thenReturn(newApexInfo); 402 403 File installedApex = extractResource("installed", "test.rebootless_apex_v2.apex"); 404 newApexInfo = mApexManager.installPackage(installedApex); 405 406 var newPkg = mockParsePackage(mPackageParser2, newApexInfo); 407 assertThat(newPkg.getBaseApkPath()).isEqualTo(finalApex.getAbsolutePath()); 408 assertThat(newPkg.getLongVersionCode()).isEqualTo(2); 409 410 var factoryPkg = mockParsePackage(mPackageParser2, 411 findFactory(results, "test.apex.rebootless").apexInfo); 412 assertThat(factoryPkg.getBaseApkPath()).isEqualTo(factoryApexInfo.modulePath); 413 assertThat(factoryPkg.getLongVersionCode()).isEqualTo(1); 414 assertThat(AndroidPackageUtils.isSystem(factoryPkg)).isTrue(); 415 } 416 417 @Test testInstallPackageBinderCallFails()418 public void testInstallPackageBinderCallFails() throws Exception { 419 when(mApexService.installAndActivatePackage(anyString())).thenThrow( 420 new RuntimeException("install failed :(")); 421 422 File installedApex = extractResource("test.apex_rebootless_v1", 423 "test.rebootless_apex_v1.apex"); 424 assertThrows(PackageManagerException.class, 425 () -> mApexManager.installPackage(installedApex)); 426 } 427 428 @Test testGetActivePackageNameForApexModuleName()429 public void testGetActivePackageNameForApexModuleName() { 430 final String moduleName = "com.android.module_name"; 431 432 ApexInfo[] apexInfo = createApexInfoForTestPkg(true, false); 433 apexInfo[0].moduleName = moduleName; 434 List<ApexManager.ScanResult> scanResults = scanApexInfos(apexInfo); 435 mApexManager.notifyScanResult(scanResults); 436 437 assertThat(mApexManager.getActivePackageNameForApexModuleName(moduleName)) 438 .isEqualTo(TEST_APEX_PKG); 439 } 440 441 @Test testGetBackingApexFiles()442 public void testGetBackingApexFiles() throws Exception { 443 final ApexInfo apex = createApexInfoForTestPkg(true, true, 37); 444 when(mApexService.getActivePackages()).thenReturn(new ApexInfo[]{apex}); 445 446 final File backingApexFile = mApexManager.getBackingApexFile( 447 new File(mMockSystem.system().getApexDirectory(), 448 TEST_APEX_PKG + "/apk/App/App.apk")); 449 assertThat(backingApexFile.getAbsolutePath()).isEqualTo(apex.modulePath); 450 } 451 452 @Test testGetBackingApexFile_fileNotOnApexMountPoint_returnsNull()453 public void testGetBackingApexFile_fileNotOnApexMountPoint_returnsNull() { 454 File result = mApexManager.getBackingApexFile( 455 new File("/data/local/tmp/whatever/does-not-matter")); 456 assertThat(result).isNull(); 457 } 458 459 @Test testGetBackingApexFiles_unknownApex_returnsNull()460 public void testGetBackingApexFiles_unknownApex_returnsNull() throws Exception { 461 final ApexInfo apex = createApexInfoForTestPkg(true, true, 37); 462 when(mApexService.getActivePackages()).thenReturn(new ApexInfo[]{apex}); 463 464 final File backingApexFile = mApexManager.getBackingApexFile( 465 new File(mMockSystem.system().getApexDirectory(), "com.wrong.apex/apk/App")); 466 assertThat(backingApexFile).isNull(); 467 } 468 469 @Test testGetBackingApexFiles_topLevelApexDir_returnsNull()470 public void testGetBackingApexFiles_topLevelApexDir_returnsNull() { 471 assertThat(mApexManager.getBackingApexFile(Environment.getApexDirectory())).isNull(); 472 assertThat(mApexManager.getBackingApexFile(new File("/apex/"))).isNull(); 473 assertThat(mApexManager.getBackingApexFile(new File("/apex//"))).isNull(); 474 } 475 476 @Test testGetBackingApexFiles_flattenedApex()477 public void testGetBackingApexFiles_flattenedApex() { 478 ApexManager flattenedApexManager = new ApexManager.ApexManagerFlattenedApex(); 479 final File backingApexFile = flattenedApexManager.getBackingApexFile( 480 new File(mMockSystem.system().getApexDirectory(), 481 "com.android.apex.cts.shim/app/CtsShim/CtsShim.apk")); 482 assertThat(backingApexFile).isNull(); 483 } 484 485 @Test testActiveApexChanged()486 public void testActiveApexChanged() throws RemoteException { 487 ApexInfo apex1 = createApexInfo( 488 "com.apex1", 37, true, true, new File("/data/apex/active/com.apex@37.apex")); 489 apex1.activeApexChanged = true; 490 apex1.preinstalledModulePath = apex1.modulePath; 491 when(mApexService.getActivePackages()).thenReturn(new ApexInfo[]{apex1}); 492 final ApexManager.ActiveApexInfo activeApex = mApexManager.getActiveApexInfos().get(0); 493 assertThat(activeApex.apexModuleName).isEqualTo("com.apex1"); 494 assertThat(activeApex.activeApexChanged).isTrue(); 495 } 496 createApexInfoForTestPkg(boolean isActive, boolean isFactory, int version)497 private ApexInfo createApexInfoForTestPkg(boolean isActive, boolean isFactory, int version) { 498 File apexFile = extractResource(TEST_APEX_PKG, TEST_APEX_FILE_NAME); 499 ApexInfo apexInfo = new ApexInfo(); 500 apexInfo.isActive = isActive; 501 apexInfo.isFactory = isFactory; 502 apexInfo.moduleName = TEST_APEX_PKG; 503 apexInfo.modulePath = apexFile.getPath(); 504 apexInfo.versionCode = version; 505 apexInfo.preinstalledModulePath = apexFile.getPath(); 506 return apexInfo; 507 } 508 createApexInfoForTestPkg(boolean isActive, boolean isFactory)509 private ApexInfo[] createApexInfoForTestPkg(boolean isActive, boolean isFactory) { 510 return new ApexInfo[]{createApexInfoForTestPkg(isActive, isFactory, 191000070)}; 511 } 512 createApexInfo(String moduleName, int versionCode, boolean isActive, boolean isFactory, File apexFile)513 private ApexInfo createApexInfo(String moduleName, int versionCode, boolean isActive, 514 boolean isFactory, File apexFile) { 515 ApexInfo apexInfo = new ApexInfo(); 516 apexInfo.moduleName = moduleName; 517 apexInfo.versionCode = versionCode; 518 apexInfo.isActive = isActive; 519 apexInfo.isFactory = isFactory; 520 apexInfo.modulePath = apexFile.getPath(); 521 apexInfo.preinstalledModulePath = apexFile.getPath(); 522 return apexInfo; 523 } 524 getFakeStagedSessionInfo()525 private ApexSessionInfo getFakeStagedSessionInfo() { 526 ApexSessionInfo stagedSessionInfo = new ApexSessionInfo(); 527 stagedSessionInfo.sessionId = TEST_SESSION_ID; 528 stagedSessionInfo.isStaged = true; 529 530 return stagedSessionInfo; 531 } 532 getFakeUnknownSessionInfo()533 private ApexSessionInfo getFakeUnknownSessionInfo() { 534 ApexSessionInfo stagedSessionInfo = new ApexSessionInfo(); 535 stagedSessionInfo.sessionId = TEST_SESSION_ID; 536 stagedSessionInfo.isUnknown = true; 537 538 return stagedSessionInfo; 539 } 540 testParamsWithChildren()541 private static ApexSessionParams testParamsWithChildren() { 542 ApexSessionParams params = new ApexSessionParams(); 543 params.sessionId = TEST_SESSION_ID; 544 params.childSessionIds = TEST_CHILD_SESSION_ID; 545 return params; 546 } 547 548 // Extracts the binary data from a resource and writes it to a temp file extractResource(String baseName, String fullResourceName)549 private static File extractResource(String baseName, String fullResourceName) { 550 File file; 551 try { 552 file = File.createTempFile(baseName, ".apex"); 553 } catch (IOException e) { 554 throw new AssertionError("CreateTempFile IOException" + e); 555 } 556 557 try ( 558 InputStream in = ApexManager.class.getClassLoader() 559 .getResourceAsStream(fullResourceName); 560 OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { 561 if (in == null) { 562 throw new IllegalArgumentException("Resource not found: " + fullResourceName); 563 } 564 byte[] buf = new byte[65536]; 565 int chunkSize; 566 while ((chunkSize = in.read(buf)) != -1) { 567 out.write(buf, 0, chunkSize); 568 } 569 return file; 570 } catch (IOException e) { 571 throw new AssertionError("Exception while converting stream to file" + e); 572 } 573 } 574 } 575