Merge "Change app code path"

This commit is contained in:
Songchun Fan
2020-02-03 21:06:52 +00:00
committed by Android (Google) Code Review
5 changed files with 57 additions and 26 deletions

View File

@@ -954,6 +954,10 @@ public class PackageParser {
throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
"No packages found in split");
}
// Apk directory is directly nested under the current directory
if (files.length == 1 && files[0].isDirectory()) {
return parseClusterPackageLite(files[0], flags);
}
String packageName = null;
int versionCode = 0;
@@ -1327,12 +1331,9 @@ public class PackageParser {
}
}
pkg.setCodePath(packageDir.getCanonicalPath());
pkg.setCodePath(lite.codePath);
pkg.setUse32bitAbi(lite.use32bitAbi);
return pkg;
} catch (IOException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
"Failed to get path: " + lite.baseCodePath, e);
} finally {
IoUtils.closeQuietly(assetLoader);
}

View File

@@ -97,6 +97,10 @@ public class ApkLiteParseUtils {
throw new PackageParser.PackageParserException(
PackageManager.INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split");
}
// Apk directory is directly nested under the current directory
if (files.length == 1 && files[0].isDirectory()) {
return parseClusterPackageLite(files[0], flags);
}
String packageName = null;
int versionCode = 0;

View File

@@ -205,11 +205,8 @@ public class ApkParseUtils {
}
}
return parsingPackage.setCodePath(packageDir.getCanonicalPath())
return parsingPackage.setCodePath(lite.codePath)
.setUse32BitAbi(lite.use32bitAbi);
} catch (IOException e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
"Failed to get path: " + lite.baseCodePath, e);
} finally {
IoUtils.closeQuietly(assetLoader);
}

View File

@@ -117,6 +117,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
import android.Manifest;
@@ -361,7 +362,6 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -651,6 +651,8 @@ public class PackageManagerService extends IPackageManager.Stub
private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
private static final String RANDOM_DIR_PREFIX = "~~";
final ServiceThread mHandlerThread;
final PackageHandler mHandler;
@@ -2996,9 +2998,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
//delete tmp files
deleteTempPackageFiles();
final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
// Remove any shared userIDs that have no associated packages
@@ -3591,8 +3590,7 @@ public class PackageManagerService extends IPackageManager.Stub
getNextCodePath(Environment.getDataAppDirectory(null), packageName);
int ret = PackageManager.INSTALL_SUCCEEDED;
try {
Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
Os.chmod(dstCodePath.getAbsolutePath(), 0755);
makeDirRecursive(dstCodePath, 0755);
for (File srcFile : compressedFiles) {
final String srcFileName = srcFile.getName();
final String dstFileName = srcFileName.substring(
@@ -9852,8 +9850,12 @@ public class PackageManagerService extends IPackageManager.Stub
@GuardedBy("mInstallLock")
void removeCodePathLI(File codePath) {
if (codePath.isDirectory()) {
File codePathParent = codePath.getParentFile();
try {
mInstaller.rmPackageDir(codePath.getAbsolutePath());
if (codePathParent.getName().startsWith(RANDOM_DIR_PREFIX)) {
mInstaller.rmPackageDir(codePathParent.getAbsolutePath());
}
} catch (InstallerException e) {
Slog.w(TAG, "Failed to remove code path", e);
}
@@ -14926,7 +14928,9 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean onIncremental = mIncrementalManager != null
&& isIncrementalPath(beforeCodeFile.getAbsolutePath());
try {
makeDirRecursive(afterCodeFile.getParentFile(), 0775);
if (onIncremental) {
// TODO(b/147371381): fix incremental installation
mIncrementalManager.rename(beforeCodeFile.getAbsolutePath(),
afterCodeFile.getAbsolutePath());
} else {
@@ -15138,16 +15142,29 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
/**
* Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
* Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
* Notice that this method doesn't actually create any directory.
*
* @param targetDir Directory that is two-levels up from the result directory.
* @param packageName Name of the package whose code files are to be installed under the result
* directory.
* @return File object for the directory that should hold the code files of {@code packageName}.
*/
private File getNextCodePath(File targetDir, String packageName) {
File result;
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[16];
File firstLevelDir;
do {
random.nextBytes(bytes);
String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
result = new File(targetDir, packageName + "-" + suffix);
} while (result.exists());
return result;
String dirName = RANDOM_DIR_PREFIX
+ Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
firstLevelDir = new File(targetDir, dirName);
} while (firstLevelDir.exists());
random.nextBytes(bytes);
String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
return new File(firstLevelDir, packageName + "-" + suffix);
}
static class PackageInstalledInfo {
@@ -17142,12 +17159,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
private void deleteTempPackageFiles() {
// TODO: Is this used?
final FilenameFilter filter =
(dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp");
}
@Override
public void deletePackageAsUser(String packageName, int versionCode,
IPackageDeleteObserver observer, int userId, int flags) {
@@ -21477,7 +21488,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int absoluteCodePathCount = absoluteCodePaths.size();
for (int i = 0; i < absoluteCodePathCount; i++) {
String absoluteCodePath = absoluteCodePaths.get(i);
if (absolutePath.startsWith(absoluteCodePath)) {
if (absoluteCodePath.startsWith(absolutePath)) {
pathValid = true;
break;
}

View File

@@ -83,6 +83,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
@@ -918,4 +919,21 @@ public class PackageManagerServiceUtils {
}
return packageSetting.getPermissionsState();
}
/**
* Recursively create target directory
*/
public static void makeDirRecursive(File targetDir, int mode) throws ErrnoException {
final Path targetDirPath = targetDir.toPath();
final int directoriesCount = targetDirPath.getNameCount();
File currentDir;
for (int i = 1; i <= directoriesCount; i++) {
currentDir = targetDirPath.subpath(0, i).toFile();
if (currentDir.exists()) {
continue;
}
Os.mkdir(currentDir.getAbsolutePath(), mode);
Os.chmod(currentDir.getAbsolutePath(), mode);
}
}
}