Loading core/tests/PackageInstallerSessions/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ android_test { "framework-res", ], java_resources: [ // Borrow an arbitrary test app from another module ":PackageManagerTestAppVersion1", ], platform_apis: true, sdk_version: "core_platform", test_suites: ["device-tests"], Loading core/tests/PackageInstallerSessions/src/android/content/pm/PackageSessionTests.kt +73 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,12 @@ package android.content.pm import android.app.Instrumentation import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.pm.PackageInstaller.SessionParams import android.platform.test.annotations.Presubmit import androidx.test.InstrumentationRegistry Loading @@ -27,6 +32,8 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.testng.Assert.assertThrows import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.TimeUnit import kotlin.random.Random /** Loading @@ -53,15 +60,49 @@ class PackageSessionTests { "android.permission.WRITE_CALL_LOG", "android.permission.PROCESS_OUTGOING_CALLS" ) private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app" private const val INTENT_ACTION = "com.android.server.pm.test.test_app.action" } private val context: Context = InstrumentationRegistry.getContext() private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val installer = context.packageManager.packageInstaller private val receiver = object : BroadcastReceiver() { private val results = ArrayBlockingQueue<Intent>(1) override fun onReceive(context: Context, intent: Intent) { results.add(intent) } fun makeIntentSender(sessionId: Int) = PendingIntent.getBroadcast(context, sessionId, Intent(INTENT_ACTION), PendingIntent.FLAG_UPDATE_CURRENT).intentSender fun getResult(unit: TimeUnit, timeout: Long) = results.poll(timeout, unit) fun clear() = results.clear() } @Before fun registerReceiver() { receiver.clear() context.registerReceiver(receiver, IntentFilter(INTENT_ACTION)) } @After fun unregisterReceiver() { context.unregisterReceiver(receiver) } @Before @After fun abandonAllSessions() { instrumentation.uiAutomation .executeShellCommand("pm uninstall com.android.server.pm.test.test_app") .close() installer.mySessions.asSequence() .map { it.sessionId } .forEach { Loading @@ -82,7 +123,7 @@ class PackageSessionTests { setAppLabel(longLabel) } createSession(params) { createAndAbandonSession(params) { assertThat(installer.getSessionInfo(it)?.appLabel) .isEqualTo(longLabel.take(PackageItemInfo.MAX_SAFE_LABEL_LENGTH)) } Loading @@ -95,7 +136,7 @@ class PackageSessionTests { setAppPackageName(longName) } createSession(params) { createAndAbandonSession(params) { assertThat(installer.getSessionInfo(it)?.appPackageName) .isEqualTo(null) } Loading @@ -108,7 +149,7 @@ class PackageSessionTests { setInstallerPackageName(longName) } createSession(params) { createAndAbandonSession(params) { // If a custom installer name is dropped, it defaults to the caller assertThat(installer.getSessionInfo(it)?.installerPackageName) .isEqualTo(context.packageName) Loading @@ -121,12 +162,39 @@ class PackageSessionTests { setWhitelistedRestrictedPermissions(invalidPermissions()) } createSession(params) { createAndAbandonSession(params) { assertThat(installer.getSessionInfo(it)?.whitelistedRestrictedPermissions!!) .containsExactlyElementsIn(RESTRICTED_PERMISSIONS) } } @Test fun fillPackageNameWithParsedValue() { val params = SessionParams(SessionParams.MODE_FULL_INSTALL) val sessionId = installer.createSession(params) val session = installer.openSession(sessionId) javaClass.classLoader.getResourceAsStream("PackageManagerTestAppVersion1.apk")!! .use { input -> session.openWrite("base", 0, -1) .use { output -> input.copyTo(output) } } // Test instrumentation doesn't have install permissions, so use shell ShellIdentityUtils.invokeWithShellPermissions { session.commit(receiver.makeIntentSender(sessionId)) } session.close() // The actual contents aren't verified as part of this test. Only care about it finishing. val result = receiver.getResult(TimeUnit.SECONDS, 30) assertThat(result).isNotNull() val sessionInfo = installer.getSessionInfo(sessionId) assertThat(sessionInfo).isNotNull() assertThat(sessionInfo!!.getAppPackageName()).isEqualTo(TEST_PKG_NAME) } @LargeTest @Test fun allocateMaxSessionsWithPermission() { Loading Loading @@ -177,7 +245,7 @@ class PackageSessionTests { repeat(10) { add(invalidPackageName(300)) } } private fun createSession(params: SessionParams, block: (Int) -> Unit = {}) { private fun createAndAbandonSession(params: SessionParams, block: (Int) -> Unit = {}) { val sessionId = installer.createSession(params) try { block(sessionId) Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +1 −1 Original line number Diff line number Diff line Loading @@ -745,7 +745,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { info.mode = params.mode; info.installReason = params.installReason; info.sizeBytes = params.sizeBytes; info.appPackageName = params.appPackageName; info.appPackageName = mPackageName != null ? mPackageName : params.appPackageName; if (includeIcon) { info.appIcon = params.appIcon; } Loading Loading
core/tests/PackageInstallerSessions/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ android_test { "framework-res", ], java_resources: [ // Borrow an arbitrary test app from another module ":PackageManagerTestAppVersion1", ], platform_apis: true, sdk_version: "core_platform", test_suites: ["device-tests"], Loading
core/tests/PackageInstallerSessions/src/android/content/pm/PackageSessionTests.kt +73 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,12 @@ package android.content.pm import android.app.Instrumentation import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.content.pm.PackageInstaller.SessionParams import android.platform.test.annotations.Presubmit import androidx.test.InstrumentationRegistry Loading @@ -27,6 +32,8 @@ import org.junit.After import org.junit.Before import org.junit.Test import org.testng.Assert.assertThrows import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.TimeUnit import kotlin.random.Random /** Loading @@ -53,15 +60,49 @@ class PackageSessionTests { "android.permission.WRITE_CALL_LOG", "android.permission.PROCESS_OUTGOING_CALLS" ) private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app" private const val INTENT_ACTION = "com.android.server.pm.test.test_app.action" } private val context: Context = InstrumentationRegistry.getContext() private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val installer = context.packageManager.packageInstaller private val receiver = object : BroadcastReceiver() { private val results = ArrayBlockingQueue<Intent>(1) override fun onReceive(context: Context, intent: Intent) { results.add(intent) } fun makeIntentSender(sessionId: Int) = PendingIntent.getBroadcast(context, sessionId, Intent(INTENT_ACTION), PendingIntent.FLAG_UPDATE_CURRENT).intentSender fun getResult(unit: TimeUnit, timeout: Long) = results.poll(timeout, unit) fun clear() = results.clear() } @Before fun registerReceiver() { receiver.clear() context.registerReceiver(receiver, IntentFilter(INTENT_ACTION)) } @After fun unregisterReceiver() { context.unregisterReceiver(receiver) } @Before @After fun abandonAllSessions() { instrumentation.uiAutomation .executeShellCommand("pm uninstall com.android.server.pm.test.test_app") .close() installer.mySessions.asSequence() .map { it.sessionId } .forEach { Loading @@ -82,7 +123,7 @@ class PackageSessionTests { setAppLabel(longLabel) } createSession(params) { createAndAbandonSession(params) { assertThat(installer.getSessionInfo(it)?.appLabel) .isEqualTo(longLabel.take(PackageItemInfo.MAX_SAFE_LABEL_LENGTH)) } Loading @@ -95,7 +136,7 @@ class PackageSessionTests { setAppPackageName(longName) } createSession(params) { createAndAbandonSession(params) { assertThat(installer.getSessionInfo(it)?.appPackageName) .isEqualTo(null) } Loading @@ -108,7 +149,7 @@ class PackageSessionTests { setInstallerPackageName(longName) } createSession(params) { createAndAbandonSession(params) { // If a custom installer name is dropped, it defaults to the caller assertThat(installer.getSessionInfo(it)?.installerPackageName) .isEqualTo(context.packageName) Loading @@ -121,12 +162,39 @@ class PackageSessionTests { setWhitelistedRestrictedPermissions(invalidPermissions()) } createSession(params) { createAndAbandonSession(params) { assertThat(installer.getSessionInfo(it)?.whitelistedRestrictedPermissions!!) .containsExactlyElementsIn(RESTRICTED_PERMISSIONS) } } @Test fun fillPackageNameWithParsedValue() { val params = SessionParams(SessionParams.MODE_FULL_INSTALL) val sessionId = installer.createSession(params) val session = installer.openSession(sessionId) javaClass.classLoader.getResourceAsStream("PackageManagerTestAppVersion1.apk")!! .use { input -> session.openWrite("base", 0, -1) .use { output -> input.copyTo(output) } } // Test instrumentation doesn't have install permissions, so use shell ShellIdentityUtils.invokeWithShellPermissions { session.commit(receiver.makeIntentSender(sessionId)) } session.close() // The actual contents aren't verified as part of this test. Only care about it finishing. val result = receiver.getResult(TimeUnit.SECONDS, 30) assertThat(result).isNotNull() val sessionInfo = installer.getSessionInfo(sessionId) assertThat(sessionInfo).isNotNull() assertThat(sessionInfo!!.getAppPackageName()).isEqualTo(TEST_PKG_NAME) } @LargeTest @Test fun allocateMaxSessionsWithPermission() { Loading Loading @@ -177,7 +245,7 @@ class PackageSessionTests { repeat(10) { add(invalidPackageName(300)) } } private fun createSession(params: SessionParams, block: (Int) -> Unit = {}) { private fun createAndAbandonSession(params: SessionParams, block: (Int) -> Unit = {}) { val sessionId = installer.createSession(params) try { block(sessionId) Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +1 −1 Original line number Diff line number Diff line Loading @@ -745,7 +745,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { info.mode = params.mode; info.installReason = params.installReason; info.sizeBytes = params.sizeBytes; info.appPackageName = params.appPackageName; info.appPackageName = mPackageName != null ? mPackageName : params.appPackageName; if (includeIcon) { info.appIcon = params.appIcon; } Loading