1 /* 2 * Copyright (C) 2018 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 package android.packageinstaller.install.cts 17 18 import android.app.Activity.RESULT_CANCELED 19 import android.app.Activity.RESULT_OK 20 import android.content.Intent 21 import android.content.pm.InstallSourceInfo 22 import android.net.Uri 23 import android.platform.test.annotations.AppModeFull 24 import androidx.test.runner.AndroidJUnit4 25 import java.util.concurrent.TimeUnit 26 import org.junit.After 27 import org.junit.Assert.assertEquals 28 import org.junit.Test 29 import org.junit.runner.RunWith 30 31 @RunWith(AndroidJUnit4::class) 32 @AppModeFull(reason = "Instant apps cannot install packages") 33 class IntentTest : PackageInstallerTestBase() { 34 35 companion object { 36 // An invalid package name that exceeds the maximum file name length. 37 const val LONG_PACKAGE_NAME = "android.packageinstaller.install.cts.invalidname." + 38 "27jEBRNRG3ozwBsGr1sVIM9U0bVTI2TdyIyeRkZgW4JrJefwNIBAmCg4AzqXiCvG6JjqA0u" + 39 "TCWSFu2YqAVxVdiRKAay19k5VFlSaM7QW9uhvlrLQqsTW01ofFzxNDbp2QfIFHZR6rebKzK" + 40 "Bz6byQFM0DYQnYMwFWXjWkMPNdqkRLykoFLyBup53G68k2n8wl27jEBRNRG3ozwBsGr" 41 } 42 43 @After disableSecureFrpnull44 fun disableSecureFrp() { 45 setSecureFrp(false) 46 } 47 48 /** 49 * Check that we can install an app via a package-installer intent 50 */ 51 @Test confirmInstallationnull52 fun confirmInstallation() { 53 val installation = startInstallationViaIntent() 54 clickInstallerUIButton(INSTALL_BUTTON_ID) 55 56 // Install should have succeeded 57 assertEquals(RESULT_OK, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 58 assertInstalled() 59 } 60 61 /** 62 * Install an app via a package-installer intent, but then cancel it when the package installer 63 * pops open. 64 */ 65 @Test cancelInstallationnull66 fun cancelInstallation() { 67 val installation = startInstallationViaIntent() 68 clickInstallerUIButton(CANCEL_BUTTON_ID) 69 70 // Install should have been aborted 71 assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 72 assertNotInstalled() 73 } 74 75 /** 76 * Install an app via a package-installer intent, and assign itself as the installer. 77 */ 78 @Test installWithCallingInstallerPackageNamenull79 fun installWithCallingInstallerPackageName() { 80 val intent = getInstallationIntent() 81 intent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, context.opPackageName) 82 val installation = startInstallationViaIntent(intent) 83 clickInstallerUIButton(INSTALL_BUTTON_ID) 84 85 // Install should have succeeded, and system will use the given installer package name 86 // in EXTRA_INSTALLER_PACKAGE_NAME as the installer. 87 assertEquals(RESULT_OK, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 88 assertEquals(context.opPackageName, getInstallSourceInfo().installingPackageName) 89 } 90 91 /** 92 * Install an app via a package-installer intent, but assign another package as installer 93 * package name. 94 */ 95 @Test installWithAnotherInstallerPackageNamenull96 fun installWithAnotherInstallerPackageName() { 97 val intent = getInstallationIntent() 98 intent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, context.opPackageName + ".another") 99 val installation = startInstallationViaIntent(intent) 100 clickInstallerUIButton(INSTALL_BUTTON_ID) 101 102 // Install should have succeeded, but system won't use the given installer package name 103 // in EXTRA_INSTALLER_PACKAGE_NAME as the installer. 104 assertEquals(RESULT_OK, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 105 assertEquals(getInstallSourceInfo().initiatingPackageName, 106 getInstallSourceInfo().installingPackageName) 107 } 108 109 /** 110 * Install an app via a package-installer intent, but assign an invalid installer 111 * package name which exceeds the maximum file name length. 112 */ 113 @Test installWithLongInstallerPackageNamenull114 fun installWithLongInstallerPackageName() { 115 val intent = getInstallationIntent() 116 intent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, LONG_PACKAGE_NAME) 117 val installation = startInstallationViaIntent(intent) 118 clickInstallerUIButton(INSTALL_BUTTON_ID) 119 120 // Install should have succeeded, but system won't use the given installer package name 121 // in EXTRA_INSTALLER_PACKAGE_NAME as the installer. 122 assertEquals(RESULT_OK, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 123 assertEquals(getInstallSourceInfo().initiatingPackageName, 124 getInstallSourceInfo().installingPackageName) 125 } 126 127 /** 128 * Make sure that an already installed app can be reinstalled via a "package" uri 129 */ 130 @Test reinstallViaPackageUrinull131 fun reinstallViaPackageUri() { 132 // Regular install 133 confirmInstallation() 134 135 // Reinstall 136 val intent = Intent(Intent.ACTION_INSTALL_PACKAGE) 137 intent.data = Uri.fromParts("package", TEST_APK_PACKAGE_NAME, null) 138 intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) 139 intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION 140 141 val reinstall = installDialogStarter.activity.startActivityForResult(intent) 142 143 clickInstallerUIButton(INSTALL_BUTTON_ID) 144 145 // Install should have succeeded 146 assertEquals(RESULT_OK, reinstall.get(TIMEOUT, TimeUnit.MILLISECONDS)) 147 assertInstalled() 148 } 149 150 /** 151 * Check that we can't install an app via a package-installer intent if Secure FRP is enabled 152 */ 153 @Test packageNotInstalledSecureFrpnull154 fun packageNotInstalledSecureFrp() { 155 setSecureFrp(true) 156 try { 157 val installation = startInstallationViaIntent() 158 clickInstallerUIButton(INSTALL_BUTTON_ID) 159 160 // Install should not have succeeded 161 assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 162 assertNotInstalled() 163 } finally { 164 setSecureFrp(false) 165 } 166 } 167 getInstallSourceInfonull168 private fun getInstallSourceInfo(): InstallSourceInfo { 169 return pm.getInstallSourceInfo(TEST_APK_PACKAGE_NAME) 170 } 171 } 172