diff options
| author | 2021-11-22 01:41:31 +0000 | |
|---|---|---|
| committer | 2021-11-22 01:41:31 +0000 | |
| commit | 083bd48e191be350eaadb343a164fb8c579be80c (patch) | |
| tree | 75fc6e2a8f7edcf7e26438b309ca8fe3b3b7b949 | |
| parent | 71bdcc81b980a73a6b85511da145477308836796 (diff) | |
| parent | a4a15f12c161af76d25855abb6fc5f6916b5d083 (diff) | |
Merge "Keep install reason unchanged when package is uninstalled"
7 files changed, 227 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 39ed9c2d51d3..861fec7cc236 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -2349,10 +2349,9 @@ final class InstallPackageHelper { // Set install reason for users that are having the package newly installed. final int[] allUsersList = mPm.mUserManager.getUserIds(); if (userId == UserHandle.USER_ALL) { - // TODO(b/152629990): It appears that the package doesn't actually get newly - // installed in this case, so the installReason shouldn't get modified? for (int currentUserId : allUsersList) { - if (!previousUserIds.contains(currentUserId)) { + if (!previousUserIds.contains(currentUserId) + && ps.getInstalled(currentUserId)) { ps.setInstallReason(installReason, currentUserId); } } diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index ba580ecaad16..e3c60fdfc697 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -108,6 +108,7 @@ android_test { data: [ ":JobTestApp", + ":StubTestApp", ], java_resources: [ diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml index 5a0f1ee963a2..4c638d669019 100644 --- a/services/tests/servicestests/AndroidTest.xml +++ b/services/tests/servicestests/AndroidTest.xml @@ -28,6 +28,17 @@ <option name="test-file-name" value="SimpleServiceTestApp3.apk" /> </target_preparer> + <!-- Create place to store apks --> + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> + <option name="run-command" value="mkdir -p /data/local/tmp/servicestests" /> + <option name="teardown-command" value="rm -rf /data/local/tmp/servicestests"/> + </target_preparer> + + <!-- Load additional APKs onto device --> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="push" value="StubTestApp.apk->/data/local/tmp/servicestests/StubTestApp.apk"/> + </target_preparer> + <option name="test-tag" value="FrameworksServicesTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.servicestests" /> diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java index 7aea392e37ec..6a85c8b2e2ba 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java @@ -16,6 +16,8 @@ package com.android.server.pm; +import static com.android.compatibility.common.util.ShellUtils.runShellCommand; + import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.fail; @@ -27,11 +29,17 @@ import static java.lang.reflect.Modifier.isPublic; import static java.lang.reflect.Modifier.isStatic; import android.annotation.Nullable; +import android.app.AppGlobals; import android.content.IIntentReceiver; +import android.content.pm.IPackageManager; +import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Bundle; +import android.os.UserHandle; +import android.os.UserManager; import android.util.SparseArray; +import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.HexDump; @@ -42,6 +50,7 @@ import com.google.android.collect.Lists; import org.junit.After; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -62,6 +71,11 @@ import java.util.regex.Pattern; // bit FrameworksServicesTests:com.android.server.pm.PackageManagerServiceTest @RunWith(AndroidJUnit4.class) public class PackageManagerServiceTest { + + private static final String TEST_DATA_PATH = "/data/local/tmp/servicestests/"; + private static final String TEST_APP_APK = "StubTestApp.apk"; + private static final String TEST_PKG_NAME = "com.android.servicestests.apps.stubapp"; + @Before public void setUp() throws Exception { } @@ -603,4 +617,119 @@ public class PackageManagerServiceTest { Collections.sort(knownPackageIds); return knownPackageIds; } + + @Test + public void testInstallReason_afterUpdate_keepUnchanged() throws Exception { + final IPackageManager pm = AppGlobals.getPackageManager(); + final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); + try { + // Try to install test APK with reason INSTALL_REASON_POLICY + runShellCommand("pm install --install-reason 1 " + testApk); + assertWithMessage("The install reason of test APK is incorrect.").that( + pm.getInstallReason(TEST_PKG_NAME, UserHandle.myUserId())).isEqualTo( + PackageManager.INSTALL_REASON_POLICY); + + // Try to update test APK with different reason INSTALL_REASON_USER + runShellCommand("pm install --install-reason 4 " + testApk); + assertWithMessage("The install reason should keep unchanged after update.").that( + pm.getInstallReason(TEST_PKG_NAME, UserHandle.myUserId())).isEqualTo( + PackageManager.INSTALL_REASON_POLICY); + } finally { + runShellCommand("pm uninstall " + TEST_PKG_NAME); + } + } + + @Test + public void testInstallReason_userRemainsUninstalled_keepUnknown() throws Exception { + Assume.assumeTrue(UserManager.supportsMultipleUsers()); + final IPackageManager pm = AppGlobals.getPackageManager(); + final UserManager um = UserManager.get( + InstrumentationRegistry.getInstrumentation().getContext()); + final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); + int userId = UserHandle.USER_NULL; + try { + // Try to install test APK with reason INSTALL_REASON_POLICY + runShellCommand("pm install --install-reason 1 " + testApk); + assertWithMessage("The install reason of test APK is incorrect.").that( + pm.getInstallReason(TEST_PKG_NAME, UserHandle.myUserId())).isEqualTo( + PackageManager.INSTALL_REASON_POLICY); + + // Create and start the 2nd user. + userId = um.createUser("Test User", 0 /* flags */).getUserHandle().getIdentifier(); + runShellCommand("am start-user -w " + userId); + // Since the test APK isn't installed on the 2nd user, the reason should be unknown. + assertWithMessage("The install reason in 2nd user should be unknown.").that( + pm.getInstallReason(TEST_PKG_NAME, userId)).isEqualTo( + PackageManager.INSTALL_REASON_UNKNOWN); + + // Try to update test APK with different reason INSTALL_REASON_USER + runShellCommand("pm install --install-reason 4 " + testApk); + assertWithMessage("The install reason in 2nd user should keep unknown.").that( + pm.getInstallReason(TEST_PKG_NAME, userId)).isEqualTo( + PackageManager.INSTALL_REASON_UNKNOWN); + } finally { + runShellCommand("pm uninstall " + TEST_PKG_NAME); + if (userId != UserHandle.USER_NULL) { + um.removeUser(userId); + } + } + } + + @Test + public void testInstallReason_installForAllUsers_sameReason() throws Exception { + Assume.assumeTrue(UserManager.supportsMultipleUsers()); + final IPackageManager pm = AppGlobals.getPackageManager(); + final UserManager um = UserManager.get( + InstrumentationRegistry.getInstrumentation().getContext()); + final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); + int userId = UserHandle.USER_NULL; + try { + // Create and start the 2nd user. + userId = um.createUser("Test User", 0 /* flags */).getUserHandle().getIdentifier(); + runShellCommand("am start-user -w " + userId); + + // Try to install test APK to all users with reason INSTALL_REASON_POLICY + runShellCommand("pm install --install-reason 1 " + testApk); + assertWithMessage("The install reason is inconsistent across users.").that( + pm.getInstallReason(TEST_PKG_NAME, UserHandle.myUserId())).isEqualTo( + pm.getInstallReason(TEST_PKG_NAME, userId)); + } finally { + runShellCommand("pm uninstall " + TEST_PKG_NAME); + if (userId != UserHandle.USER_NULL) { + um.removeUser(userId); + } + } + } + + @Test + public void testInstallReason_installSeparately_withSeparatedReason() throws Exception { + Assume.assumeTrue(UserManager.supportsMultipleUsers()); + final IPackageManager pm = AppGlobals.getPackageManager(); + final UserManager um = UserManager.get( + InstrumentationRegistry.getInstrumentation().getContext()); + final File testApk = new File(TEST_DATA_PATH, TEST_APP_APK); + int userId = UserHandle.USER_NULL; + try { + // Create and start the 2nd user. + userId = um.createUser("Test User", 0 /* flags */).getUserHandle().getIdentifier(); + runShellCommand("am start-user -w " + userId); + + // Try to install test APK on the current user with reason INSTALL_REASON_POLICY + runShellCommand("pm install --user cur --install-reason 1 " + testApk); + assertWithMessage("The install reason on the current user is incorrect.").that( + pm.getInstallReason(TEST_PKG_NAME, UserHandle.myUserId())).isEqualTo( + PackageManager.INSTALL_REASON_POLICY); + + // Try to install test APK on the 2nd user with reason INSTALL_REASON_USER + runShellCommand("pm install --user " + userId + " --install-reason 4 " + testApk); + assertWithMessage("The install reason on the 2nd user is incorrect.").that( + pm.getInstallReason(TEST_PKG_NAME, userId)).isEqualTo( + PackageManager.INSTALL_REASON_USER); + } finally { + runShellCommand("pm uninstall " + TEST_PKG_NAME); + if (userId != UserHandle.USER_NULL) { + um.removeUser(userId); + } + } + } } diff --git a/services/tests/servicestests/test-apps/StubApp/Android.bp b/services/tests/servicestests/test-apps/StubApp/Android.bp new file mode 100644 index 000000000000..99deb3f5bbf0 --- /dev/null +++ b/services/tests/servicestests/test-apps/StubApp/Android.bp @@ -0,0 +1,37 @@ +// Copyright (C) 2021 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. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +android_test_helper_app { + name: "StubTestApp", + + sdk_version: "current", + + srcs: ["**/*.java"], + + dex_preopt: { + enabled: false, + }, + optimize: { + enabled: false, + }, +} diff --git a/services/tests/servicestests/test-apps/StubApp/AndroidManifest.xml b/services/tests/servicestests/test-apps/StubApp/AndroidManifest.xml new file mode 100644 index 000000000000..90172e77f958 --- /dev/null +++ b/services/tests/servicestests/test-apps/StubApp/AndroidManifest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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="com.android.servicestests.apps.stubapp"> + + <application android:label="StubTestApp"> + <activity android:name=".TestActivity" + android:exported="true" /> + </application> + +</manifest>
\ No newline at end of file diff --git a/services/tests/servicestests/test-apps/StubApp/src/com/android/servicestests/apps/stubapp/TestActivity.java b/services/tests/servicestests/test-apps/StubApp/src/com/android/servicestests/apps/stubapp/TestActivity.java new file mode 100644 index 000000000000..0d94676aeb52 --- /dev/null +++ b/services/tests/servicestests/test-apps/StubApp/src/com/android/servicestests/apps/stubapp/TestActivity.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 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. + */ + +package com.android.servicestests.apps.stubapp; + +import android.app.Activity; + +public class TestActivity extends Activity { +} |