Loading core/java/android/content/pm/ApplicationInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -413,6 +413,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** * Full path to the base APK for this application. */ // TODO: verify that nobody is doing codePath comparisons against this public String sourceDir; /** Loading core/java/android/content/pm/PackageParser.java +38 −29 Original line number Diff line number Diff line Loading @@ -279,11 +279,11 @@ public class PackageParser { mMetrics = metrics; } private static final boolean isPackageFilename(File file) { public static final boolean isPackageFilename(File file) { return isPackageFilename(file.getName()); } private static final boolean isPackageFilename(String name) { public static final boolean isPackageFilename(String name) { return name.endsWith(".apk"); } Loading Loading @@ -552,7 +552,7 @@ public class PackageParser { * Note that this <em>does not</em> perform signature verification; that * must be done separately in {@link #collectCertificates(Package, int)}. */ public Package parseSplitPackage(File apkDir, int flags) throws PackageParserException { public Package parseClusterPackage(File apkDir, int flags) throws PackageParserException { final File[] files = apkDir.listFiles(); if (ArrayUtils.isEmpty(files)) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, Loading Loading @@ -600,27 +600,23 @@ public class PackageParser { "Missing base APK in " + apkDir); } // Always apply deterministic ordering based on splitName final int size = apks.size(); final String[] splitNames = apks.keySet().toArray(new String[size]); Arrays.sort(splitNames, sSplitNameComparator); final File[] splitFiles = new File[size]; for (int i = 0; i < size; i++) { splitFiles[i] = apks.get(splitNames[i]); } final Package pkg = parseBaseApk(baseFile, flags); if (pkg == null) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, "Failed to parse base APK: " + baseFile); } for (File splitFile : splitFiles) { parseSplitApk(pkg, splitFile, flags); // Always apply deterministic ordering based on splitName final int size = apks.size(); final String[] splitNames = apks.keySet().toArray(new String[size]); Arrays.sort(splitNames, sSplitNameComparator); for (String splitName : splitNames) { final File splitFile = apks.get(splitName); parseSplitApk(pkg, splitFile, splitName, flags); } pkg.codePath = apkDir.getAbsolutePath(); return pkg; } Loading @@ -632,11 +628,12 @@ public class PackageParser { */ public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException { final Package pkg = parseBaseApk(apkFile, flags); if (pkg != null) { return pkg; } else { if (pkg == null) { throw new PackageParserException(mParseError, "Failed to parse " + apkFile); } pkg.codePath = apkFile.getAbsolutePath(); return pkg; } private Package parseBaseApk(File apkFile, int flags) { Loading Loading @@ -723,19 +720,22 @@ public class PackageParser { parser.close(); assmgr.close(); pkg.codePath = apkPath; pkg.baseCodePath = apkPath; pkg.mSignatures = null; return pkg; } private void parseSplitApk(Package pkg, File apkFile, int flags) throws PackageParserException { final String apkPath = apkFile.getAbsolutePath(); private void parseSplitApk(Package pkg, File apkFile, String splitName, int flags) throws PackageParserException { final String splitCodePath = apkFile.getAbsolutePath(); mArchiveSourcePath = apkFile.getAbsolutePath(); // TODO: expand split APK parsing // TODO: extract splitName during parse pkg.splitNames = ArrayUtils.appendElement(String.class, pkg.splitNames, splitName); pkg.splitCodePaths = ArrayUtils.appendElement(String.class, pkg.splitCodePaths, apkFile.getAbsolutePath()); splitCodePath); } /** Loading @@ -748,7 +748,7 @@ public class PackageParser { // TODO: extend to gather digest for split APKs try { final StrictJarFile jarFile = new StrictJarFile(pkg.codePath); final StrictJarFile jarFile = new StrictJarFile(pkg.baseCodePath); try { final ZipEntry je = jarFile.findEntry(ANDROID_MANIFEST_FILENAME); if (je != null) { Loading @@ -773,7 +773,7 @@ public class PackageParser { pkg.mSignatures = null; pkg.mSigningKeys = null; collectCertificates(pkg, new File(pkg.codePath), flags); collectCertificates(pkg, new File(pkg.baseCodePath), flags); if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (String splitCodePath : pkg.splitCodePaths) { Loading Loading @@ -3692,12 +3692,21 @@ public class PackageParser { public final static class Package { public String packageName; /** Names of any split APKs, ordered by parsed splitName */ public String[] splitNames; // TODO: work towards making these paths invariant /** Base APK */ /** * Path where this package was found on disk. For monolithic packages * this is path to single base APK file; for cluster packages this is * path to the cluster directory. */ public String codePath; /** Split APKs, ordered by parsed splitName */ /** Path of base APK */ public String baseCodePath; /** Paths of any split APKs, ordered by parsed splitName */ public String[] splitCodePaths; // For now we only support one application per package. Loading Loading @@ -3816,9 +3825,9 @@ public class PackageParser { applicationInfo.uid = -1; } public Collection<String> getAllCodePaths() { public List<String> getAllCodePaths() { ArrayList<String> paths = new ArrayList<>(); paths.add(codePath); paths.add(baseCodePath); if (!ArrayUtils.isEmpty(splitCodePaths)) { Collections.addAll(paths, splitCodePaths); } Loading core/java/android/os/FileUtils.java +24 −3 Original line number Diff line number Diff line Loading @@ -384,16 +384,18 @@ public class FileUtils { return filePath.startsWith(dirPath); } public static void deleteContents(File dir) { public static boolean deleteContents(File dir) { File[] files = dir.listFiles(); boolean success = true; if (files != null) { for (File file : files) { if (file.isDirectory()) { deleteContents(file); success &= deleteContents(file); } file.delete(); success &= file.delete(); } } return success; } /** Loading @@ -411,4 +413,23 @@ public class FileUtils { } return true; } public static String rewriteAfterRename(File beforeDir, File afterDir, String path) { final File result = rewriteAfterRename(beforeDir, afterDir, new File(path)); return (result != null) ? result.getAbsolutePath() : null; } /** * Given a path under the "before" directory, rewrite it to live under the * "after" directory. For example, {@code /before/foo/bar.txt} would become * {@code /after/foo/bar.txt}. */ public static File rewriteAfterRename(File beforeDir, File afterDir, File file) { if (contains(beforeDir, file)) { final String splice = file.getAbsolutePath().substring( beforeDir.getAbsolutePath().length()); return new File(afterDir, splice); } return null; } } core/java/android/os/SELinux.java +19 −0 Original line number Diff line number Diff line Loading @@ -171,4 +171,23 @@ public class SELinux { return false; } } /** * Recursively restores all files under the given path to their default * SELinux security context. If the system is not compiled with SELinux, * then {@code true} is automatically returned. If SELinux is compiled in, * but disabled, then {@code true} is returned. * * @return a boolean indicating whether the relabeling succeeded. */ public static boolean restoreconTree(File dir) { final File[] files = dir.listFiles(); boolean success = true; if (files != null) { for (File file : files) { success &= restorecon(file); } } return success; } } core/java/com/android/internal/app/IMediaContainerService.aidl +12 −14 Original line number Diff line number Diff line Loading @@ -16,27 +16,25 @@ package com.android.internal.app; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.content.pm.ContainerEncryptionParams; import android.content.pm.PackageInfoLite; import android.content.res.ObbInfo; interface IMediaContainerService { String copyResourceToContainer(in Uri packageURI, String containerId, String key, String copyResourceToContainer(String packagePath, String containerId, String key, String resFileName, String publicResFileName, boolean isExternal, boolean isForwardLocked, in String abiOverride); int copyResource(in Uri packageURI, in ContainerEncryptionParams encryptionParams, boolean isForwardLocked, String abiOverride); int copyResource(String packagePath, in ContainerEncryptionParams encryptionParams, in ParcelFileDescriptor outStream); PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold, in String abiOverride); boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold); boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in String abiOverride); ObbInfo getObbInfo(in String filename); long calculateDirectorySize(in String directory); PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, long threshold, String abiOverride); boolean checkInternalFreeStorage(String packagePath, boolean isForwardLocked, long threshold); boolean checkExternalFreeStorage(String packagePath, boolean isForwardLocked, String abiOverride); ObbInfo getObbInfo(String filename); long calculateDirectorySize(String directory); /** Return file system stats: [0] is total bytes, [1] is available bytes */ long[] getFileSystemStats(in String path); void clearDirectory(in String directory); long calculateInstalledSize(in String packagePath, boolean isForwardLocked, in String abiOverride); long[] getFileSystemStats(String path); void clearDirectory(String directory); long calculateInstalledSize(String packagePath, boolean isForwardLocked, String abiOverride); } Loading
core/java/android/content/pm/ApplicationInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -413,6 +413,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { /** * Full path to the base APK for this application. */ // TODO: verify that nobody is doing codePath comparisons against this public String sourceDir; /** Loading
core/java/android/content/pm/PackageParser.java +38 −29 Original line number Diff line number Diff line Loading @@ -279,11 +279,11 @@ public class PackageParser { mMetrics = metrics; } private static final boolean isPackageFilename(File file) { public static final boolean isPackageFilename(File file) { return isPackageFilename(file.getName()); } private static final boolean isPackageFilename(String name) { public static final boolean isPackageFilename(String name) { return name.endsWith(".apk"); } Loading Loading @@ -552,7 +552,7 @@ public class PackageParser { * Note that this <em>does not</em> perform signature verification; that * must be done separately in {@link #collectCertificates(Package, int)}. */ public Package parseSplitPackage(File apkDir, int flags) throws PackageParserException { public Package parseClusterPackage(File apkDir, int flags) throws PackageParserException { final File[] files = apkDir.listFiles(); if (ArrayUtils.isEmpty(files)) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, Loading Loading @@ -600,27 +600,23 @@ public class PackageParser { "Missing base APK in " + apkDir); } // Always apply deterministic ordering based on splitName final int size = apks.size(); final String[] splitNames = apks.keySet().toArray(new String[size]); Arrays.sort(splitNames, sSplitNameComparator); final File[] splitFiles = new File[size]; for (int i = 0; i < size; i++) { splitFiles[i] = apks.get(splitNames[i]); } final Package pkg = parseBaseApk(baseFile, flags); if (pkg == null) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, "Failed to parse base APK: " + baseFile); } for (File splitFile : splitFiles) { parseSplitApk(pkg, splitFile, flags); // Always apply deterministic ordering based on splitName final int size = apks.size(); final String[] splitNames = apks.keySet().toArray(new String[size]); Arrays.sort(splitNames, sSplitNameComparator); for (String splitName : splitNames) { final File splitFile = apks.get(splitName); parseSplitApk(pkg, splitFile, splitName, flags); } pkg.codePath = apkDir.getAbsolutePath(); return pkg; } Loading @@ -632,11 +628,12 @@ public class PackageParser { */ public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException { final Package pkg = parseBaseApk(apkFile, flags); if (pkg != null) { return pkg; } else { if (pkg == null) { throw new PackageParserException(mParseError, "Failed to parse " + apkFile); } pkg.codePath = apkFile.getAbsolutePath(); return pkg; } private Package parseBaseApk(File apkFile, int flags) { Loading Loading @@ -723,19 +720,22 @@ public class PackageParser { parser.close(); assmgr.close(); pkg.codePath = apkPath; pkg.baseCodePath = apkPath; pkg.mSignatures = null; return pkg; } private void parseSplitApk(Package pkg, File apkFile, int flags) throws PackageParserException { final String apkPath = apkFile.getAbsolutePath(); private void parseSplitApk(Package pkg, File apkFile, String splitName, int flags) throws PackageParserException { final String splitCodePath = apkFile.getAbsolutePath(); mArchiveSourcePath = apkFile.getAbsolutePath(); // TODO: expand split APK parsing // TODO: extract splitName during parse pkg.splitNames = ArrayUtils.appendElement(String.class, pkg.splitNames, splitName); pkg.splitCodePaths = ArrayUtils.appendElement(String.class, pkg.splitCodePaths, apkFile.getAbsolutePath()); splitCodePath); } /** Loading @@ -748,7 +748,7 @@ public class PackageParser { // TODO: extend to gather digest for split APKs try { final StrictJarFile jarFile = new StrictJarFile(pkg.codePath); final StrictJarFile jarFile = new StrictJarFile(pkg.baseCodePath); try { final ZipEntry je = jarFile.findEntry(ANDROID_MANIFEST_FILENAME); if (je != null) { Loading @@ -773,7 +773,7 @@ public class PackageParser { pkg.mSignatures = null; pkg.mSigningKeys = null; collectCertificates(pkg, new File(pkg.codePath), flags); collectCertificates(pkg, new File(pkg.baseCodePath), flags); if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { for (String splitCodePath : pkg.splitCodePaths) { Loading Loading @@ -3692,12 +3692,21 @@ public class PackageParser { public final static class Package { public String packageName; /** Names of any split APKs, ordered by parsed splitName */ public String[] splitNames; // TODO: work towards making these paths invariant /** Base APK */ /** * Path where this package was found on disk. For monolithic packages * this is path to single base APK file; for cluster packages this is * path to the cluster directory. */ public String codePath; /** Split APKs, ordered by parsed splitName */ /** Path of base APK */ public String baseCodePath; /** Paths of any split APKs, ordered by parsed splitName */ public String[] splitCodePaths; // For now we only support one application per package. Loading Loading @@ -3816,9 +3825,9 @@ public class PackageParser { applicationInfo.uid = -1; } public Collection<String> getAllCodePaths() { public List<String> getAllCodePaths() { ArrayList<String> paths = new ArrayList<>(); paths.add(codePath); paths.add(baseCodePath); if (!ArrayUtils.isEmpty(splitCodePaths)) { Collections.addAll(paths, splitCodePaths); } Loading
core/java/android/os/FileUtils.java +24 −3 Original line number Diff line number Diff line Loading @@ -384,16 +384,18 @@ public class FileUtils { return filePath.startsWith(dirPath); } public static void deleteContents(File dir) { public static boolean deleteContents(File dir) { File[] files = dir.listFiles(); boolean success = true; if (files != null) { for (File file : files) { if (file.isDirectory()) { deleteContents(file); success &= deleteContents(file); } file.delete(); success &= file.delete(); } } return success; } /** Loading @@ -411,4 +413,23 @@ public class FileUtils { } return true; } public static String rewriteAfterRename(File beforeDir, File afterDir, String path) { final File result = rewriteAfterRename(beforeDir, afterDir, new File(path)); return (result != null) ? result.getAbsolutePath() : null; } /** * Given a path under the "before" directory, rewrite it to live under the * "after" directory. For example, {@code /before/foo/bar.txt} would become * {@code /after/foo/bar.txt}. */ public static File rewriteAfterRename(File beforeDir, File afterDir, File file) { if (contains(beforeDir, file)) { final String splice = file.getAbsolutePath().substring( beforeDir.getAbsolutePath().length()); return new File(afterDir, splice); } return null; } }
core/java/android/os/SELinux.java +19 −0 Original line number Diff line number Diff line Loading @@ -171,4 +171,23 @@ public class SELinux { return false; } } /** * Recursively restores all files under the given path to their default * SELinux security context. If the system is not compiled with SELinux, * then {@code true} is automatically returned. If SELinux is compiled in, * but disabled, then {@code true} is returned. * * @return a boolean indicating whether the relabeling succeeded. */ public static boolean restoreconTree(File dir) { final File[] files = dir.listFiles(); boolean success = true; if (files != null) { for (File file : files) { success &= restorecon(file); } } return success; } }
core/java/com/android/internal/app/IMediaContainerService.aidl +12 −14 Original line number Diff line number Diff line Loading @@ -16,27 +16,25 @@ package com.android.internal.app; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.content.pm.ContainerEncryptionParams; import android.content.pm.PackageInfoLite; import android.content.res.ObbInfo; interface IMediaContainerService { String copyResourceToContainer(in Uri packageURI, String containerId, String key, String copyResourceToContainer(String packagePath, String containerId, String key, String resFileName, String publicResFileName, boolean isExternal, boolean isForwardLocked, in String abiOverride); int copyResource(in Uri packageURI, in ContainerEncryptionParams encryptionParams, boolean isForwardLocked, String abiOverride); int copyResource(String packagePath, in ContainerEncryptionParams encryptionParams, in ParcelFileDescriptor outStream); PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold, in String abiOverride); boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold); boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in String abiOverride); ObbInfo getObbInfo(in String filename); long calculateDirectorySize(in String directory); PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, long threshold, String abiOverride); boolean checkInternalFreeStorage(String packagePath, boolean isForwardLocked, long threshold); boolean checkExternalFreeStorage(String packagePath, boolean isForwardLocked, String abiOverride); ObbInfo getObbInfo(String filename); long calculateDirectorySize(String directory); /** Return file system stats: [0] is total bytes, [1] is available bytes */ long[] getFileSystemStats(in String path); void clearDirectory(in String directory); long calculateInstalledSize(in String packagePath, boolean isForwardLocked, in String abiOverride); long[] getFileSystemStats(String path); void clearDirectory(String directory); long calculateInstalledSize(String packagePath, boolean isForwardLocked, String abiOverride); }