Test apps could opt out the update ownership

Bug: 244413073
Test: atest CtsPackageInstallTestCases:UpdateOwnershipEnforcementTest
Change-Id: I3272f81eaf88088529ad3a574e87d65bb590b49f
diff --git a/tests/tests/packageinstaller/install/Android.bp b/tests/tests/packageinstaller/install/Android.bp
index aae1e0b..beb16f7 100644
--- a/tests/tests/packageinstaller/install/Android.bp
+++ b/tests/tests/packageinstaller/install/Android.bp
@@ -43,6 +43,7 @@
     data: [
         ":CtsEmptyTestApp",
         ":CtsEmptyInstallerApp",
+        ":CtsEmptyTestApp_NotAllowUpdateOwnership",
     ],
     per_testcase_directory: true,
 }
diff --git a/tests/tests/packageinstaller/install/AndroidTest.xml b/tests/tests/packageinstaller/install/AndroidTest.xml
index 0926c9d..df5f553 100644
--- a/tests/tests/packageinstaller/install/AndroidTest.xml
+++ b/tests/tests/packageinstaller/install/AndroidTest.xml
@@ -38,6 +38,7 @@
         <option name="push" value="CtsEmptyTestApp.apk->/data/local/tmp/cts/packageinstaller/CtsEmptyTestApp.apk" />
         <option name="push" value="CtsEmptyTestApp_pl.apk->/data/local/tmp/cts/packageinstaller/CtsEmptyTestApp_pl.apk" />
         <option name="push" value="CtsEmptyInstallerApp.apk->/data/local/tmp/cts/packageinstaller/CtsEmptyInstallerApp.apk" />
+        <option name="push" value="CtsEmptyTestApp_NotAllowUpdateOwnership.apk->/data/local/tmp/cts/packageinstaller/CtsEmptyTestApp_NotAllowUpdateOwnership.apk" />
     </target_preparer>
 
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UpdateOwnershipEnforcementTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UpdateOwnershipEnforcementTest.kt
index f0e38fb..8179d1b 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UpdateOwnershipEnforcementTest.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UpdateOwnershipEnforcementTest.kt
@@ -21,6 +21,7 @@
 import android.platform.test.annotations.AppModeFull
 import androidx.test.InstrumentationRegistry
 import androidx.test.runner.AndroidJUnit4
+import java.io.File
 import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
@@ -33,11 +34,18 @@
 class UpdateOwnershipEnforcementTest : PackageInstallerTestBase() {
 
     companion object {
+        const val TEST_NOT_ALLOW_UPDATE_OWNERSHIP_APK_NAME =
+                "CtsEmptyTestApp_NotAllowUpdateOwnership.apk"
+
         const val TEST_INSTALLER_APK_NAME = "CtsEmptyInstallerApp.apk"
         const val TEST_INSTALLER_APK_PACKAGE_NAME = "android.packageinstaller.emptyinstaller.cts"
     }
 
     private var isUpdateOwnershipEnforcementAvailable: String? = null
+    private val notAllowUpdateOwnershipApkFile = File(
+            context.filesDir,
+            TEST_NOT_ALLOW_UPDATE_OWNERSHIP_APK_NAME
+    )
 
     /**
      * Make sure the feature flag of update ownership enforcement is available.
@@ -403,4 +411,34 @@
         // request should have succeeded
         getInstallSessionResult()
     }
+
+    /**
+     * Checks that the app can opt out the update ownership via manifest attr.
+     */
+    @Test
+    fun allowUpdateOwnership_shouldRemoveUpdateOwner() {
+        copyTestNotAllowUpdateOwnershipApk()
+        installTestPackage("--update-ownership -i $TEST_INSTALLER_APK_PACKAGE_NAME")
+        var sourceInfo = pm.getInstallSourceInfo(TEST_APK_PACKAGE_NAME)
+        assertEquals(TEST_INSTALLER_APK_PACKAGE_NAME, sourceInfo.updateOwnerPackageName)
+
+        startInstallationViaSession(
+                0 /* installFlags */,
+                TEST_NOT_ALLOW_UPDATE_OWNERSHIP_APK_NAME
+        )
+        clickInstallerUIButton(INSTALL_BUTTON_ID)
+
+        val result = getInstallSessionResult()
+        assertEquals(PackageInstaller.STATUS_SUCCESS, result.status)
+
+        sourceInfo = pm.getInstallSourceInfo(TEST_APK_PACKAGE_NAME)
+        assertEquals(null, sourceInfo.updateOwnerPackageName)
+    }
+
+    private fun copyTestNotAllowUpdateOwnershipApk() {
+        File(
+                TEST_APK_LOCATION,
+                TEST_NOT_ALLOW_UPDATE_OWNERSHIP_APK_NAME
+        ).copyTo(target = notAllowUpdateOwnershipApkFile, overwrite = true)
+    }
 }
diff --git a/tests/tests/packageinstaller/test-apps/emptytestapp/Android.bp b/tests/tests/packageinstaller/test-apps/emptytestapp/Android.bp
index 481f517..3fb95ce 100644
--- a/tests/tests/packageinstaller/test-apps/emptytestapp/Android.bp
+++ b/tests/tests/packageinstaller/test-apps/emptytestapp/Android.bp
@@ -31,3 +31,16 @@
     // Generate a locale split.
     package_splits: ["pl"],
 }
+
+android_test_helper_app {
+    name: "CtsEmptyTestApp_NotAllowUpdateOwnership",
+    defaults: ["cts_defaults"],
+    manifest: "AndroidManifest_notAllowUpdateOwnership.xml",
+    sdk_version: "current",
+    min_sdk_version: "23",
+    // tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+}
diff --git a/tests/tests/packageinstaller/test-apps/emptytestapp/AndroidManifest_notAllowUpdateOwnership.xml b/tests/tests/packageinstaller/test-apps/emptytestapp/AndroidManifest_notAllowUpdateOwnership.xml
new file mode 100644
index 0000000..a66c4fc
--- /dev/null
+++ b/tests/tests/packageinstaller/test-apps/emptytestapp/AndroidManifest_notAllowUpdateOwnership.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.packageinstaller.emptytestapp.cts"
+          android:allowUpdateOwnership="false" >
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="26"/>
+
+    <application android:hasCode="false"
+                 android:label="@string/app_name"
+    />
+
+</manifest>