summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageInfo.java6
-rw-r--r--core/java/android/content/pm/PackageParser.java9
-rw-r--r--services/java/com/android/server/PackageManagerService.java13
-rwxr-xr-xtests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java140
4 files changed, 102 insertions, 66 deletions
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index e9a9f31..af327c3 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -153,6 +153,12 @@ public class PackageInfo implements Parcelable {
* the {@link android.R.attr#installLocation} attribute.
* @hide
*/
+ public static final int INSTALL_LOCATION_UNSPECIFIED = -1;
+ /**
+ * Constant corresponding to <code>auto</code> in
+ * the {@link android.R.attr#installLocation} attribute.
+ * @hide
+ */
public static final int INSTALL_LOCATION_AUTO = 0;
/**
* Constant corresponding to <code>internalOnly</code> in
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c33f305..821d19c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -96,7 +96,8 @@ public class PackageParser {
private static final Object mSync = new Object();
private static WeakReference<byte[]> mReadBuffer;
- private static boolean sCompatibilityModeEnabled = true;
+ private static boolean sCompatibilityModeEnabled = true;
+ private static final int PARSE_DEFAULT_INSTALL_LOCATION = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
static class ParsePackageItemArgs {
final Package owner;
@@ -707,12 +708,12 @@ public class PackageParser {
+ pkgName + "\": " + nameError;
return null;
}
- int installLocation = PackageInfo.INSTALL_LOCATION_AUTO;
+ int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
for (int i = 0; i < attrs.getAttributeCount(); i++) {
String attr = attrs.getAttributeName(i);
if (attr.equals("installLocation")) {
installLocation = attrs.getAttributeIntValue(i,
- PackageInfo.INSTALL_LOCATION_AUTO);
+ PARSE_DEFAULT_INSTALL_LOCATION);
break;
}
}
@@ -778,7 +779,7 @@ public class PackageParser {
pkg.installLocation = sa.getInteger(
com.android.internal.R.styleable.AndroidManifest_installLocation,
- PackageInfo.INSTALL_LOCATION_AUTO);
+ PARSE_DEFAULT_INSTALL_LOCATION);
// Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 87a744e..f854067 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4701,23 +4701,22 @@ class PackageManagerService extends IPackageManager.Stub {
}
return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
} else {
- // When replacing apps make sure we honour
- // the existing app location if not overwritten by other options
- boolean prevOnSd = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
if (onSd) {
// Install flag overrides everything.
return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
}
- // If current upgrade does not specify install location.
+ // If current upgrade specifies particular preference
if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
// Application explicitly specified internal.
return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
} else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
// App explictly prefers external. Let policy decide
- } else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
+ } else {
// Prefer previous location
- return prevOnSd ? PackageHelper.RECOMMEND_INSTALL_EXTERNAL:
- PackageHelper.RECOMMEND_INSTALL_INTERNAL;
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
+ return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
+ }
+ return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
}
}
} else {
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 009c0f2..b581192 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -86,8 +86,7 @@ public class PackageManagerTests extends AndroidTestCase {
fail(errMsg);
}
void failStr(Exception e) {
- Log.w(TAG, "e.getMessage="+e.getMessage());
- Log.w(TAG, "e="+e);
+ failStr(e.getMessage());
}
@Override
@@ -297,6 +296,17 @@ public class PackageManagerTests extends AndroidTestCase {
private static final int INSTALL_LOC_INT = 1;
private static final int INSTALL_LOC_SD = 2;
private static final int INSTALL_LOC_ERR = -1;
+ private int checkDefaultPolicy(long pkgLen) {
+ // Check for free memory internally
+ if (checkInt(pkgLen)) {
+ return INSTALL_LOC_INT;
+ }
+ // Check for free memory externally
+ if (checkSd(pkgLen)) {
+ return INSTALL_LOC_SD;
+ }
+ return INSTALL_LOC_ERR;
+ }
private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) {
// Flags explicitly over ride everything else.
if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) {
@@ -324,15 +334,7 @@ public class PackageManagerTests extends AndroidTestCase {
return INSTALL_LOC_ERR;
}
if (expInstallLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
- // Check for free memory internally
- if (checkInt(pkgLen)) {
- return INSTALL_LOC_INT;
- }
- // Check for free memory externally
- if (checkSd(pkgLen)) {
- return INSTALL_LOC_SD;
- }
- return INSTALL_LOC_ERR;
+ return checkDefaultPolicy(pkgLen);
}
// Check for settings preference.
boolean checkSd = false;
@@ -359,19 +361,9 @@ public class PackageManagerTests extends AndroidTestCase {
return INSTALL_LOC_SD;
}
return INSTALL_LOC_ERR;
- } else if (userPref == APP_INSTALL_AUTO) {
- if (checkInt(pkgLen)) {
- return INSTALL_LOC_INT;
- }
- // Check for free memory externally
- if (checkSd(pkgLen)) {
- return INSTALL_LOC_SD;
- }
- return INSTALL_LOC_ERR;
-
}
- }
- return INSTALL_LOC_ERR;
+ }
+ return checkDefaultPolicy(pkgLen);
}
private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
@@ -434,7 +426,7 @@ public class PackageManagerTests extends AndroidTestCase {
private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) {
return installFromRawResource("install.apk", R.raw.install, flags, cleanUp,
- false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
+ false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
static final String PERM_PACKAGE = "package";
@@ -1114,7 +1106,7 @@ public class PackageManagerTests extends AndroidTestCase {
public void testManifestInstallLocationUnspecified() {
installFromRawResource("install.apk", R.raw.install_loc_unspecified,
- 0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
+ 0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
public void testManifestInstallLocationFwdLockedFlagSdcard() {
@@ -1122,7 +1114,7 @@ public class PackageManagerTests extends AndroidTestCase {
PackageManager.INSTALL_FORWARD_LOCK |
PackageManager.INSTALL_EXTERNAL, true, true,
PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
- PackageInfo.INSTALL_LOCATION_AUTO);
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
public void testManifestInstallLocationFwdLockedSdcard() {
@@ -1178,12 +1170,12 @@ public class PackageManagerTests extends AndroidTestCase {
public void testManifestInstallLocationReplaceInternalSdcard() {
int iFlags = 0;
- int iApk = R.raw.install_loc_unspecified;
+ int iApk = R.raw.install_loc_internal;
int rFlags = 0;
int rApk = R.raw.install_loc_sdcard;
InstallParams ip = installFromRawResource("install.apk", iApk,
iFlags, false,
- false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
+ false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
try {
@@ -1855,21 +1847,28 @@ public class PackageManagerTests extends AndroidTestCase {
* The following set of tests check install location for existing
* application based on user setting.
*/
- private void setExistingXUserX(int userSetting, int iFlags) {
+ private int getExpectedInstallLocation(int userSetting) {
+ int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+ boolean enable = getUserSettingSetInstallLocation();
+ if (enable) {
+ if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
+ iloc = PackageInfo.INSTALL_LOCATION_AUTO;
+ } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
+ iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
+ } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
+ iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
+ }
+ }
+ return iloc;
+ }
+ private void setExistingXUserX(int userSetting, int iFlags, int iloc) {
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
// First install.
installFromRawResource("install.apk", R.raw.install,
iFlags,
false,
false, -1,
- -1);
- // Watch out for this.
- int iloc = PackageInfo.INSTALL_LOCATION_AUTO;
- if ((iFlags & PackageManager.INSTALL_INTERNAL) != 0) {
- iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
- } else if ((iFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
- iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
- }
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
int origSetting = getInstallLoc();
try {
// Set user setting
@@ -1887,49 +1886,56 @@ public class PackageManagerTests extends AndroidTestCase {
public void testExistingIUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
int iFlags = PackageManager.INSTALL_INTERNAL;
- setExistingXUserX(userSetting, iFlags);
+ setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
public void testExistingIUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
int iFlags = PackageManager.INSTALL_INTERNAL;
- setExistingXUserX(userSetting, iFlags);
+ setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
public void testExistingIUserA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
int iFlags = PackageManager.INSTALL_INTERNAL;
- setExistingXUserX(userSetting, iFlags);
+ setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
public void testExistingEUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
int iFlags = PackageManager.INSTALL_EXTERNAL;
- setExistingXUserX(userSetting, iFlags);
+ setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
public void testExistingEUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
int iFlags = PackageManager.INSTALL_EXTERNAL;
- setExistingXUserX(userSetting, iFlags);
+ setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
public void testExistingEUserA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
int iFlags = PackageManager.INSTALL_EXTERNAL;
- setExistingXUserX(userSetting, iFlags);
+ setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
/*
* The following set of tests verify that the user setting defines
* the install location.
*
*/
- private void setUserX(int userSetting) {
- int origSetting = getInstallLoc();
- int iloc = PackageInfo.INSTALL_LOCATION_AUTO;
- if (userSetting == PackageHelper.APP_INSTALL_AUTO) {
- iloc = PackageInfo.INSTALL_LOCATION_AUTO;
- } else if (userSetting == PackageHelper.APP_INSTALL_EXTERNAL) {
- iloc = PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
- } else if (userSetting == PackageHelper.APP_INSTALL_INTERNAL) {
- iloc = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
+ private boolean getUserSettingSetInstallLocation() {
+ try {
+ return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION) != 0;
+
+ } catch (SettingNotFoundException e1) {
}
+ return false;
+ }
+
+ private void setUserSettingSetInstallLocation(boolean value) {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SET_INSTALL_LOCATION, value ? 1 : 0);
+ }
+ private void setUserX(boolean enable, int userSetting, int iloc) {
+ boolean origUserSetting = getUserSettingSetInstallLocation();
+ int origSetting = getInstallLoc();
try {
+ setUserSettingSetInstallLocation(enable);
// Set user setting
setInstallLoc(userSetting);
// Replace now
@@ -1939,20 +1945,44 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
iloc);
} finally {
+ // Restore original setting
+ setUserSettingSetInstallLocation(origUserSetting);
setInstallLoc(origSetting);
}
}
public void testUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
- setUserX(userSetting);
+ int iloc = getExpectedInstallLocation(userSetting);
+ setUserX(true, userSetting, iloc);
}
public void testUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
- setUserX(userSetting);
+ int iloc = getExpectedInstallLocation(userSetting);
+ setUserX(true, userSetting, iloc);
}
public void testUserA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
- setUserX(userSetting);
+ int iloc = getExpectedInstallLocation(userSetting);
+ setUserX(true, userSetting, iloc);
+ }
+ /*
+ * The following set of tests turn on/off the basic
+ * user setting for turning on install location.
+ */
+ public void testUserPrefOffUserI() {
+ int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
+ int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+ setUserX(false, userSetting, iloc);
+ }
+ public void testUserPrefOffUserE() {
+ int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+ int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+ setUserX(false, userSetting, iloc);
+ }
+ public void testUserPrefOffA() {
+ int userSetting = PackageHelper.APP_INSTALL_AUTO;
+ int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+ setUserX(false, userSetting, iloc);
}
static final String BASE_PERMISSIONS_DEFINED[] = new String[] {