summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2014-07-16 20:49:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-16 16:25:13 +0000
commitc0844bef3e743ecc40a12ad7f5a7c20b3aaacede (patch)
tree4d12c54cee047c33f5d8f96eb6de8a9636d6cbde
parent8b4649c2e6a5d2b806c28c75b217dd1535cc788b (diff)
parent9a445771f57dd15b06db0dbefd66c368d84eec2d (diff)
downloadframeworks_base-c0844bef3e743ecc40a12ad7f5a7c20b3aaacede.zip
frameworks_base-c0844bef3e743ecc40a12ad7f5a7c20b3aaacede.tar.gz
frameworks_base-c0844bef3e743ecc40a12ad7f5a7c20b3aaacede.tar.bz2
Merge "Install sessions only inherit APK files." into lmp-dev
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java26
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java41
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java6
4 files changed, 46 insertions, 38 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b7f1ff9..d6c17ae 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -998,8 +998,8 @@ public final class Pm {
final InstallSessionParams params = new InstallSessionParams();
params.installFlags = PackageManager.INSTALL_ALL_USERS;
- params.mode = InstallSessionParams.MODE_FULL_INSTALL;
- params.progressMax = -1;
+ params.setModeFullInstall();
+ params.setProgressMax(-1);
String opt;
while ((opt = nextOption()) != null) {
@@ -1021,10 +1021,11 @@ public final class Pm {
} else if (opt.equals("-d")) {
params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
} else if (opt.equals("-p")) {
- params.mode = InstallSessionParams.MODE_INHERIT_EXISTING;
+ params.setModeInheritExisting();
} else if (opt.equals("-S")) {
- params.deltaSize = Long.parseLong(nextOptionData());
- params.progressMax = (int) params.deltaSize;
+ final long deltaSize = Long.parseLong(nextOptionData());
+ params.setDeltaSize(deltaSize);
+ params.setProgressMax((int) params.deltaSize);
} else if (opt.equals("--abi")) {
params.abiOverride = checkAbiArgument(nextOptionData());
} else {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 190e87c..db915e2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -76,6 +76,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
@GuardedBy("mSessions")
private final SparseArray<PackageInstallerSession> mSessions = new SparseArray<>();
+ /** Historical sessions kept around for debugging purposes */
+ @GuardedBy("mSessions")
+ private final SparseArray<PackageInstallerSession> mHistoricalSessions = new SparseArray<>();
+
private RemoteCallbackList<IPackageInstallerObserver> mObservers = new RemoteCallbackList<>();
private static final FilenameFilter sStageFilter = new FilenameFilter() {
@@ -344,18 +348,29 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
}
void dump(IndentingPrintWriter pw) {
- pw.println("Active install sessions:");
- pw.increaseIndent();
synchronized (mSessions) {
- final int N = mSessions.size();
+ pw.println("Active install sessions:");
+ pw.increaseIndent();
+ int N = mSessions.size();
for (int i = 0; i < N; i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
session.dump(pw);
pw.println();
}
+ pw.println();
+ pw.decreaseIndent();
+
+ pw.println("Historical install sessions:");
+ pw.increaseIndent();
+ N = mHistoricalSessions.size();
+ for (int i = 0; i < N; i++) {
+ final PackageInstallerSession session = mHistoricalSessions.valueAt(i);
+ session.dump(pw);
+ pw.println();
+ }
+ pw.println();
+ pw.decreaseIndent();
}
- pw.println();
- pw.decreaseIndent();
}
class Callback {
@@ -367,6 +382,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
notifySessionFinished(session.sessionId, success);
synchronized (mSessions) {
mSessions.remove(session.sessionId);
+ mHistoricalSessions.put(session.sessionId, session);
}
writeSessionsAsync();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 31d9704..0e6a3f0 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -65,6 +65,7 @@ import java.util.ArrayList;
public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String TAG = "PackageInstaller";
+ private static final boolean LOGD = true;
// TODO: enforce INSTALL_ALLOW_TEST
// TODO: enforce INSTALL_ALLOW_DOWNGRADE
@@ -435,35 +436,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/
private void spliceExistingFilesIntoStage() throws PackageManagerException {
final ApplicationInfo app = mPm.getApplicationInfo(mPackageName, 0, userId);
- final File existingDir = new File(app.getBaseCodePath());
- try {
- linkTreeIgnoringExisting(existingDir, sessionStageDir);
- } catch (ErrnoException e) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Failed to splice into stage");
- }
- }
-
- /**
- * Recursively hard link all files from source directory tree to target.
- * When a file already exists in the target tree, it leaves that file
- * intact.
- */
- private void linkTreeIgnoringExisting(File sourceDir, File targetDir) throws ErrnoException {
- final File[] sourceContents = sourceDir.listFiles();
- if (ArrayUtils.isEmpty(sourceContents)) return;
-
- for (File sourceFile : sourceContents) {
- final File targetFile = new File(targetDir, sourceFile.getName());
+ int n = 0;
+ final File[] oldFiles = new File(app.getCodePath()).listFiles();
+ if (!ArrayUtils.isEmpty(oldFiles)) {
+ for (File oldFile : oldFiles) {
+ if (!PackageParser.isApkFile(oldFile)) continue;
- if (sourceFile.isDirectory()) {
- targetFile.mkdir();
- linkTreeIgnoringExisting(sourceFile, targetFile);
- } else {
- Libcore.os.link(sourceFile.getAbsolutePath(), targetFile.getAbsolutePath());
+ final File newFile = new File(sessionStageDir, oldFile.getName());
+ try {
+ Os.link(oldFile.getAbsolutePath(), newFile.getAbsolutePath());
+ n++;
+ } catch (ErrnoException e) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Failed to splice into stage", e);
+ }
}
}
+
+ if (LOGD) Slog.d(TAG, "Spliced " + n + " existing APKs into stage");
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0ad3a68..727cff0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10026,9 +10026,6 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- // Nuke any cached code
- deleteCodeCacheDirsLI(pkgName);
-
boolean sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
@@ -10066,6 +10063,7 @@ public class PackageManagerService extends IPackageManager.Stub {
deletedPkg = false;
} else {
// Successfully deleted the old package. Now proceed with re-installation
+ deleteCodeCacheDirsLI(pkgName);
try {
final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user, abiOverride);
@@ -10177,6 +10175,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
// Successfully disabled the old package. Now proceed with re-installation
+ deleteCodeCacheDirsLI(packageName);
+
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;