summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuchi Amalapurapu <asuchitra@google.com>2010-03-17 08:37:04 -0700
committerSuchi Amalapurapu <asuchitra@google.com>2010-03-17 18:43:31 -0700
commit14b6abda1309631d49d4bebbb0317a7e1dfc0a50 (patch)
treebee361e635743a09bb7253fef333d6fb94df6322
parentd246ca811575eee9122070648e93b7484f6edd81 (diff)
downloadframeworks_base-14b6abda1309631d49d4bebbb0317a7e1dfc0a50.zip
frameworks_base-14b6abda1309631d49d4bebbb0317a7e1dfc0a50.tar.gz
frameworks_base-14b6abda1309631d49d4bebbb0317a7e1dfc0a50.tar.bz2
Add new install flag to install on internal flash only
Change default install location policy for new flag. New error code for media unavailable. Change-Id: I5a5d0828b067692b2b94a15a2bcc7534f796c1a2
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java6
-rw-r--r--core/java/android/content/pm/PackageManager.java7
-rwxr-xr-xcore/java/com/android/internal/app/IMediaContainerService.aidl2
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java151
-rw-r--r--services/java/com/android/server/PackageManagerService.java26
-rwxr-xr-xtests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java676
6 files changed, 743 insertions, 125 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index fc5707d..cfc2e75 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -602,6 +602,9 @@ public final class Pm {
} else if (opt.equals("-s")) {
// Override if -s option is specified.
installFlags |= PackageManager.INSTALL_EXTERNAL;
+ } else if (opt.equals("-f")) {
+ // Override if -s option is specified.
+ installFlags |= PackageManager.INSTALL_INTERNAL;
} else {
System.err.println("Error: Unknown option: " + opt);
showUsage();
@@ -861,7 +864,7 @@ public final class Pm {
System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]");
System.err.println(" pm list features");
System.err.println(" pm path PACKAGE");
- System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] PATH");
+ System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm mountsd [-m true/false]");
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
@@ -895,6 +898,7 @@ public final class Pm {
System.err.println(" -t: allow test .apks to be installed.");
System.err.println(" -i: specify the installer package name.");
System.err.println(" -s: install package on sdcard.");
+ System.err.println(" -f: install package on internal flash.");
System.err.println("");
System.err.println("The uninstall command removes a package from the system. Options:");
System.err.println(" -k: keep the data and cache directories around.");
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e1fbe48..bbf4ca1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -261,6 +261,13 @@ public abstract class PackageManager {
public static final int INSTALL_EXTERNAL = 0x00000008;
/**
+ * Flag parameter for {@link #installPackage} to indicate that this
+ * package has to be installed on the sdcard.
+ * @hide
+ */
+ public static final int INSTALL_INTERNAL = 0x00000010;
+
+ /**
* Flag parameter for
* {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
* that you don't want to kill the app containing the component. Be careful when you set this
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index badabb0..0f817b7 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -26,6 +26,6 @@ interface IMediaContainerService {
String key, String resFileName);
boolean copyResource(in Uri packageURI,
in ParcelFileDescriptor outStream);
- PackageInfoLite getMinimalPackageInfo(in Uri fileUri);
+ PackageInfoLite getMinimalPackageInfo(in Uri fileUri, int flags);
boolean checkFreeStorage(boolean external, in Uri fileUri);
} \ No newline at end of file
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 77d11cc..14c8806 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -105,7 +105,7 @@ public class DefaultContainerService extends IntentService {
* @return Returns PackageInfoLite object containing
* the package info and recommended app location.
*/
- public PackageInfoLite getMinimalPackageInfo(final Uri fileUri) {
+ public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags) {
PackageInfoLite ret = new PackageInfoLite();
if (fileUri == null) {
Log.i(TAG, "Invalid package uri " + fileUri);
@@ -136,7 +136,7 @@ public class DefaultContainerService extends IntentService {
return ret;
}
ret.packageName = pkg.packageName;
- ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath);
+ ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath, flags);
return ret;
}
@@ -305,8 +305,65 @@ public class DefaultContainerService extends IntentService {
private static final int ERR_LOC = -1;
private int recommendAppInstallLocation(int installLocation,
- String archiveFilePath) {
- // Initial implementation:
+ String archiveFilePath, int flags) {
+ boolean checkInt = false;
+ boolean checkExt = false;
+ boolean checkBoth = false;
+ check_inner : {
+ // Check flags.
+ if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
+ // Check for forward locked app
+ checkInt = true;
+ break check_inner;
+ } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
+ // Explicit flag to install internally.
+ // Check internal storage and return
+ checkInt = true;
+ break check_inner;
+ } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
+ // Explicit flag to install externally.
+ // Check external storage and return
+ checkExt = true;
+ break check_inner;
+ }
+ // Check for manifest option
+ if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
+ checkInt = true;
+ break check_inner;
+ } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
+ checkExt = true;
+ checkBoth = true;
+ break check_inner;
+ } else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
+ checkInt = true;
+ checkBoth = true;
+ break check_inner;
+ }
+ // Check if user option is enabled
+ boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
+ .getContentResolver(),
+ Settings.System.SET_INSTALL_LOCATION, 0) != 0;
+ if (setInstallLoc) {
+ // Pick user preference
+ int installPreference = Settings.System.getInt(getApplicationContext()
+ .getContentResolver(),
+ Settings.System.DEFAULT_INSTALL_LOCATION,
+ PackageHelper.APP_INSTALL_AUTO);
+ if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
+ checkInt = true;
+ checkBoth = true;
+ break check_inner;
+ } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
+ checkExt = true;
+ checkBoth = true;
+ break check_inner;
+ }
+ }
+ // Fall back to default policy if nothing else is specified.
+ checkInt = true;
+ checkBoth = true;
+ }
+
// Package size = code size + cache size + data size
// If code size > 1 MB, install on SD card.
// Else install on internal NAND flash, unless space on NAND is less than 10%
@@ -330,77 +387,47 @@ public class DefaultContainerService extends IntentService {
File apkFile = new File(archiveFilePath);
long pkgLen = apkFile.length();
-
- boolean auto = true;
+
// To make final copy
long reqInstallSize = pkgLen;
// For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now.
long reqInternalSize = 0;
boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize);
- boolean fitsOnSd = mediaAvailable && (reqInstallSize < availSDSize)
- && intThresholdOk &&
- (reqInternalSize < availInternalSize);
+ boolean fitsOnSd = false;
+ if (mediaAvailable && (reqInstallSize < availSDSize)) {
+ // If we do not have an internal size requirement
+ // don't do a threshold check.
+ if (reqInternalSize == 0) {
+ fitsOnSd = true;
+ } else if ((reqInternalSize < availInternalSize) && intThresholdOk) {
+ fitsOnSd = true;
+ }
+ }
boolean fitsOnInt = intThresholdOk && intAvailOk;
-
- // Consider application flags preferences as well...
- boolean installOnlyOnSd = (installLocation ==
- PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
- boolean installOnlyInternal = (installLocation ==
- PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
- if (installOnlyInternal) {
- // If set explicitly in manifest,
- // let that override everything else
- auto = false;
- } else if (installOnlyOnSd){
- // Check if this can be accommodated on the sdcard
- if (fitsOnSd) {
- auto = false;
+ if (checkInt) {
+ // Check for internal memory availability
+ if (fitsOnInt) {
+ return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
}
- } else {
- // Check if user option is enabled
- boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
- .getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 0) != 0;
- if (setInstallLoc) {
- // Pick user preference
- int installPreference = Settings.System.getInt(getApplicationContext()
- .getContentResolver(),
- Settings.System.DEFAULT_INSTALL_LOCATION,
- PackageHelper.APP_INSTALL_AUTO);
- if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
- installOnlyInternal = true;
- auto = false;
- } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
- installOnlyOnSd = true;
- auto = false;
- }
+ } else if (checkExt) {
+ if (fitsOnSd) {
+ return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
}
}
- if (!auto) {
- if (installOnlyOnSd) {
- if (fitsOnSd) {
- return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
- }
- if (!mediaAvailable) {
- return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
- }
- return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
- } else if (installOnlyInternal){
- // Check on internal flash
- return fitsOnInt ? PackageHelper.RECOMMEND_INSTALL_INTERNAL :
- PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
+ if (checkBoth) {
+ // Check for internal first
+ if (fitsOnInt) {
+ return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
+ }
+ // Check for external next
+ if (fitsOnSd) {
+ return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
}
}
- // Try to install internally
- if (fitsOnInt) {
- return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
- }
- // Try the sdcard now.
- if (fitsOnSd) {
- return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
+ if (checkExt || checkBoth && !mediaAvailable) {
+ return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
}
- // Return error code
return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 818e99e..55725bd 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -595,10 +595,13 @@ class PackageManagerService extends IPackageManager.Stub {
static boolean installOnSd(int flags) {
if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) ||
- ((flags & PackageManager.INSTALL_EXTERNAL) == 0)) {
+ ((flags & PackageManager.INSTALL_INTERNAL) != 0)) {
return false;
}
- return true;
+ if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
+ return true;
+ }
+ return false;
}
static boolean isFwdLocked(int flags) {
@@ -4452,8 +4455,8 @@ class PackageManagerService extends IPackageManager.Stub {
res.uid = -1;
res.pkg = null;
res.removedInfo = new PackageRemovedInfo();
- args.doPreInstall(res.returnCode);
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
+ args.doPreInstall(res.returnCode);
synchronized (mInstallLock) {
installPackageLI(args, true, res);
}
@@ -4623,13 +4626,18 @@ class PackageManagerService extends IPackageManager.Stub {
int ret = PackageManager.INSTALL_SUCCEEDED;
boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
- // Dont need to invoke getInstallLocation for forward locked apps.
- if (fwdLocked && onSd) {
+ boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
+ if (onInt && onSd) {
+ // Check if both bits are set.
+ Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
+ ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
+ } else if (fwdLocked && onSd) {
+ // Check for forward locked apps
Slog.w(TAG, "Cannot install fwd locked apps on sdcard");
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} else {
// Remote call to find out default install location
- PackageInfoLite pkgLite = mContainerService.getMinimalPackageInfo(packageURI);
+ PackageInfoLite pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags);
int loc = pkgLite.recommendedInstallLocation;
if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
@@ -4644,14 +4652,16 @@ class PackageManagerService extends IPackageManager.Stub {
} else {
// Override with defaults if needed.
loc = installLocationPolicy(pkgLite, flags);
- // Override install location with flags
- if ((flags & PackageManager.INSTALL_EXTERNAL) == 0){
+ if (!onSd && !onInt) {
+ // Override install location with flags
if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
// Set the flag to install on external media.
flags |= PackageManager.INSTALL_EXTERNAL;
+ flags &= ~PackageManager.INSTALL_INTERNAL;
} else {
// Make sure the flag for installing on external
// media is unset
+ flags |= PackageManager.INSTALL_INTERNAL;
flags &= ~PackageManager.INSTALL_EXTERNAL;
}
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index a06a13b..b988920 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -78,6 +78,7 @@ public class PackageManagerTests extends AndroidTestCase {
private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL;
+ private boolean mOrigState;
void failStr(String errMsg) {
Log.w(TAG, "errMsg="+errMsg);
@@ -91,6 +92,21 @@ public class PackageManagerTests extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
+ mOrigState = getMediaState();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Restore media state.
+ boolean newState = getMediaState();
+ if (newState != mOrigState) {
+ if (mOrigState) {
+ getMs().mountVolume(Environment.getExternalStorageDirectory().getPath());
+ } else {
+ getMs().unmountVolume(Environment.getExternalStorageDirectory().getPath(), true);
+ }
+ }
+ super.tearDown();
}
private class PackageInstallObserver extends IPackageInstallObserver.Stub {
@@ -254,21 +270,70 @@ public class PackageManagerTests extends AndroidTestCase {
packageParser = null;
return pkg;
}
- private boolean getInstallLoc(int flags, int expInstallLocation) {
+ private boolean checkSd(long pkgLen) {
+ String status = Environment.getExternalStorageState();
+ if (!status.equals(Environment.MEDIA_MOUNTED)) {
+ return false;
+ }
+ long sdSize = -1;
+ StatFs sdStats = new StatFs(
+ Environment.getExternalStorageDirectory().getPath());
+ sdSize = (long)sdStats.getAvailableBlocks() *
+ (long)sdStats.getBlockSize();
+ // TODO check for thesholds here
+ return pkgLen <= sdSize;
+
+ }
+ private boolean checkInt(long pkgLen) {
+ StatFs intStats = new StatFs(Environment.getDataDirectory().getPath());
+ long intSize = (long)intStats.getBlockCount() *
+ (long)intStats.getBlockSize();
+ long iSize = (long)intStats.getAvailableBlocks() *
+ (long)intStats.getBlockSize();
+ // TODO check for thresholds here?
+ return pkgLen <= iSize;
+ }
+ 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 getInstallLoc(int flags, int expInstallLocation, long pkgLen) {
// Flags explicitly over ride everything else.
if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) {
- return false;
+ return INSTALL_LOC_INT;
} else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) {
- return true;
+ return INSTALL_LOC_SD;
+ } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
+ return INSTALL_LOC_INT;
}
// Manifest option takes precedence next
if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
- return true;
+ // TODO fitsonSd check
+ if (checkSd(pkgLen)) {
+ return INSTALL_LOC_SD;
+ }
+ if (checkInt(pkgLen)) {
+ return INSTALL_LOC_INT;
+ }
+ return INSTALL_LOC_ERR;
}
if (expInstallLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
- return false;
+ if (checkInt(pkgLen)) {
+ return INSTALL_LOC_INT;
+ }
+ return INSTALL_LOC_ERR;
}
- // TODO Out of memory checks here.
+ 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;
+ }
+ // Check for settings preference.
boolean checkSd = false;
int setLoc = 0;
try {
@@ -284,46 +349,63 @@ public class PackageManagerTests extends AndroidTestCase {
failStr(e);
}
if (userPref == APP_INSTALL_DEVICE) {
- checkSd = false;
+ if (checkInt(pkgLen)) {
+ return INSTALL_LOC_INT;
+ }
+ return INSTALL_LOC_ERR;
} else if (userPref == APP_INSTALL_SDCARD) {
- checkSd = true;
+ if (checkSd(pkgLen)) {
+ return INSTALL_LOC_SD;
+ }
+ return INSTALL_LOC_ERR;
} else if (userPref == APP_INSTALL_AUTO) {
- // Might be determined dynamically. TODO fix this
- checkSd = false;
+ if (checkInt(pkgLen)) {
+ return INSTALL_LOC_INT;
+ }
+ // Check for free memory externally
+ if (checkSd(pkgLen)) {
+ return INSTALL_LOC_SD;
+ }
+ return INSTALL_LOC_ERR;
+
}
- }
- return checkSd;
+ }
+ return INSTALL_LOC_ERR;
}
private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
try {
String pkgName = pkg.packageName;
- ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
- assertNotNull(info);
- assertEquals(pkgName, info.packageName);
- File dataDir = Environment.getDataDirectory();
- String appInstallPath = new File(dataDir, "app").getPath();
- String drmInstallPath = new File(dataDir, "app-private").getPath();
- File srcDir = new File(info.sourceDir);
- String srcPath = srcDir.getParent();
- File publicSrcDir = new File(info.publicSourceDir);
- String publicSrcPath = publicSrcDir.getParent();
-
- if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
- assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
- assertEquals(srcPath, drmInstallPath);
- assertEquals(publicSrcPath, appInstallPath);
- } else {
- assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
- if (!getInstallLoc(flags, expInstallLocation)) {
- assertEquals(srcPath, appInstallPath);
+ ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
+ assertNotNull(info);
+ assertEquals(pkgName, info.packageName);
+ File dataDir = Environment.getDataDirectory();
+ String appInstallPath = new File(dataDir, "app").getPath();
+ String drmInstallPath = new File(dataDir, "app-private").getPath();
+ File srcDir = new File(info.sourceDir);
+ String srcPath = srcDir.getParent();
+ File publicSrcDir = new File(info.publicSourceDir);
+ String publicSrcPath = publicSrcDir.getParent();
+ long pkgLen = new File(info.sourceDir).length();
+
+ if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
+ assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
+ assertEquals(srcPath, drmInstallPath);
assertEquals(publicSrcPath, appInstallPath);
- assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
} else {
- assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
- assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
- assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
+ assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
+ int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
+ if (rLoc == INSTALL_LOC_INT) {
+ assertEquals(srcPath, appInstallPath);
+ assertEquals(publicSrcPath, appInstallPath);
+ assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
+ } else if (rLoc == INSTALL_LOC_SD){
+ assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
+ assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
+ assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
+ } else {
+ // TODO handle error. Install should have failed.
+ }
}
- }
} catch (NameNotFoundException e) {
failStr("failed with exception : " + e);
}
@@ -396,8 +478,6 @@ public class PackageManagerTests extends AndroidTestCase {
} catch (Exception e) {
failStr(e);
}
- // Clean up the containers as well
- clearSecureContainersForPkg(pkg.packageName);
}
InstallParams ip = null;
try {
@@ -1047,19 +1127,6 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- public void xxxtestClearAllSecureContainers() {
- IMountService ms = getMs();
- try {
- String list[] = ms.getSecureContainerList();
- if (list != null) {
- for (String cid : list) {
- Log.i(TAG, "Destroying container " + cid);
- ms.destroySecureContainer(cid, false);
- }
- }
- } catch (RemoteException e) {}
- }
-
class MoveReceiver extends GenericReceiver {
String pkgName;
final static int INVALID = -1;
@@ -1185,7 +1252,7 @@ public class PackageManagerTests extends AndroidTestCase {
public void moveFromRawResource(int installFlags, int moveFlags,
int expRetCode) {
int origDefaultLoc = getInstallLoc();
- setInstallLoc(PackageInfo.INSTALL_LOCATION_AUTO);
+ setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
// Install first
InstallParams ip = sampleInstallFromRawResource(installFlags, false);
ApplicationInfo oldAppInfo = null;
@@ -1255,7 +1322,7 @@ public class PackageManagerTests extends AndroidTestCase {
// Try to install and make sure an error code is returned.
assertNull(installFromRawResource("install.apk", R.raw.install,
PackageManager.INSTALL_EXTERNAL, false,
- true, PackageManager.INSTALL_FAILED_CONTAINER_ERROR,
+ true, PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE,
PackageInfo.INSTALL_LOCATION_AUTO));
} finally {
// Restore original media state
@@ -1292,6 +1359,509 @@ public class PackageManagerTests extends AndroidTestCase {
}
/*---------- Recommended install location tests ----*/
+ /* Precedence: FlagManifestExistingUser
+ * PrecedenceSuffixes:
+ * Flag : FlagI, FlagE, FlagF
+ * I - internal, E - external, F - forward locked, Flag suffix absent if not using any option.
+ * Manifest: ManifestI, ManifestE, ManifestA, Manifest suffix absent if not using any option.
+ * Existing: Existing suffix absent if not existing.
+ * User: UserI, UserE, UserA, User suffix absent if not existing.
+ *
+ */
+ /*
+ * Install an app on internal flash
+ */
+ public void testFlagI() {
+ sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
+ }
+ /*
+ * Install an app on sdcard.
+ */
+ public void testFlagE() {
+ sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
+ }
+
+ /*
+ * Install an app on sdcard.
+ */
+ public void testFlagF() {
+ sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
+ }
+ /*
+ * Install an app with both internal and external flags set. should fail
+ */
+ public void testFlagIE() {
+ installFromRawResource("install.apk", R.raw.install,
+ PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
+ false,
+ true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+ PackageInfo.INSTALL_LOCATION_AUTO);
+ }
+
+ /*
+ * Install an app with both internal and external flags set. should fail
+ */
+ public void testFlagIF() {
+ sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK |
+ PackageManager.INSTALL_INTERNAL, true);
+ }
+ /*
+ * Install an app with both internal and external flags set. should fail
+ */
+ public void testFlagEF() {
+ installFromRawResource("install.apk", R.raw.install,
+ PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
+ false,
+ true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+ PackageInfo.INSTALL_LOCATION_AUTO);
+ }
+ /*
+ * Install an app with both internal and external flags set. should fail
+ */
+ public void testFlagIEF() {
+ installFromRawResource("install.apk", R.raw.install,
+ PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
+ PackageManager.INSTALL_EXTERNAL,
+ false,
+ true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+ PackageInfo.INSTALL_LOCATION_AUTO);
+ }
+ /*
+ * Install an app with both internal and manifest option set.
+ * should install on internal.
+ */
+ public void testFlagIManifestI() {
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ PackageManager.INSTALL_INTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ /*
+ * Install an app with both internal and manifest preference for
+ * preferExternal. Should install on internal.
+ */
+ public void testFlagIManifestE() {
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ PackageManager.INSTALL_INTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ /*
+ * Install an app with both internal and manifest preference for
+ * auto. should install internal.
+ */
+ public void testFlagIManifestA() {
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ PackageManager.INSTALL_INTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ /*
+ * Install an app with both external and manifest option set.
+ * should install externally.
+ */
+ public void testFlagEManifestI() {
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ PackageManager.INSTALL_EXTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ /*
+ * Install an app with both external and manifest preference for
+ * preferExternal. Should install externally.
+ */
+ public void testFlagEManifestE() {
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ PackageManager.INSTALL_EXTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ /*
+ * Install an app with both external and manifest preference for
+ * auto. should install on external media.
+ */
+ public void testFlagEManifestA() {
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ PackageManager.INSTALL_EXTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ /*
+ * Install an app with fwd locked flag set and install location set to
+ * internal. should install internally.
+ */
+ public void testFlagFManifestI() {
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ PackageManager.INSTALL_EXTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ /*
+ * Install an app with fwd locked flag set and install location set to
+ * preferExternal. should install internally.
+ */
+ public void testFlagFManifestE() {
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ PackageManager.INSTALL_EXTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ /*
+ * Install an app with fwd locked flag set and install location set to
+ * auto. should install internally.
+ */
+ public void testFlagFManifestA() {
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ PackageManager.INSTALL_EXTERNAL,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ /* The following test functions verify install location for existing apps.
+ * ie existing app can be installed internally or externally. If install
+ * flag is explicitly set it should override current location. If manifest location
+ * is set, that should over ride current location too. if not the existing install
+ * location should be honoured.
+ * testFlagI/E/F/ExistingI/E -
+ */
+ public void testFlagIExistingI() {
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ -1);
+ }
+ public void testFlagIExistingE() {
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ -1);
+ }
+ public void testFlagEExistingI() {
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ -1);
+ }
+ public void testFlagEExistingE() {
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ -1);
+ }
+ public void testFlagFExistingI() {
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ -1);
+ }
+ public void testFlagFExistingE() {
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ -1);
+ }
+ /*
+ * The following set of tests verify the installation of apps with
+ * install location attribute set to internalOnly, preferExternal and auto.
+ * The manifest option should dictate the install location.
+ * public void testManifestI/E/A
+ * TODO out of memory fall back behaviour.
+ */
+ public void testManifestI() {
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ 0,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ public void testManifestE() {
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ 0,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ public void testManifestA() {
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ 0,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ /*
+ * The following set of tests verify the installation of apps
+ * with install location attribute set to internalOnly, preferExternal and auto
+ * for already existing apps. The manifest option should take precedence.
+ * TODO add out of memory fall back behaviour.
+ * testManifestI/E/AExistingI/E
+ */
+ public void testManifestIExistingI() {
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ rFlags,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ public void testManifestIExistingE() {
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ rFlags,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ }
+ public void testManifestEExistingI() {
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ rFlags,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ public void testManifestEExistingE() {
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ rFlags,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ }
+ public void testManifestAExistingI() {
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ rFlags,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_AUTO);
+ }
+ public void testManifestAExistingE() {
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+ // First install.
+ installFromRawResource("install.apk", R.raw.install,
+ iFlags,
+ false,
+ false, -1,
+ -1);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ rFlags,
+ true,
+ false, -1,
+ PackageInfo.INSTALL_LOCATION_AUTO);
+ }
+ /*
+ * The following set of tests check install location for existing
+ * application based on user setting.
+ */
+ private void setExistingXUserX(int userSetting, int iFlags) {
+ 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;
+ }
+ int origSetting = getInstallLoc();
+ try {
+ // Set user setting
+ setInstallLoc(userSetting);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ rFlags,
+ true,
+ false, -1,
+ iloc);
+ } finally {
+ setInstallLoc(origSetting);
+ }
+ }
+ public void testExistingIUserI() {
+ int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ setExistingXUserX(userSetting, iFlags);
+ }
+ public void testExistingIUserE() {
+ int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ setExistingXUserX(userSetting, iFlags);
+ }
+ public void testExistingIUserA() {
+ int userSetting = PackageHelper.APP_INSTALL_AUTO;
+ int iFlags = PackageManager.INSTALL_INTERNAL;
+ setExistingXUserX(userSetting, iFlags);
+ }
+ public void testExistingEUserI() {
+ int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ setExistingXUserX(userSetting, iFlags);
+ }
+ public void testExistingEUserE() {
+ int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ setExistingXUserX(userSetting, iFlags);
+ }
+ public void testExistingEUserA() {
+ int userSetting = PackageHelper.APP_INSTALL_AUTO;
+ int iFlags = PackageManager.INSTALL_EXTERNAL;
+ setExistingXUserX(userSetting, iFlags);
+ }
+ /*
+ * 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;
+ }
+ try {
+ // Set user setting
+ setInstallLoc(userSetting);
+ // Replace now
+ installFromRawResource("install.apk", R.raw.install,
+ 0,
+ true,
+ false, -1,
+ iloc);
+ } finally {
+ setInstallLoc(origSetting);
+ }
+ }
+ public void testUserI() {
+ int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
+ setUserX(userSetting);
+ }
+ public void testUserE() {
+ int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+ setUserX(userSetting);
+ }
+ public void testUserA() {
+ int userSetting = PackageHelper.APP_INSTALL_AUTO;
+ setUserX(userSetting);
+ }
/*
* TODO's
* check version numbers for upgrades