summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java17
-rwxr-xr-xservices/core/java/com/android/server/pm/Settings.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java68
3 files changed, 107 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 068df4b..0e174c3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5994,16 +5994,17 @@ public class PackageManagerService extends IPackageManager.Stub {
if ((parseFlags & PackageParser.PARSE_IS_PREBUNDLED_DIR) != 0) {
synchronized (mPackages) {
PackageSetting existingSettings = mSettings.peekPackageLPr(pkg.packageName);
- boolean isInstalledForUser = (existingSettings != null
- && existingSettings.getInstalled(user.getIdentifier()));
- if (mSettings.wasPrebundledPackageInstalledLPr(user.getIdentifier(),
- pkg.packageName) && !isInstalledForUser) {
- // The prebundled app was installed at some point for the user and isn't
- // currently installed for the user, skip reinstalling it
+
+ if (!mSettings.shouldPrebundledPackageBeInstalledForUserLPr(existingSettings,
+ user.getIdentifier(), pkg.packageName)) {
+ // The prebundled app was installed at some point for the owner and isn't
+ // currently installed for the owner, dont install it for a new user
+ // OR the prebundled app was installed for the user at some point and isn't
+ // current installed for the user, so skip reinstalling it
throw new PackageManagerException(INSTALL_FAILED_UNINSTALLED_PREBUNDLE,
"skip reinstall for " + pkg.packageName);
- } else if (!mSettings.shouldPrebundledPackageBeInstalled(mContext.getResources(),
- pkg.packageName, mCustomResources)) {
+ } else if (!mSettings.shouldPrebundledPackageBeInstalledForRegion(
+ mContext.getResources(), pkg.packageName, mCustomResources)) {
// The prebundled app is not needed for the default mobile country code,
// skip installing it
throw new PackageManagerException(INSTALL_FAILED_REGION_LOCKED_PREBUNDLE,
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 502afa0..38478c2 100755
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2524,7 +2524,7 @@ final class Settings {
return mPrebundledPackages.get(userId).contains(packageName);
}
- boolean shouldPrebundledPackageBeInstalled(Resources res, String packageName,
+ boolean shouldPrebundledPackageBeInstalledForRegion(Resources res, String packageName,
Resources configuredResources) {
// Default fallback on lack of bad package
if (TextUtils.isEmpty(packageName)) {
@@ -2557,6 +2557,37 @@ final class Settings {
return !ArrayUtils.contains(prebundledArray, packageName);
}
+ boolean shouldPrebundledPackageBeInstalledForUserLPr(PackageSetting existingSettings,
+ int userIdentifier, String packageName) {
+
+ // Check if package installed for the user
+ final boolean isInstalledForUser = (existingSettings != null
+ && existingSettings.getInstalled(userIdentifier));
+
+ // Check if package installed for the owner
+ final boolean isInstalledForOwner = (existingSettings != null
+ && existingSettings.getInstalled(UserHandle.USER_OWNER));
+
+ // Check if the user is the owner
+ final boolean isOwner = userIdentifier == UserHandle.USER_OWNER;
+
+ // If the given user is not the owner, and the prebundle was installed for the owner
+ // but is no longer installed, and isn't currently installed for the user,
+ // skip installing it.
+ if (!isOwner && wasPrebundledPackageInstalledLPr(UserHandle.USER_OWNER, packageName)
+ && !isInstalledForOwner && !isInstalledForUser) {
+ return false;
+ }
+
+ // If the given package was installed for the user and isn't currently, skip reinstalling it
+ if (wasPrebundledPackageInstalledLPr(userIdentifier, packageName) &&
+ !isInstalledForUser) {
+ return false;
+ }
+
+ return true;
+ }
+
void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
throws java.io.IOException {
serializer.startTag(null, "updated-package");
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 9c44c7a..aa8b37f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -27,6 +27,7 @@ import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.test.AndroidTestCase;
import android.test.mock.MockContext;
import android.text.TextUtils;
@@ -365,7 +366,7 @@ public class PackageManagerSettingsTests extends AndroidTestCase {
};
Mockito.when(resources.getStringArray(R.array.config_restrict_to_region_locked_devices))
.thenReturn(regionRestrictedPackages);
- assertFalse(settings.shouldPrebundledPackageBeInstalled(resources,
+ assertFalse(settings.shouldPrebundledPackageBeInstalledForRegion(resources,
expectedPackageNeededForRegion, resources));
}
@@ -384,7 +385,70 @@ public class PackageManagerSettingsTests extends AndroidTestCase {
Mockito.when(resources.getStringArray(R.array.config_restrict_to_region_locked_devices))
.thenReturn(regionLockedPackages);
- assertTrue(settings.shouldPrebundledPackageBeInstalled(resources,
+ assertTrue(settings.shouldPrebundledPackageBeInstalledForRegion(resources,
expectedPackageNeededForRegion, resources));
}
+
+ // Shamelessly kanged from KeySetManagerServiceTest
+ public PackageSetting generateFakePackageSetting(String name) {
+ return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"),
+ new File(mContext.getCacheDir(), "fakeResPath"), "", "", "",
+ "", 1, 0, 0);
+ }
+
+ // Checks if a package that was installed and currently isn't installed for the owner
+ // is accepted for a secondary user
+ public void testPrebundledSecondaryUserAccept() {
+ Settings settings = new Settings(getContext().getFilesDir());
+ String expectedPackageToBeInstalled = "org.cyanogenmod.secondaryuser.package";
+
+ PackageSetting packageSetting =
+ generateFakePackageSetting(expectedPackageToBeInstalled);
+
+ int userOwner = UserHandle.USER_OWNER;
+ int userSecondary = 1000;
+
+ // Return true that the package was installed for the owner at some point
+ settings.markPrebundledPackageInstalledLPr(userOwner, expectedPackageToBeInstalled);
+ assertTrue(settings.wasPrebundledPackageInstalledLPr(userOwner,
+ expectedPackageToBeInstalled));
+
+ // Return false that the package was installed for the secondary user at some point
+ // DON'T MARK PREBUNDLED PACKAGE INSTALLED
+
+ // Return false that the package is currently not installed for the owner
+ packageSetting.setInstalled(false, userOwner);
+ assertFalse(packageSetting.getInstalled(userOwner));
+
+ // Return false that the package is currently not installed for the secondary user
+ packageSetting.setInstalled(false, userSecondary);
+ assertFalse(packageSetting.getInstalled(userSecondary));
+
+ assertFalse(settings.shouldPrebundledPackageBeInstalledForUserLPr(packageSetting,
+ userSecondary, expectedPackageToBeInstalled));
+ }
+
+ // Checks if a package that was installed for a secondary user and currently isn't installed
+ // for the user is accepted to be reinstalled
+ public void testPrebundledSecondaryUserReinstallAccept() {
+ Settings settings = new Settings(getContext().getFilesDir());
+ String expectedPackageToBeInstalled = "org.cyanogenmod.secondaryuser.package";
+
+ PackageSetting packageSetting =
+ generateFakePackageSetting(expectedPackageToBeInstalled);
+
+ int userSecondary = 1000;
+
+ // Return true that the package was installed for the secondary user at some point
+ settings.markPrebundledPackageInstalledLPr(userSecondary, expectedPackageToBeInstalled);
+ assertTrue(settings.wasPrebundledPackageInstalledLPr(userSecondary,
+ expectedPackageToBeInstalled));
+
+ // Return false that the package is currently not installed for the secondary user
+ packageSetting.setInstalled(false, userSecondary);
+ assertFalse(packageSetting.getInstalled(userSecondary));
+
+ assertFalse(settings.shouldPrebundledPackageBeInstalledForUserLPr(packageSetting,
+ userSecondary, expectedPackageToBeInstalled));
+ }
}