Loading cmds/pm/src/com/android/commands/pm/Pm.java +6 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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 { Loading services/core/java/com/android/server/pm/PackageInstallerService.java +21 −5 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -344,19 +348,30 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } void dump(IndentingPrintWriter pw) { synchronized (mSessions) { pw.println("Active install sessions:"); pw.increaseIndent(); synchronized (mSessions) { final int N = mSessions.size(); 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(); } } class Callback { public void onSessionProgress(PackageInstallerSession session, int progress) { Loading @@ -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(); } Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +16 −25 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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()); int n = 0; final File[] oldFiles = new File(app.getCodePath()).listFiles(); if (!ArrayUtils.isEmpty(oldFiles)) { for (File oldFile : oldFiles) { if (!PackageParser.isApkFile(oldFile)) continue; final File newFile = new File(sessionStageDir, oldFile.getName()); try { linkTreeIgnoringExisting(existingDir, sessionStageDir); Os.link(oldFile.getAbsolutePath(), newFile.getAbsolutePath()); n++; } catch (ErrnoException e) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Failed to splice into stage"); "Failed to splice into stage", e); } } /** * 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()); } } if (LOGD) Slog.d(TAG, "Spliced " + n + " existing APKs into stage"); } @Override Loading services/core/java/com/android/server/pm/PackageManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading
cmds/pm/src/com/android/commands/pm/Pm.java +6 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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 { Loading
services/core/java/com/android/server/pm/PackageInstallerService.java +21 −5 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -344,19 +348,30 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } void dump(IndentingPrintWriter pw) { synchronized (mSessions) { pw.println("Active install sessions:"); pw.increaseIndent(); synchronized (mSessions) { final int N = mSessions.size(); 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(); } } class Callback { public void onSessionProgress(PackageInstallerSession session, int progress) { Loading @@ -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(); } Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +16 −25 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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()); int n = 0; final File[] oldFiles = new File(app.getCodePath()).listFiles(); if (!ArrayUtils.isEmpty(oldFiles)) { for (File oldFile : oldFiles) { if (!PackageParser.isApkFile(oldFile)) continue; final File newFile = new File(sessionStageDir, oldFile.getName()); try { linkTreeIgnoringExisting(existingDir, sessionStageDir); Os.link(oldFile.getAbsolutePath(), newFile.getAbsolutePath()); n++; } catch (ErrnoException e) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Failed to splice into stage"); "Failed to splice into stage", e); } } /** * 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()); } } if (LOGD) Slog.d(TAG, "Spliced " + n + " existing APKs into stage"); } @Override Loading
services/core/java/com/android/server/pm/PackageManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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; Loading