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.content.pm.ApplicationInfo.CATEGORY_MAPS 20 import android.content.pm.ApplicationInfo.CATEGORY_UNDEFINED 21 import android.content.pm.PackageInstaller.STATUS_FAILURE_ABORTED 22 import android.content.pm.PackageInstaller.STATUS_SUCCESS 23 import android.platform.test.annotations.AppModeFull 24 import androidx.test.InstrumentationRegistry 25 import androidx.test.runner.AndroidJUnit4 26 import com.android.compatibility.common.util.AppOpsUtils 27 import org.junit.Assert.assertEquals 28 import org.junit.Assert.assertTrue 29 import org.junit.Assert.fail 30 import org.junit.Rule 31 import org.junit.Test 32 import org.junit.runner.RunWith 33 import java.util.concurrent.TimeUnit 34 35 private const val INSTALL_BUTTON_ID = "button1" 36 private const val CANCEL_BUTTON_ID = "button2" 37 38 @AppModeFull(reason = "Instant apps cannot create installer sessions") 39 @RunWith(AndroidJUnit4::class) 40 class SessionTest : PackageInstallerTestBase() { 41 private val context = InstrumentationRegistry.getTargetContext() 42 private val pm = context.packageManager 43 44 @get:Rule 45 val excludeWatch = ExcludeWatch("Installing APKs not supported on watch", pm) 46 47 /** 48 * Check that we can install an app via a package-installer session 49 */ 50 @Test confirmInstallationnull51 fun confirmInstallation() { 52 val installation = startInstallationViaSession() 53 clickInstallerUIButton(INSTALL_BUTTON_ID) 54 55 // Install should have succeeded 56 assertEquals(STATUS_SUCCESS, getInstallSessionResult()) 57 assertInstalled() 58 59 // Even when the install succeeds the install confirm dialog returns 'canceled' 60 assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 61 62 assertTrue(AppOpsUtils.allowedOperationLogged(context.packageName, APP_OP_STR)) 63 } 64 65 /** 66 * Check that we can set an app category for an app we installed 67 */ 68 @Test setAppCategorynull69 fun setAppCategory() { 70 val installation = startInstallationViaSession() 71 clickInstallerUIButton(INSTALL_BUTTON_ID) 72 73 // Wait for installation to finish 74 getInstallSessionResult() 75 76 assertEquals(CATEGORY_UNDEFINED, pm.getApplicationInfo(TEST_APK_PACKAGE_NAME, 0).category) 77 78 // This app installed the app, hence we can set the category 79 pm.setApplicationCategoryHint(TEST_APK_PACKAGE_NAME, CATEGORY_MAPS) 80 81 assertEquals(CATEGORY_MAPS, pm.getApplicationInfo(TEST_APK_PACKAGE_NAME, 0).category) 82 } 83 84 /** 85 * Install an app via a package-installer session, but then cancel it when the package installer 86 * pops open. 87 */ 88 @Test cancelInstallationnull89 fun cancelInstallation() { 90 val installation = startInstallationViaSession() 91 clickInstallerUIButton(CANCEL_BUTTON_ID) 92 93 // Install should have been aborted 94 assertEquals(STATUS_FAILURE_ABORTED, getInstallSessionResult()) 95 assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS)) 96 assertNotInstalled() 97 } 98 99 /** 100 * Check that can't install when FRP mode is enabled. 101 */ 102 @Test confirmFrpInstallationFailsnull103 fun confirmFrpInstallationFails() { 104 try { 105 setSecureFrp(true) 106 107 try { 108 val installation = startInstallationViaSession() 109 clickInstallerUIButton(CANCEL_BUTTON_ID) 110 111 fail("Package should not be installed") 112 } catch (expected: SecurityException) { 113 } 114 115 // Install should never have started 116 assertNotInstalled() 117 } finally { 118 setSecureFrp(false) 119 } 120 } 121 122 /** 123 * Check that can't install Instant App when installer don't have proper permission. 124 */ 125 @Test confirmInstantInstallationFailsnull126 fun confirmInstantInstallationFails() { 127 try { 128 val installation = startInstallationViaSession(INSTALL_INSTANT_APP) 129 clickInstallerUIButton(CANCEL_BUTTON_ID) 130 131 fail("Expected security exception on instant install from non-system app") 132 } catch (expected: SecurityException) { 133 // Expected 134 } 135 136 // Install should never have started 137 assertNotInstalled() 138 } 139 } 140