Merge "Reuse a same buffer per session instead of reallocating each time." into tm-dev

This commit is contained in:
TreeHugger Robot
2022-04-30 02:57:55 +00:00
committed by Android (Google) Code Review
2 changed files with 35 additions and 18 deletions

View File

@@ -171,39 +171,53 @@ public final class PackageUtils {
}
/**
* @see #computeSha256DigestForLargeFile(String, String)
* Creates a fixed size buffer based on whether the device is low ram or not. This is to be used
* with the {@link #computeSha256DigestForLargeFile(String, byte[])} and
* {@link #computeSha256DigestForLargeFile(String, byte[], String)} methods.
* @return a byte array of size {@link #LOW_RAM_BUFFER_SIZE_BYTES} if the device is a low RAM
* device, otherwise a byte array of size {@link #HIGH_RAM_BUFFER_SIZE_BYTES}
*/
public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath) {
return computeSha256DigestForLargeFile(filePath, null);
public static @NonNull byte[] createLargeFileBuffer() {
int bufferSize = ActivityManager.isLowRamDeviceStatic()
? LOW_RAM_BUFFER_SIZE_BYTES : HIGH_RAM_BUFFER_SIZE_BYTES;
return new byte[bufferSize];
}
/**
* Computes the SHA256 digest of large files.
* @param filePath The path to which the file's content is to be hashed.
* @param separator Separator between each pair of characters, such as colon, or null to omit.
* @return The digest or null if an error occurs.
* @see #computeSha256DigestForLargeFile(String, byte[], String)
*/
public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
@Nullable String separator) {
@NonNull byte[] fileBuffer) {
return computeSha256DigestForLargeFile(filePath, fileBuffer, null);
}
/**
* Computes the SHA256 digest of large files. This is typically useful for large APEXs.
* @param filePath The path to which the file's content is to be hashed.
* @param fileBuffer A buffer to read file's content into memory. It is strongly recommended to
* make use of the {@link #createLargeFileBuffer()} method to create this
* buffer.
* @param separator Separator between each pair of characters, such as colon, or null to omit.
* @return The SHA256 digest or null if an error occurs.
*/
public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
@NonNull byte[] fileBuffer, @Nullable String separator) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA256");
messageDigest.reset();
} catch (NoSuchAlgorithmException e) {
// this shouldn't happen!
// this really shouldn't happen!
return null;
}
boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
int bufferSize = isLowRamDevice ? LOW_RAM_BUFFER_SIZE_BYTES : HIGH_RAM_BUFFER_SIZE_BYTES;
File f = new File(filePath);
try {
DigestInputStream digestStream = new DigestInputStream(new FileInputStream(f),
DigestInputStream digestInputStream = new DigestInputStream(new FileInputStream(f),
messageDigest);
byte[] buffer = new byte[bufferSize];
while (digestStream.read(buffer) != -1);
while (digestInputStream.read(fileBuffer) != -1);
} catch (IOException e) {
e.printStackTrace();
return null;
}

View File

@@ -500,6 +500,7 @@ public class BinaryTransparencyService extends SystemService {
// ones appearing out of the blue. Thus, we're going to only go through our cache to check
// for changes, rather than freshly invoking `getInstalledPackages()` and
// `getInstalledModules()`
byte[] largeFileBuffer = PackageUtils.createLargeFileBuffer();
for (Map.Entry<String, Long> entry : mBinaryLastUpdateTimes.entrySet()) {
String packageName = entry.getKey();
try {
@@ -513,7 +514,7 @@ public class BinaryTransparencyService extends SystemService {
// compute the digest for the updated package
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(
packageInfo.applicationInfo.sourceDir);
packageInfo.applicationInfo.sourceDir, largeFileBuffer);
if (sha256digest == null) {
Slog.e(TAG, "Failed to compute SHA256sum for file at "
+ packageInfo.applicationInfo.sourceDir);
@@ -545,11 +546,13 @@ public class BinaryTransparencyService extends SystemService {
// In general, we care about all APEXs, *and* all Modules, which may include some APKs.
// First, we deal with all installed APEXs.
byte[] largeFileBuffer = PackageUtils.createLargeFileBuffer();
for (PackageInfo packageInfo : getInstalledApexs()) {
ApplicationInfo appInfo = packageInfo.applicationInfo;
// compute SHA256 for these APEXs
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(appInfo.sourceDir);
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(appInfo.sourceDir,
largeFileBuffer);
if (sha256digest == null) {
Slog.e(TAG, String.format("Failed to compute SHA256 digest for %s",
packageInfo.packageName));
@@ -585,7 +588,7 @@ public class BinaryTransparencyService extends SystemService {
// compute SHA256 digest for these modules
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(
appInfo.sourceDir);
appInfo.sourceDir, largeFileBuffer);
if (sha256digest == null) {
Slog.e(TAG, String.format("Failed to compute SHA256 digest for %s",
packageName));