Renable SDK apk installation test and refactor InstallVariantTask

* Adds logging for privacy sandbox sdk apk installation
* Avoids using the BuiltArtifactsLoader
* Re-enables SDK installation test

Bug: 303076495
Test: InstallVariantTaskTest.checkDependencyApkInstallation
Change-Id: I5fb2a3abea85d4cd20557b0e802de8d3518b5424
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/InstallVariantTask.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/InstallVariantTask.java
index 56aa1a6..f0e277d 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/InstallVariantTask.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/InstallVariantTask.java
@@ -178,6 +178,12 @@
                                                 .map(Path::toFile)
                                                 .collect(Collectors.toUnmodifiableList());
                                 try {
+                                    logger.lifecycle(
+                                            "Installing Privacy Sandbox APK '{}' on '{}' for {}:{}",
+                                            FileUtils.getNamesAsCommaSeparatedList(sdkApkFiles),
+                                            device.getName(),
+                                            projectPath,
+                                            variantName);
                                     device.installPackages(
                                             sdkApkFiles, extraArgs, timeOutInMs, iLogger);
                                 } catch (DeviceException e) {
@@ -189,30 +195,23 @@
                                 }
                             });
                     if (additionalSupportedSdkApkSplits.isPresent()) {
-                        BuiltArtifactsImpl privacySandboxSupportedApkSplitsBuiltArtifacts =
-                                new BuiltArtifactsLoaderImpl()
-                                        .load(additionalSupportedSdkApkSplits);
-                        if (privacySandboxSupportedApkSplitsBuiltArtifacts != null) {
-                            for (BuiltArtifactImpl split
-                                    : privacySandboxSupportedApkSplitsBuiltArtifacts.getElements()) {
-                                apkFiles.add(new File(split.getOutputFile()));
-                            }
-                        }
+                        List<File> splitApks = additionalSupportedSdkApkSplits.get()
+                                .getAsFileTree()
+                                .getFiles()
+                                .stream()
+                                .filter(file -> file.getName().endsWith(SdkConstants.DOT_ANDROID_PACKAGE))
+                                .collect(Collectors.toList());
+                        apkFiles.addAll(splitApks);
                     }
