• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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