Merge "Change app code path"
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user