diff options
author | Jeff Sharkey <jsharkey@android.com> | 2014-07-16 20:49:40 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-07-16 16:25:13 +0000 |
commit | c0844bef3e743ecc40a12ad7f5a7c20b3aaacede (patch) | |
tree | 4d12c54cee047c33f5d8f96eb6de8a9636d6cbde | |
parent | 8b4649c2e6a5d2b806c28c75b217dd1535cc788b (diff) | |
parent | 9a445771f57dd15b06db0dbefd66c368d84eec2d (diff) | |
download | frameworks_base-c0844bef3e743ecc40a12ad7f5a7c20b3aaacede.zip frameworks_base-c0844bef3e743ecc40a12ad7f5a7c20b3aaacede.tar.gz frameworks_base-c0844bef3e743ecc40a12ad7f5a7c20b3aaacede.tar.bz2 |
Merge "Install sessions only inherit APK files." into lmp-dev
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; |