Loading services/core/java/com/android/server/pm/InstallPackageHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -2919,7 +2919,7 @@ final class InstallPackageHelper { mPm.scheduleDeferredNoKillPostDelete(args); if (Flags.improveInstallDontKill()) { synchronized (mPm.mInstallLock) { PackageManagerServiceUtils.linkSplitsToOldDirs(mPm.mInstaller, PackageManagerServiceUtils.linkFilesToOldDirs(mPm.mInstaller, packageName, pkgSetting.getPath(), pkgSetting.getOldPaths()); } } Loading services/core/java/com/android/server/pm/PackageManagerService.java +2 −0 Original line number Diff line number Diff line Loading @@ -598,6 +598,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final int DEFAULT_FILE_ACCESS_MODE = 0644; static final int DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE = 0755; final Handler mHandler; final Handler mBackgroundHandler; Loading services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +91 −37 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.content.pm.SigningDetails.CertCapabilities.SHARED_USER_ID; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDWR; import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH; import static com.android.server.LocalManagerRegistry.ManagerNotFoundException; Loading @@ -31,6 +32,7 @@ import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION; import static com.android.server.pm.PackageManagerService.DEBUG_INTENT_MATCHING; import static com.android.server.pm.PackageManagerService.DEBUG_PREFERRED; import static com.android.server.pm.PackageManagerService.DEFAULT_FILE_ACCESS_MODE; import static com.android.server.pm.PackageManagerService.DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE; import static com.android.server.pm.PackageManagerService.RANDOM_CODEPATH_PREFIX; import static com.android.server.pm.PackageManagerService.RANDOM_DIR_PREFIX; import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME; Loading Loading @@ -1554,7 +1556,7 @@ public class PackageManagerServiceUtils { return initiatingPackageName == null || SHELL_PACKAGE_NAME.equals(initiatingPackageName); } public static void linkSplitsToOldDirs(@NonNull Installer installer, public static void linkFilesToOldDirs(@NonNull Installer installer, @NonNull String packageName, @NonNull File newPath, @Nullable Set<File> oldPaths) { Loading @@ -1569,56 +1571,108 @@ public class PackageManagerServiceUtils { if (filesInNewPath == null || filesInNewPath.length == 0) { return; } final List<String> splitApkNames = new ArrayList<String>(); for (int i = 0; i < filesInNewPath.length; i++) { if (!filesInNewPath[i].isDirectory() && filesInNewPath[i].toString().endsWith(".apk")) { splitApkNames.add(filesInNewPath[i].getName()); final List<File> splitApks = new ArrayList<>(); for (File file : filesInNewPath) { if (!file.isDirectory() && file.toString().endsWith(".apk")) { splitApks.add(file); } } final int numSplits = splitApkNames.size(); if (numSplits == 0) { if (splitApks.isEmpty()) { return; } final File[] splitApkNames = splitApks.toArray(new File[0]); for (File oldPath : oldPaths) { if (!oldPath.exists()) { continue; } for (int i = 0; i < numSplits; i++) { final String splitApkName = splitApkNames.get(i); final File linkedSplit = new File(oldPath, splitApkName); if (linkedSplit.exists()) { linkFilesAndSetModes(installer, packageName, newPath, oldPath, splitApkNames, DEFAULT_FILE_ACCESS_MODE); linkNativeLibraries(installer, packageName, newPath, oldPath, LIB_DIR_NAME); linkNativeLibraries(installer, packageName, newPath, oldPath, LIB64_DIR_NAME); } } private static void linkNativeLibraries(@NonNull Installer installer, @NonNull String packageName, @NonNull File sourcePath, @NonNull File targetPath, @NonNull String libDirName) { final File sourceLibDir = new File(sourcePath, libDirName); if (!sourceLibDir.exists()) { return; } final File targetLibDir = new File(targetPath, libDirName); if (!targetLibDir.exists()) { try { NativeLibraryHelper.createNativeLibrarySubdir(targetLibDir); } catch (IOException e) { Slog.w(PackageManagerService.TAG, "Failed to create native library dir at <" + targetLibDir + ">", e); return; } } final File[] archs = sourceLibDir.listFiles(); if (archs == null) { return; } for (File arch : archs) { final File targetArchDir = new File(targetLibDir, arch.getName()); if (!targetArchDir.exists()) { try { NativeLibraryHelper.createNativeLibrarySubdir(targetArchDir); } catch (IOException e) { Slog.w(PackageManagerService.TAG, "Failed to create native library subdir at <" + targetArchDir + ">", e); continue; } } final File sourceArchDir = new File(sourceLibDir, arch.getName()); final File[] files = sourceArchDir.listFiles(); if (files == null || files.length == 0) { continue; } linkFilesAndSetModes(installer, packageName, sourceArchDir, targetArchDir, files, DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE); } } // Link the files with specified names from under the sourcePath to be under the targetPath private static void linkFilesAndSetModes(@NonNull Installer installer, String packageName, @NonNull File sourcePath, @NonNull File targetPath, @NonNull File[] files, int mode) { for (File file : files) { final String fileName = file.getName(); final File sourceFile = new File(sourcePath, fileName); final File targetFile = new File(targetPath, fileName); if (targetFile.exists()) { if (DEBUG) { Slog.d(PackageManagerService.TAG, "Skipping existing linked split <" + linkedSplit + ">"); Slog.d(PackageManagerService.TAG, "Skipping existing linked file <" + targetFile + ">"); } continue; } final File sourceSplit = new File(newPath, splitApkName); try { installer.linkFile(packageName, splitApkName, newPath.getAbsolutePath(), oldPath.getAbsolutePath()); installer.linkFile(packageName, fileName, sourcePath.getAbsolutePath(), targetPath.getAbsolutePath()); if (DEBUG) { Slog.d(PackageManagerService.TAG, "Linked <" + sourceSplit + "> to <" + linkedSplit + ">"); + sourceFile + "> to <" + targetFile + ">"); } } catch (Installer.InstallerException e) { Slog.w(PackageManagerService.TAG, "Failed to link split <" + sourceSplit + " > to <" + linkedSplit + ">", e); Slog.w(PackageManagerService.TAG, "Failed to link native library <" + sourceFile + "> to <" + targetFile + ">", e); continue; } try { Os.chmod(linkedSplit.getAbsolutePath(), DEFAULT_FILE_ACCESS_MODE); Os.chmod(targetFile.getAbsolutePath(), mode); } catch (ErrnoException e) { Slog.w(PackageManagerService.TAG, "Failed to set mode for linked split <" + linkedSplit + ">", e); Slog.w(PackageManagerService.TAG, "Failed to set mode for linked file <" + targetFile + ">", e); continue; } if (!SELinux.restorecon(linkedSplit)) { Slog.w(PackageManagerService.TAG, "Failed to restorecon for linked split <" + linkedSplit + ">"); } if (!SELinux.restorecon(targetFile)) { Slog.w(PackageManagerService.TAG, "Failed to restorecon for linked file <" + targetFile + ">"); } } //TODO(b/291212866): support native libs } } Loading
services/core/java/com/android/server/pm/InstallPackageHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -2919,7 +2919,7 @@ final class InstallPackageHelper { mPm.scheduleDeferredNoKillPostDelete(args); if (Flags.improveInstallDontKill()) { synchronized (mPm.mInstallLock) { PackageManagerServiceUtils.linkSplitsToOldDirs(mPm.mInstaller, PackageManagerServiceUtils.linkFilesToOldDirs(mPm.mInstaller, packageName, pkgSetting.getPath(), pkgSetting.getOldPaths()); } } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +2 −0 Original line number Diff line number Diff line Loading @@ -598,6 +598,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final int DEFAULT_FILE_ACCESS_MODE = 0644; static final int DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE = 0755; final Handler mHandler; final Handler mBackgroundHandler; Loading
services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +91 −37 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.content.pm.SigningDetails.CertCapabilities.SHARED_USER_ID; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDWR; import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH; import static com.android.server.LocalManagerRegistry.ManagerNotFoundException; Loading @@ -31,6 +32,7 @@ import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION; import static com.android.server.pm.PackageManagerService.DEBUG_INTENT_MATCHING; import static com.android.server.pm.PackageManagerService.DEBUG_PREFERRED; import static com.android.server.pm.PackageManagerService.DEFAULT_FILE_ACCESS_MODE; import static com.android.server.pm.PackageManagerService.DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE; import static com.android.server.pm.PackageManagerService.RANDOM_CODEPATH_PREFIX; import static com.android.server.pm.PackageManagerService.RANDOM_DIR_PREFIX; import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME; Loading Loading @@ -1554,7 +1556,7 @@ public class PackageManagerServiceUtils { return initiatingPackageName == null || SHELL_PACKAGE_NAME.equals(initiatingPackageName); } public static void linkSplitsToOldDirs(@NonNull Installer installer, public static void linkFilesToOldDirs(@NonNull Installer installer, @NonNull String packageName, @NonNull File newPath, @Nullable Set<File> oldPaths) { Loading @@ -1569,56 +1571,108 @@ public class PackageManagerServiceUtils { if (filesInNewPath == null || filesInNewPath.length == 0) { return; } final List<String> splitApkNames = new ArrayList<String>(); for (int i = 0; i < filesInNewPath.length; i++) { if (!filesInNewPath[i].isDirectory() && filesInNewPath[i].toString().endsWith(".apk")) { splitApkNames.add(filesInNewPath[i].getName()); final List<File> splitApks = new ArrayList<>(); for (File file : filesInNewPath) { if (!file.isDirectory() && file.toString().endsWith(".apk")) { splitApks.add(file); } } final int numSplits = splitApkNames.size(); if (numSplits == 0) { if (splitApks.isEmpty()) { return; } final File[] splitApkNames = splitApks.toArray(new File[0]); for (File oldPath : oldPaths) { if (!oldPath.exists()) { continue; } for (int i = 0; i < numSplits; i++) { final String splitApkName = splitApkNames.get(i); final File linkedSplit = new File(oldPath, splitApkName); if (linkedSplit.exists()) { linkFilesAndSetModes(installer, packageName, newPath, oldPath, splitApkNames, DEFAULT_FILE_ACCESS_MODE); linkNativeLibraries(installer, packageName, newPath, oldPath, LIB_DIR_NAME); linkNativeLibraries(installer, packageName, newPath, oldPath, LIB64_DIR_NAME); } } private static void linkNativeLibraries(@NonNull Installer installer, @NonNull String packageName, @NonNull File sourcePath, @NonNull File targetPath, @NonNull String libDirName) { final File sourceLibDir = new File(sourcePath, libDirName); if (!sourceLibDir.exists()) { return; } final File targetLibDir = new File(targetPath, libDirName); if (!targetLibDir.exists()) { try { NativeLibraryHelper.createNativeLibrarySubdir(targetLibDir); } catch (IOException e) { Slog.w(PackageManagerService.TAG, "Failed to create native library dir at <" + targetLibDir + ">", e); return; } } final File[] archs = sourceLibDir.listFiles(); if (archs == null) { return; } for (File arch : archs) { final File targetArchDir = new File(targetLibDir, arch.getName()); if (!targetArchDir.exists()) { try { NativeLibraryHelper.createNativeLibrarySubdir(targetArchDir); } catch (IOException e) { Slog.w(PackageManagerService.TAG, "Failed to create native library subdir at <" + targetArchDir + ">", e); continue; } } final File sourceArchDir = new File(sourceLibDir, arch.getName()); final File[] files = sourceArchDir.listFiles(); if (files == null || files.length == 0) { continue; } linkFilesAndSetModes(installer, packageName, sourceArchDir, targetArchDir, files, DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE); } } // Link the files with specified names from under the sourcePath to be under the targetPath private static void linkFilesAndSetModes(@NonNull Installer installer, String packageName, @NonNull File sourcePath, @NonNull File targetPath, @NonNull File[] files, int mode) { for (File file : files) { final String fileName = file.getName(); final File sourceFile = new File(sourcePath, fileName); final File targetFile = new File(targetPath, fileName); if (targetFile.exists()) { if (DEBUG) { Slog.d(PackageManagerService.TAG, "Skipping existing linked split <" + linkedSplit + ">"); Slog.d(PackageManagerService.TAG, "Skipping existing linked file <" + targetFile + ">"); } continue; } final File sourceSplit = new File(newPath, splitApkName); try { installer.linkFile(packageName, splitApkName, newPath.getAbsolutePath(), oldPath.getAbsolutePath()); installer.linkFile(packageName, fileName, sourcePath.getAbsolutePath(), targetPath.getAbsolutePath()); if (DEBUG) { Slog.d(PackageManagerService.TAG, "Linked <" + sourceSplit + "> to <" + linkedSplit + ">"); + sourceFile + "> to <" + targetFile + ">"); } } catch (Installer.InstallerException e) { Slog.w(PackageManagerService.TAG, "Failed to link split <" + sourceSplit + " > to <" + linkedSplit + ">", e); Slog.w(PackageManagerService.TAG, "Failed to link native library <" + sourceFile + "> to <" + targetFile + ">", e); continue; } try { Os.chmod(linkedSplit.getAbsolutePath(), DEFAULT_FILE_ACCESS_MODE); Os.chmod(targetFile.getAbsolutePath(), mode); } catch (ErrnoException e) { Slog.w(PackageManagerService.TAG, "Failed to set mode for linked split <" + linkedSplit + ">", e); Slog.w(PackageManagerService.TAG, "Failed to set mode for linked file <" + targetFile + ">", e); continue; } if (!SELinux.restorecon(linkedSplit)) { Slog.w(PackageManagerService.TAG, "Failed to restorecon for linked split <" + linkedSplit + ">"); } if (!SELinux.restorecon(targetFile)) { Slog.w(PackageManagerService.TAG, "Failed to restorecon for linked file <" + targetFile + ">"); } } //TODO(b/291212866): support native libs } }