summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcore/tests/coretests/src/android/content/pm/PackageManagerTests.java11
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java11
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java139
3 files changed, 131 insertions, 30 deletions
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 8a5f8bb..77e4986 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -1229,9 +1229,8 @@ public class PackageManagerTests extends AndroidTestCase {
installFromRawResource("install.apk", R.raw.install_loc_unspecified,
PackageManager.INSTALL_FORWARD_LOCK |
- PackageManager.INSTALL_EXTERNAL, true, true,
- PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
- PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ PackageManager.INSTALL_EXTERNAL, true, false, -1,
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
@LargeTest
@@ -1626,8 +1625,8 @@ public class PackageManagerTests extends AndroidTestCase {
int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
- boolean fail = true;
- int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
+ boolean fail = false;
+ int result = PackageManager.MOVE_SUCCEEDED;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
}
@@ -1950,7 +1949,7 @@ public class PackageManagerTests extends AndroidTestCase {
PackageManager.INSTALL_FORWARD_LOCK,
true,
false, -1,
- PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ PackageInfo.INSTALL_LOCATION_AUTO);
}
/* The following test functions verify install location for existing apps.
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 3eec18c..c709e40 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -311,6 +311,14 @@ public class DefaultContainerService extends IntentService {
return null;
}
+ try {
+ Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
+ } catch (ErrnoException e) {
+ Slog.e(TAG, "Could not chown APK: " + e.getMessage());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+
if (isForwardLocked) {
File publicZipFile = new File(newCachePath, publicResFileName);
try {
@@ -326,10 +334,9 @@ public class DefaultContainerService extends IntentService {
}
try {
- Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644);
} catch (ErrnoException e) {
- Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage());
+ Slog.e(TAG, "Could not chown public resource file: " + e.getMessage());
PackageHelper.destroySdDir(newCid);
return null;
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 21ae624..b5d0b60 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -5863,9 +5863,28 @@ public class PackageManagerService extends IPackageManager.Stub {
Log.w(TAG, "Insufficient storage to install");
return;
}
- // Create the file args now.
+
+ mRet = srcArgs.doPreCopy();
+ if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+ return;
+ }
+
mRet = targetArgs.copyApk(mContainerService, false);
- targetArgs.doPreInstall(mRet);
+ if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+ srcArgs.doPostCopy(uid);
+ return;
+ }
+
+ mRet = srcArgs.doPostCopy(uid);
+ if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+ return;
+ }
+
+ mRet = targetArgs.doPreInstall(mRet);
+ if (mRet != PackageManager.INSTALL_SUCCEEDED) {
+ return;
+ }
+
if (DEBUG_SD_INSTALL) {
StringBuilder builder = new StringBuilder();
if (srcArgs != null) {
@@ -5936,7 +5955,7 @@ public class PackageManagerService extends IPackageManager.Stub {
String nativeLibraryPath) {
if (installOnSd(flags) || installForwardLocked(flags)) {
return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
- (flags & PackageManager.INSTALL_EXTERNAL) != 0);
+ installOnSd(flags), installForwardLocked(flags));
} else {
return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
}
@@ -5945,9 +5964,10 @@ public class PackageManagerService extends IPackageManager.Stub {
// Used by package mover
private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
if (installOnSd(flags) || installForwardLocked(flags)) {
- String cid = getNextCodePath(null, pkgName, "/" + AsecInstallArgs.RES_FILE_NAME);
- return new AsecInstallArgs(packageURI, cid,
- (flags & PackageManager.INSTALL_EXTERNAL) != 0);
+ String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
+ + AsecInstallArgs.RES_FILE_NAME);
+ return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
+ installForwardLocked(flags));
} else {
return new FileInstallArgs(packageURI, pkgName, dataDir);
}
@@ -5984,6 +6004,26 @@ public class PackageManagerService extends IPackageManager.Stub {
abstract boolean doPostDeleteLI(boolean delete);
abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
+ /**
+ * Called before the source arguments are copied. This is used mostly
+ * for MoveParams when it needs to read the source file to put it in the
+ * destination.
+ */
+ int doPreCopy() {
+ return PackageManager.INSTALL_SUCCEEDED;
+ }
+
+ /**
+ * Called after the source arguments are copied. This is used mostly for
+ * MoveParams when it needs to read the source file to put it in the
+ * destination.
+ *
+ * @return
+ */
+ int doPostCopy(int uid) {
+ return PackageManager.INSTALL_SUCCEEDED;
+ }
+
protected boolean isFwdLocked() {
return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
}
@@ -6280,8 +6320,9 @@ public class PackageManagerService extends IPackageManager.Stub {
}
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
- boolean isExternal) {
- super(null, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null);
+ boolean isExternal, boolean isForwardLocked) {
+ super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
+ | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null);
// Extract cid from fullCodePath
int eidx = fullCodePath.lastIndexOf("/");
String subStr1 = fullCodePath.substring(0, eidx);
@@ -6296,8 +6337,9 @@ public class PackageManagerService extends IPackageManager.Stub {
setCachePath(PackageHelper.getSdDir(cid));
}
- AsecInstallArgs(Uri packageURI, String cid, boolean isExternal) {
- super(packageURI, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null);
+ AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
+ super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
+ | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null);
this.cid = cid;
}
@@ -6443,8 +6485,18 @@ public class PackageManagerService extends IPackageManager.Stub {
if (status != PackageManager.INSTALL_SUCCEEDED) {
cleanUp();
} else {
+ final int groupOwner;
+ final String protectedFile;
+ if (isFwdLocked()) {
+ groupOwner = uid;
+ protectedFile = RES_FILE_NAME;
+ } else {
+ groupOwner = -1;
+ protectedFile = null;
+ }
+
if (uid < Process.FIRST_APPLICATION_UID
- || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
+ || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
Slog.e(TAG, "Failed to finalize " + cid);
PackageHelper.destroySdDir(cid);
return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
@@ -6505,6 +6557,33 @@ public class PackageManagerService extends IPackageManager.Stub {
}
return ret;
}
+
+ @Override
+ int doPreCopy() {
+ if (isFwdLocked()) {
+ if (!PackageHelper.fixSdPermissions(cid,
+ getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
+ return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
+ }
+ }
+
+ return PackageManager.INSTALL_SUCCEEDED;
+ }
+
+ @Override
+ int doPostCopy(int uid) {
+ if (isFwdLocked()) {
+ PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME);
+ if (uid < Process.FIRST_APPLICATION_UID
+ || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
+ Slog.e(TAG, "Failed to finalize " + cid);
+ PackageHelper.destroySdDir(cid);
+ return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
+ }
+ }
+
+ return PackageManager.INSTALL_SUCCEEDED;
+ }
};
// Utility method used to create code paths based on package name and available index.
@@ -8696,9 +8775,15 @@ public class PackageManagerService extends IPackageManager.Stub {
: PackageManager.INSTALL_INTERNAL;
currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
: PackageManager.INSTALL_INTERNAL;
+
if (newFlags == currFlags) {
Slog.w(TAG, "No move required. Trying to move to same location");
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+ } else {
+ if (isForwardLocked(pkg)) {
+ currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+ newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+ }
}
}
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
@@ -8784,21 +8869,31 @@ public class PackageManagerService extends IPackageManager.Stub {
final String newNativePath = mp.targetArgs
.getNativeLibraryPath();
- if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) {
- if (mInstaller
- .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
- returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ try {
+ final File newNativeDir = new File(newNativePath);
+
+ final String libParentDir = newNativeDir.getParentFile()
+ .getCanonicalPath();
+ if (newNativeDir.getParentFile().getCanonicalPath()
+ .equals(pkg.applicationInfo.dataDir)) {
+ if (mInstaller
+ .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
+ returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ } else {
+ NativeLibraryHelper.copyNativeBinariesIfNeededLI(
+ new File(newCodePath), newNativeDir);
+ }
} else {
- NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
- newCodePath), new File(newNativePath));
- }
- } else {
- if (mInstaller.linkNativeLibraryDirectory(
- pkg.applicationInfo.dataDir, newNativePath) < 0) {
- returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ if (mInstaller.linkNativeLibraryDirectory(
+ pkg.applicationInfo.dataDir, newNativePath) < 0) {
+ returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ }
}
+ } catch (IOException e) {
+ returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
}
+
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
pkg.mPath = newCodePath;
// Move dex files around