-                }
-
-                BuiltArtifactsImpl privacySandboxLegacySplitbuiltArtifacts = null;
-                if (privacySandboxSdkSplitApksForLegacy.getOrNull() != null) {
-                    privacySandboxLegacySplitbuiltArtifacts =
-                            new BuiltArtifactsLoaderImpl()
-                                    .load(privacySandboxSdkSplitApksForLegacy);
-                }
-
-                if (!device.getSupportsPrivacySandbox()
-                        && privacySandboxLegacySplitbuiltArtifacts != null) {
-                    for (BuiltArtifactImpl sdkBuiltArtifact :
-                            privacySandboxLegacySplitbuiltArtifacts.getElements()) {
-                        apkFiles.add(new File(sdkBuiltArtifact.getOutputFile()));
+                } else {
+                    if (privacySandboxSdkSplitApksForLegacy.isPresent()) {
+                        List<File> splitApks = privacySandboxSdkSplitApksForLegacy.get()
+                                .getAsFileTree()
+                                .getFiles()
+                                .stream()
+                                .filter(file -> file.getName().endsWith(SdkConstants.DOT_ANDROID_PACKAGE))
+                                .collect(Collectors.toList());
+                        apkFiles.addAll(splitApks);
                     }
                 }
 
diff --git a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/tasks/InstallVariantTaskTest.kt b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/tasks/InstallVariantTaskTest.kt
index 6312f63..e06f5f8 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/tasks/InstallVariantTaskTest.kt
+++ b/build-system/gradle-core/src/test/java/com/android/build/gradle/internal/tasks/InstallVariantTaskTest.kt
@@ -16,9 +16,9 @@
 package com.android.build.gradle.internal.tasks
 
 import com.android.build.api.variant.impl.BuiltArtifactsImpl
-import com.android.build.gradle.internal.fixtures.FakeFileCollection
 import com.android.build.gradle.internal.fixtures.FakeGradleDirectory
 import com.android.build.gradle.internal.fixtures.FakeGradleDirectoryProperty
+import com.android.build.gradle.internal.fixtures.FakeLogger
 import com.android.builder.testing.api.DeviceConnector
 import com.android.builder.testing.api.DeviceProvider
 import com.android.ddmlib.AndroidDebugBridge
@@ -26,25 +26,28 @@
 import com.android.fakeadbserver.DeviceState
 import com.android.fakeadbserver.services.PackageManager
 import com.android.sdklib.AndroidVersion
+import com.android.testutils.MockLog
 import com.android.utils.StdLogger
 import com.google.common.collect.ImmutableList
 import com.google.common.collect.ImmutableSet
+import com.google.common.truth.Truth.assertThat
 import org.gradle.api.logging.Logger
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.TemporaryFolder
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
-import org.mockito.ArgumentMatchers
 import org.mockito.Mock
 import org.mockito.Mockito
-import org.mockito.internal.verification.VerificationModeFactory.times
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
+import java.io.BufferedOutputStream
 import java.io.File
+import java.io.FileOutputStream
 import java.util.concurrent.TimeUnit
+import java.util.zip.ZipEntry
+import java.util.zip.ZipOutputStream
 
 @RunWith(Parameterized::class)
 class InstallVariantTaskTest(private val deviceVersion: AndroidVersion) {
@@ -67,25 +70,29 @@
     @Rule
     var temporaryFolder = TemporaryFolder()
 
-    @Mock
-    lateinit var logger: Logger
+    lateinit var logger: FakeLogger
 
     @get:Rule
     val fakeAdb = FakeAdbTestRule(deviceVersion)
 
+    @Mock
     private lateinit var deviceConnector: DeviceConnector
     private lateinit var deviceState: DeviceState
     private lateinit var mainOutputFileApk: File
 
+    private var sandboxSupported: Boolean = false
+
     lateinit var privacySandboxLegacyApkSplitsDirectory: File
 
     @Before
     fun setUp() {
         deviceState = fakeAdb.connectAndWaitForDevice()
         deviceState.setActivityManager(PackageManager())
-        if (deviceVersion.apiLevel >= 34) {
+        sandboxSupported = deviceVersion.apiLevel >= 34
+        if (sandboxSupported) {
             deviceState.serviceManager.setService("sdk_sandbox") { _, _ -> }
         }
+        logger = FakeLogger()
         val device = AndroidDebugBridge.getBridge()!!.devices.single()
         deviceConnector = CustomConnectedDevice(
                 device,
@@ -93,6 +100,7 @@
                 10000,
                 TimeUnit.MILLISECONDS,
                 deviceVersion)
+
         privacySandboxLegacyApkSplitsDirectory = temporaryFolder.newFolder("privacysandbox-legacy-split-apks")
     }
 
@@ -104,18 +112,17 @@
 
     @Test
     @Throws(Exception::class)
-    @Ignore("b/303076495") // Won't pass because the privacy sandbox sdk .apks file is not set up correctly.
     fun checkDependencyApkInstallation() {
         createMainApkListingFile()
-        val listingFile = createDependencyApkListingFile()
+        val splitApk = getSdkSupportSplitApk()
         InstallVariantTask.install(
             "project",
             "variant",
             FakeDeviceProvider(ImmutableList.of(deviceConnector)),
             AndroidVersion.DEFAULT,
             FakeGradleDirectory(temporaryFolder.root),
-            ImmutableSet.of(listingFile),
-            FakeGradleDirectoryProperty(null),
+            getPrivacySandboxSdkApks(),
+            FakeGradleDirectoryProperty(FakeGradleDirectory(splitApk)),
             FakeGradleDirectoryProperty(FakeGradleDirectory(privacySandboxLegacyApkSplitsDirectory)),
             ImmutableSet.of(),
             ImmutableList.of(),
@@ -123,32 +130,30 @@
             logger,
             FakeGradleDirectoryProperty(null),
         )
-        Mockito.verify(logger, times(3)).quiet("Installed on {} {}.", 1, "device")
-        Mockito.verify(deviceConnector, Mockito.atLeastOnce()).name
-        Mockito.verify(deviceConnector, Mockito.atLeastOnce()).apiLevel
-        Mockito.verify(deviceConnector, Mockito.atLeastOnce()).abis
-        Mockito.verify(deviceConnector, Mockito.atLeastOnce()).deviceConfig
-        val inOrder = Mockito.inOrder(deviceConnector)
 
-        inOrder.verify(deviceConnector).installPackage(
-            ArgumentMatchers.eq(temporaryFolder.newFolder("apks").resolve("dependency1.apk")),
-            ArgumentMatchers.any(),
-            ArgumentMatchers.anyInt(),
-            ArgumentMatchers.any()
-        )
-        inOrder.verify(deviceConnector).installPackage(
-            ArgumentMatchers.eq(temporaryFolder.root.resolve("dependency2.apk")),
-            ArgumentMatchers.any(),
-            ArgumentMatchers.anyInt(),
-            ArgumentMatchers.any()
-        )
-        inOrder.verify(deviceConnector).installPackage(
-            ArgumentMatchers.eq(temporaryFolder.root.resolve("main.apk")),
-            ArgumentMatchers.any(),
-            ArgumentMatchers.anyInt(),
-            ArgumentMatchers.any()
-        )
-        Mockito.verifyNoMoreInteractions(deviceConnector)
+
+        val packageInstalls =
+            deviceState.abbLogs.filter { it.startsWith("package\u0000install-write") }
+        if (sandboxSupported) {
+            assertThat(logger.lifeCycles).containsExactly(
+                "Installing Privacy Sandbox APK '{}' on '{}' for {}:{}",
+                "Installing Privacy Sandbox APK '{}' on '{}' for {}:{}",
+                "Installing APK '{}' on '{}' for {}:{}"
+            )
+            assertThat(packageInstalls.count()).isEqualTo(2)
+        } else {
+            assertThat(logger.lifeCycles).containsExactly(
+                "Installing APK '{}' on '{}' for {}:{}")
+            assertThat(packageInstalls.count()).isEqualTo(0)
+        }
+        assertThat(deviceState.pmLogs)
+            .containsExactly("install -r -t \"/data/local/tmp/main.apk\"")
+    }
+
+    private fun getSdkSupportSplitApk(): File {
+        val privacySandboxSupportSplit =
+            temporaryFolder.newFolder("privacy-sandobox-support-split")
+        return File(privacySandboxSupportSplit, "sdk-support.apk")
     }
 
     private fun checkSingleApk(deviceConnector: DeviceConnector) {
@@ -171,16 +176,8 @@
         assert(deviceState.pmLogs.any {
             it.startsWith("install -r -t") && it.contains("main.apk")
         })
-
-        Mockito.verify(logger)
-                .lifecycle(
-                        "Installing APK '{}' on '{}' for {}:{}",
-                        "main.apk",
-                        deviceConnector.name,
-                        "project",
-                        "variant"
-                )
-        Mockito.verify(logger).quiet("Installed on {} {}.", 1, "device")
+        assertThat(logger.quiets)
+            .containsExactly("Installed on {} {}.")
     }
 
     internal class FakeDeviceProvider(private val devices: List<DeviceConnector>) : DeviceProvider() {
@@ -230,47 +227,20 @@
 }""", Charsets.UTF_8)
     }
 
-    private fun createDependencyApkListingFile(): File {
-        val dependencyApk1 = temporaryFolder.newFile("dependency1.apk")
-        val dependencyApk2 = temporaryFolder.newFile("dependency2.apk")
-        return temporaryFolder.newFile("dependencyApkListingFile.txt").also {
-            it.writeText("""
-[{
-  "version": 1,
-  "artifactType": {
-    "type": "APK",
-    "kind": "Directory"
-  },
-  "applicationId": "com.android.test1",
-  "variantName": "debug",
-  "elements": [
-    {
-      "type": "SINGLE",
-      "filters": [],
-      "versionCode": 123,
-      "versionName": "version_name",
-      "outputFile": "${dependencyApk1.name}"
-    }
-  ]
-},{
-  "version": 1,
-  "artifactType": {
-    "type": "APK",
-    "kind": "Directory"
-  },
-  "applicationId": "com.android.test2",
-  "variantName": "debug",
-  "elements": [
-    {
-      "type": "SINGLE",
-      "filters": [],
-      "versionCode": 123,
-      "versionName": "version_name",
-      "outputFile": "${dependencyApk2.name}"
-    }
-  ]
-}]""", Charsets.UTF_8)
+    private fun getPrivacySandboxSdkApks(): Set<File> {
+        val sdkApkDir = temporaryFolder.newFolder("sdkApks")
+        val sdkApks = listOf(
+            File(sdkApkDir, "sdkApk1.zip"),
+            File(sdkApkDir, "sdkApk2.zip")
+        )
+        sdkApks.forEach { zip ->
+            ZipOutputStream(BufferedOutputStream(FileOutputStream(zip))).use { instrumentedJar ->
+                val standalonesDir = ZipEntry("standalones/standalone.apk")
+                instrumentedJar.putNextEntry(standalonesDir)
+                instrumentedJar.closeEntry()
+            }
         }
+        return sdkApks.toSet()
     }
 
 }