am 2158503f: Merge "Install sessions only inherit APK files." into lmp-dev

* commit '2158503ff835f60d1a39f5bac724dd90e0900403':
  Install sessions only inherit APK files.
This commit is contained in:
Jeff Sharkey
2014-07-17 16:45:19 +00:00
committed by Android Git Automerger
4 changed files with 46 additions and 38 deletions

View File

@@ -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 {

View File

@@ -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();
}

View File

@@ -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");
}
}
int n = 0;
final File[] oldFiles = new File(app.getCodePath()).listFiles();
if (!ArrayUtils.isEmpty(oldFiles)) {
for (File oldFile : oldFiles) {
if (!PackageParser.isApkFile(oldFile)) continue;
/**
* 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());
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

View File

@@ -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;